v5.page.test.js 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. import mongoose from 'mongoose';
  2. import { getInstance } from '../setup-crowi';
  3. describe('Page', () => {
  4. let crowi;
  5. let Page;
  6. let Revision;
  7. let User;
  8. let Tag;
  9. let PageTagRelation;
  10. let Bookmark;
  11. let Comment;
  12. let ShareLink;
  13. let PageRedirect;
  14. let UserGroup;
  15. let UserGroupRelation;
  16. let xssSpy;
  17. let rootPage;
  18. let dummyUser1;
  19. let pModelUser1;
  20. let pModelUser2;
  21. let pModelUser3;
  22. let groupIdIsolate;
  23. let groupIdA;
  24. let groupIdB;
  25. let groupIdC;
  26. beforeAll(async() => {
  27. crowi = await getInstance();
  28. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', { 'app:isV5Compatible': true });
  29. jest.restoreAllMocks();
  30. User = mongoose.model('User');
  31. Page = mongoose.model('Page');
  32. Revision = mongoose.model('Revision');
  33. Tag = mongoose.model('Tag');
  34. PageTagRelation = mongoose.model('PageTagRelation');
  35. Bookmark = mongoose.model('Bookmark');
  36. Comment = mongoose.model('Comment');
  37. ShareLink = mongoose.model('ShareLink');
  38. PageRedirect = mongoose.model('PageRedirect');
  39. UserGroup = mongoose.model('UserGroup');
  40. UserGroupRelation = mongoose.model('UserGroupRelation');
  41. dummyUser1 = await User.findOne({ username: 'v5DummyUser1' });
  42. rootPage = await Page.findOne({ path: '/' });
  43. const pModelUserId1 = new mongoose.Types.ObjectId();
  44. const pModelUserId2 = new mongoose.Types.ObjectId();
  45. const pModelUserId3 = new mongoose.Types.ObjectId();
  46. await User.insertMany([
  47. {
  48. _id: pModelUserId1, name: 'pmodelUser1', username: 'pmodelUser1', email: 'pmodelUser1@example.com',
  49. },
  50. {
  51. _id: pModelUserId2, name: 'pmodelUser2', username: 'pmodelUser2', email: 'pmodelUser2@example.com',
  52. },
  53. {
  54. _id: pModelUserId3, name: 'pModelUser3', username: 'pModelUser3', email: 'pModelUser3@example.com',
  55. },
  56. ]);
  57. pModelUser1 = await User.findOne({ _id: pModelUserId1 });
  58. pModelUser2 = await User.findOne({ _id: pModelUserId2 });
  59. pModelUser3 = await User.findOne({ _id: pModelUserId3 });
  60. groupIdIsolate = new mongoose.Types.ObjectId();
  61. groupIdA = new mongoose.Types.ObjectId();
  62. groupIdB = new mongoose.Types.ObjectId();
  63. groupIdC = new mongoose.Types.ObjectId();
  64. await UserGroup.insertMany([
  65. {
  66. _id: groupIdIsolate,
  67. name: 'pModel_groupIsolate',
  68. },
  69. {
  70. _id: groupIdA,
  71. name: 'pModel_groupA',
  72. },
  73. {
  74. _id: groupIdB,
  75. name: 'pModel_groupB',
  76. parent: groupIdA,
  77. },
  78. {
  79. _id: groupIdC,
  80. name: 'pModel_groupC',
  81. parent: groupIdB,
  82. },
  83. ]);
  84. await UserGroupRelation.insertMany([
  85. {
  86. relatedGroup: groupIdIsolate,
  87. relatedUser: pModelUserId1,
  88. createdAt: new Date(),
  89. },
  90. {
  91. relatedGroup: groupIdIsolate,
  92. relatedUser: pModelUserId2,
  93. createdAt: new Date(),
  94. },
  95. {
  96. relatedGroup: groupIdA,
  97. relatedUser: pModelUserId1,
  98. createdAt: new Date(),
  99. },
  100. {
  101. relatedGroup: groupIdA,
  102. relatedUser: pModelUserId2,
  103. createdAt: new Date(),
  104. },
  105. {
  106. relatedGroup: groupIdA,
  107. relatedUser: pModelUserId3,
  108. createdAt: new Date(),
  109. },
  110. {
  111. relatedGroup: groupIdB,
  112. relatedUser: pModelUserId2,
  113. createdAt: new Date(),
  114. },
  115. {
  116. relatedGroup: groupIdB,
  117. relatedUser: pModelUserId3,
  118. createdAt: new Date(),
  119. },
  120. {
  121. relatedGroup: groupIdC,
  122. relatedUser: pModelUserId3,
  123. createdAt: new Date(),
  124. },
  125. ]);
  126. const pageIdCreate1 = new mongoose.Types.ObjectId();
  127. const pageIdCreate2 = new mongoose.Types.ObjectId();
  128. const pageIdCreate3 = new mongoose.Types.ObjectId();
  129. const pageIdCreate4 = new mongoose.Types.ObjectId();
  130. /**
  131. * create
  132. * mc_ => model create
  133. * emp => empty => page with isEmpty: true
  134. * pub => public => GRANT_PUBLIC
  135. */
  136. await Page.insertMany([
  137. {
  138. _id: pageIdCreate1,
  139. path: '/v5_empty_create_4',
  140. grant: Page.GRANT_PUBLIC,
  141. parent: rootPage._id,
  142. isEmpty: true,
  143. },
  144. {
  145. path: '/v5_empty_create_4/v5_create_5',
  146. grant: Page.GRANT_PUBLIC,
  147. creator: dummyUser1,
  148. lastUpdateUser: dummyUser1._id,
  149. parent: pageIdCreate1,
  150. isEmpty: false,
  151. },
  152. {
  153. _id: pageIdCreate2,
  154. path: '/mc4_top/mc1_emp',
  155. grant: Page.GRANT_PUBLIC,
  156. creator: dummyUser1,
  157. lastUpdateUser: dummyUser1._id,
  158. parent: rootPage._id,
  159. isEmpty: true,
  160. },
  161. {
  162. path: '/mc4_top/mc1_emp/mc2_pub',
  163. grant: Page.GRANT_PUBLIC,
  164. creator: dummyUser1,
  165. lastUpdateUser: dummyUser1._id,
  166. parent: pageIdCreate2,
  167. isEmpty: false,
  168. },
  169. {
  170. path: '/mc5_top/mc3_awl',
  171. grant: Page.GRANT_RESTRICTED,
  172. creator: dummyUser1,
  173. lastUpdateUser: dummyUser1._id,
  174. isEmpty: false,
  175. },
  176. {
  177. _id: pageIdCreate3,
  178. path: '/mc4_top',
  179. grant: Page.GRANT_PUBLIC,
  180. creator: dummyUser1,
  181. lastUpdateUser: dummyUser1._id,
  182. isEmpty: false,
  183. parent: rootPage._id,
  184. descendantCount: 1,
  185. },
  186. {
  187. _id: pageIdCreate4,
  188. path: '/mc5_top',
  189. grant: Page.GRANT_PUBLIC,
  190. creator: dummyUser1,
  191. lastUpdateUser: dummyUser1._id,
  192. isEmpty: false,
  193. parent: rootPage._id,
  194. descendantCount: 0,
  195. },
  196. ]);
  197. /**
  198. * update
  199. * mup_ => model update
  200. * emp => empty => page with isEmpty: true
  201. * pub => public => GRANT_PUBLIC
  202. * awl => Anyone with the link => GRANT_RESTRICTED
  203. */
  204. const pageIdUpd1 = new mongoose.Types.ObjectId();
  205. const pageIdUpd2 = new mongoose.Types.ObjectId();
  206. const pageIdUpd3 = new mongoose.Types.ObjectId();
  207. const pageIdUpd4 = new mongoose.Types.ObjectId();
  208. const pageIdUpd5 = new mongoose.Types.ObjectId();
  209. const pageIdUpd6 = new mongoose.Types.ObjectId();
  210. const pageIdUpd7 = new mongoose.Types.ObjectId();
  211. const pageIdUpd8 = new mongoose.Types.ObjectId();
  212. const pageIdUpd9 = new mongoose.Types.ObjectId();
  213. const pageIdUpd10 = new mongoose.Types.ObjectId();
  214. const pageIdUpd11 = new mongoose.Types.ObjectId();
  215. const pageIdUpd12 = new mongoose.Types.ObjectId();
  216. const pageIdUpd13 = new mongoose.Types.ObjectId();
  217. const pageIdUpd14 = new mongoose.Types.ObjectId();
  218. const pageIdUpd15 = new mongoose.Types.ObjectId();
  219. const pageIdUpd16 = new mongoose.Types.ObjectId();
  220. const pageIdUpd17 = new mongoose.Types.ObjectId();
  221. const pageIdUpd18 = new mongoose.Types.ObjectId();
  222. const pageIdUpd19 = new mongoose.Types.ObjectId();
  223. await Page.insertMany([
  224. {
  225. _id: pageIdUpd1,
  226. path: '/mup13_top/mup1_emp',
  227. grant: Page.GRANT_PUBLIC,
  228. parent: pageIdUpd8._id,
  229. isEmpty: true,
  230. },
  231. {
  232. _id: pageIdUpd2,
  233. path: '/mup13_top/mup1_emp/mup2_pub',
  234. grant: Page.GRANT_PUBLIC,
  235. parent: pageIdUpd1._id,
  236. creator: dummyUser1,
  237. lastUpdateUser: dummyUser1._id,
  238. isEmpty: false,
  239. },
  240. {
  241. _id: pageIdUpd3,
  242. path: '/mup14_top/mup6_pub',
  243. grant: Page.GRANT_PUBLIC,
  244. creator: dummyUser1,
  245. lastUpdateUser: dummyUser1._id,
  246. parent: pageIdUpd9,
  247. isEmpty: false,
  248. descendantCount: 1,
  249. },
  250. {
  251. path: '/mup14_top/mup6_pub/mup7_pub',
  252. grant: Page.GRANT_PUBLIC,
  253. creator: dummyUser1,
  254. lastUpdateUser: dummyUser1._id,
  255. parent: pageIdUpd3,
  256. isEmpty: false,
  257. descendantCount: 0,
  258. },
  259. {
  260. _id: pageIdUpd4,
  261. path: '/mup15_top/mup8_pub',
  262. grant: Page.GRANT_PUBLIC,
  263. creator: dummyUser1,
  264. lastUpdateUser: dummyUser1._id,
  265. parent: pageIdUpd10._id,
  266. isEmpty: false,
  267. },
  268. {
  269. _id: pageIdUpd5,
  270. path: '/mup16_top/mup9_pub/mup10_pub/mup11_awl',
  271. grant: Page.GRANT_RESTRICTED,
  272. creator: dummyUser1,
  273. lastUpdateUser: dummyUser1._id,
  274. isEmpty: false,
  275. },
  276. {
  277. _id: pageIdUpd6,
  278. path: '/mup17_top/mup12_emp',
  279. isEmpty: true,
  280. parent: pageIdUpd12._id,
  281. descendantCount: 1,
  282. },
  283. {
  284. _id: pageIdUpd7,
  285. path: '/mup17_top/mup12_emp',
  286. grant: Page.GRANT_RESTRICTED,
  287. creator: dummyUser1,
  288. lastUpdateUser: dummyUser1._id,
  289. isEmpty: false,
  290. },
  291. {
  292. path: '/mup17_top/mup12_emp/mup18_pub',
  293. isEmpty: false,
  294. creator: dummyUser1,
  295. lastUpdateUser: dummyUser1._id,
  296. parent: pageIdUpd6._id,
  297. },
  298. {
  299. _id: pageIdUpd8,
  300. path: '/mup13_top',
  301. grant: Page.GRANT_PUBLIC,
  302. creator: dummyUser1,
  303. lastUpdateUser: dummyUser1._id,
  304. isEmpty: false,
  305. parent: rootPage._id,
  306. descendantCount: 2,
  307. },
  308. {
  309. _id: pageIdUpd9,
  310. path: '/mup14_top',
  311. grant: Page.GRANT_PUBLIC,
  312. creator: dummyUser1,
  313. lastUpdateUser: dummyUser1._id,
  314. isEmpty: false,
  315. parent: rootPage._id,
  316. descendantCount: 2,
  317. },
  318. {
  319. _id: pageIdUpd10,
  320. path: '/mup15_top',
  321. grant: Page.GRANT_PUBLIC,
  322. creator: dummyUser1,
  323. lastUpdateUser: dummyUser1._id,
  324. isEmpty: false,
  325. parent: rootPage._id,
  326. descendantCount: 1,
  327. },
  328. {
  329. _id: pageIdUpd11,
  330. path: '/mup16_top',
  331. grant: Page.GRANT_PUBLIC,
  332. creator: dummyUser1,
  333. lastUpdateUser: dummyUser1._id,
  334. isEmpty: false,
  335. parent: rootPage._id,
  336. descendantCount: 0,
  337. },
  338. {
  339. _id: pageIdUpd12,
  340. path: '/mup17_top',
  341. grant: Page.GRANT_PUBLIC,
  342. creator: dummyUser1,
  343. lastUpdateUser: dummyUser1._id,
  344. isEmpty: false,
  345. parent: rootPage._id,
  346. descendantCount: 1,
  347. },
  348. {
  349. path: '/mup19',
  350. grant: Page.GRANT_PUBLIC,
  351. creator: dummyUser1,
  352. lastUpdateUser: dummyUser1._id,
  353. isEmpty: false,
  354. parent: rootPage._id,
  355. descendantCount: 0,
  356. },
  357. {
  358. path: '/mup20',
  359. grant: Page.GRANT_USER_GROUP,
  360. grantedGroup: groupIdA,
  361. creator: pModelUserId1,
  362. lastUpdateUser: pModelUserId1,
  363. isEmpty: false,
  364. parent: rootPage._id,
  365. descendantCount: 0,
  366. },
  367. {
  368. path: '/mup21',
  369. grant: Page.GRANT_RESTRICTED,
  370. creator: dummyUser1,
  371. lastUpdateUser: dummyUser1._id,
  372. isEmpty: false,
  373. descendantCount: 0,
  374. },
  375. {
  376. _id: pageIdUpd13,
  377. path: '/mup22',
  378. grant: Page.GRANT_PUBLIC,
  379. creator: pModelUser1,
  380. lastUpdateUser: pModelUser1._id,
  381. isEmpty: false,
  382. parent: rootPage._id,
  383. descendantCount: 1,
  384. },
  385. {
  386. path: '/mup22/mup23',
  387. grant: Page.GRANT_USER_GROUP,
  388. grantedGroup: groupIdA,
  389. creator: pModelUserId1,
  390. lastUpdateUser: pModelUserId1,
  391. isEmpty: false,
  392. parent: pageIdUpd13,
  393. descendantCount: 0,
  394. },
  395. {
  396. _id: pageIdUpd14,
  397. path: '/mup24_pub',
  398. grant: Page.GRANT_PUBLIC,
  399. creator: pModelUserId1,
  400. lastUpdateUser: pModelUserId1,
  401. isEmpty: false,
  402. parent: rootPage,
  403. descendantCount: 1,
  404. },
  405. {
  406. path: '/mup24_pub/mup25_pub',
  407. grant: Page.GRANT_PUBLIC,
  408. creator: pModelUserId1,
  409. lastUpdateUser: pModelUserId1,
  410. isEmpty: false,
  411. parent: rootPage,
  412. descendantCount: 0,
  413. },
  414. {
  415. path: '/mup26_awl',
  416. grant: Page.GRANT_RESTRICTED,
  417. creator: pModelUserId1,
  418. lastUpdateUser: pModelUserId1,
  419. isEmpty: false,
  420. descendantCount: 0,
  421. },
  422. {
  423. _id: pageIdUpd15,
  424. path: '/mup27_pub',
  425. grant: Page.GRANT_PUBLIC,
  426. creator: pModelUserId1,
  427. lastUpdateUser: pModelUserId1,
  428. isEmpty: false,
  429. parent: rootPage,
  430. descendantCount: 1,
  431. },
  432. {
  433. path: '/mup27_pub/mup28_owner',
  434. grant: Page.GRANT_OWNER,
  435. creator: pModelUserId1,
  436. lastUpdateUser: pModelUserId1,
  437. isEmpty: false,
  438. parent: rootPage,
  439. grantedUsers: [pModelUserId1],
  440. descendantCount: 0,
  441. },
  442. {
  443. _id: pageIdUpd16,
  444. path: '/mup29_A',
  445. grant: Page.GRANT_USER_GROUP,
  446. grantedGroup: groupIdA,
  447. creator: pModelUserId1,
  448. lastUpdateUser: pModelUserId1,
  449. isEmpty: false,
  450. parent: rootPage,
  451. descendantCount: 1,
  452. },
  453. {
  454. path: '/mup29_A/mup30_owner',
  455. grant: Page.GRANT_OWNER,
  456. grantedUsers: [pModelUserId1],
  457. creator: pModelUserId1,
  458. lastUpdateUser: pModelUserId1,
  459. isEmpty: false,
  460. parent: pageIdUpd16,
  461. descendantCount: 0,
  462. },
  463. {
  464. _id: pageIdUpd17,
  465. path: '/mup31_A',
  466. grant: Page.GRANT_USER_GROUP,
  467. grantedGroup: groupIdA,
  468. creator: pModelUserId1,
  469. lastUpdateUser: pModelUserId1,
  470. isEmpty: false,
  471. parent: rootPage,
  472. descendantCount: 1,
  473. },
  474. {
  475. path: '/mup31_A/mup32_owner',
  476. grant: Page.GRANT_OWNER,
  477. grantedUsers: [pModelUserId1],
  478. creator: pModelUserId1,
  479. lastUpdateUser: pModelUserId1,
  480. isEmpty: false,
  481. parent: pageIdUpd17,
  482. descendantCount: 0,
  483. },
  484. {
  485. _id: pageIdUpd18,
  486. path: '/mup33_C',
  487. grant: Page.GRANT_USER_GROUP,
  488. grantedGroup: groupIdC,
  489. creator: pModelUserId3,
  490. lastUpdateUser: pModelUserId3,
  491. isEmpty: false,
  492. parent: rootPage,
  493. descendantCount: 1,
  494. },
  495. {
  496. path: '/mup33_C/mup34_owner',
  497. grant: Page.GRANT_OWNER,
  498. grantedUsers: [pModelUserId3],
  499. creator: pModelUserId3,
  500. lastUpdateUser: pModelUserId3,
  501. isEmpty: false,
  502. parent: pageIdUpd18,
  503. descendantCount: 0,
  504. },
  505. {
  506. _id: pageIdUpd19,
  507. path: '/mup35_owner',
  508. grant: Page.GRANT_OWNER,
  509. grantedUsers: [pModelUserId1],
  510. creator: pModelUserId1,
  511. lastUpdateUser: pModelUserId1,
  512. isEmpty: false,
  513. parent: rootPage,
  514. descendantCount: 1,
  515. },
  516. {
  517. path: '/mup35_owner/mup36_owner',
  518. grant: Page.GRANT_OWNER,
  519. grantedUsers: [pModelUserId1],
  520. creator: pModelUserId1,
  521. lastUpdateUser: pModelUserId1,
  522. isEmpty: false,
  523. parent: pageIdUpd19,
  524. descendantCount: 0,
  525. },
  526. {
  527. path: '/mup40', // used this number to resolve conflict
  528. grant: Page.GRANT_OWNER,
  529. grantedUsers: [dummyUser1._id],
  530. creator: dummyUser1,
  531. lastUpdateUser: dummyUser1._id,
  532. isEmpty: false,
  533. parent: rootPage._id,
  534. descendantCount: 0,
  535. },
  536. ]);
  537. /**
  538. * getParentAndFillAncestors
  539. */
  540. const pageIdPAF1 = new mongoose.Types.ObjectId();
  541. const pageIdPAF2 = new mongoose.Types.ObjectId();
  542. const pageIdPAF3 = new mongoose.Types.ObjectId();
  543. await Page.insertMany([
  544. {
  545. _id: pageIdPAF1,
  546. path: '/PAF1',
  547. grant: Page.GRANT_PUBLIC,
  548. creator: dummyUser1,
  549. lastUpdateUser: dummyUser1._id,
  550. isEmpty: false,
  551. parent: rootPage._id,
  552. descendantCount: 0,
  553. },
  554. {
  555. _id: pageIdPAF2,
  556. path: '/emp_anc3',
  557. grant: Page.GRANT_PUBLIC,
  558. isEmpty: true,
  559. descendantCount: 1,
  560. parent: rootPage._id,
  561. },
  562. {
  563. path: '/emp_anc3/PAF3',
  564. grant: Page.GRANT_PUBLIC,
  565. creator: dummyUser1,
  566. lastUpdateUser: dummyUser1._id,
  567. isEmpty: false,
  568. descendantCount: 0,
  569. parent: pageIdPAF2,
  570. },
  571. {
  572. _id: pageIdPAF3,
  573. path: '/emp_anc4',
  574. grant: Page.GRANT_PUBLIC,
  575. isEmpty: true,
  576. descendantCount: 1,
  577. parent: rootPage._id,
  578. },
  579. {
  580. path: '/emp_anc4/PAF4',
  581. grant: Page.GRANT_PUBLIC,
  582. creator: dummyUser1,
  583. lastUpdateUser: dummyUser1._id,
  584. isEmpty: false,
  585. descendantCount: 0,
  586. parent: pageIdPAF3,
  587. },
  588. {
  589. path: '/emp_anc4',
  590. grant: Page.GRANT_OWNER,
  591. grantedUsers: [dummyUser1._id],
  592. creator: dummyUser1,
  593. lastUpdateUser: dummyUser1._id,
  594. isEmpty: false,
  595. },
  596. ]);
  597. });
  598. describe('create', () => {
  599. test('Should create single page', async() => {
  600. const page = await Page.create('/v5_create1', 'create1', dummyUser1, {});
  601. expect(page).toBeTruthy();
  602. expect(page.parent).toStrictEqual(rootPage._id);
  603. });
  604. test('Should create empty-child and non-empty grandchild', async() => {
  605. const grandchildPage = await Page.create('/v5_empty_create2/v5_create_3', 'grandchild', dummyUser1, {});
  606. const childPage = await Page.findOne({ path: '/v5_empty_create2' });
  607. expect(childPage.isEmpty).toBe(true);
  608. expect(grandchildPage).toBeTruthy();
  609. expect(childPage).toBeTruthy();
  610. expect(childPage.parent).toStrictEqual(rootPage._id);
  611. expect(grandchildPage.parent).toStrictEqual(childPage._id);
  612. });
  613. test('Should create on empty page', async() => {
  614. const beforeCreatePage = await Page.findOne({ path: '/v5_empty_create_4' });
  615. expect(beforeCreatePage.isEmpty).toBe(true);
  616. const childPage = await Page.create('/v5_empty_create_4', 'body', dummyUser1, {});
  617. const grandchildPage = await Page.findOne({ parent: childPage._id });
  618. expect(childPage).toBeTruthy();
  619. expect(childPage.isEmpty).toBe(false);
  620. expect(childPage.revision.body).toBe('body');
  621. expect(grandchildPage).toBeTruthy();
  622. expect(childPage.parent).toStrictEqual(rootPage._id);
  623. expect(grandchildPage.parent).toStrictEqual(childPage._id);
  624. });
  625. describe('Creating a page using existing path', () => {
  626. test('with grant RESTRICTED should only create the page and change nothing else', async() => {
  627. const pathT = '/mc4_top';
  628. const path1 = '/mc4_top/mc1_emp';
  629. const path2 = '/mc4_top/mc1_emp/mc2_pub';
  630. const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
  631. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  632. const page2 = await Page.findOne({ path: path2 });
  633. const page3 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  634. expect(pageT).toBeTruthy();
  635. expect(page1).toBeTruthy();
  636. expect(page2).toBeTruthy();
  637. expect(page3).toBeNull();
  638. // use existing path
  639. await Page.create(path1, 'new body', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  640. const _pageT = await Page.findOne({ path: pathT });
  641. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  642. const _page2 = await Page.findOne({ path: path2 });
  643. const _page3 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  644. expect(_pageT).toBeTruthy();
  645. expect(_page1).toBeTruthy();
  646. expect(_page2).toBeTruthy();
  647. expect(_page3).toBeTruthy();
  648. expect(_pageT.descendantCount).toBe(1);
  649. });
  650. });
  651. describe('Creating a page under a page with grant RESTRICTED', () => {
  652. test('will create a new empty page with the same path as the grant RESTRECTED page and become a parent', async() => {
  653. const pathT = '/mc5_top';
  654. const path1 = '/mc5_top/mc3_awl';
  655. const pathN = '/mc5_top/mc3_awl/mc4_pub'; // used to create
  656. const pageT = await Page.findOne({ path: pathT });
  657. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  658. const page2 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  659. expect(pageT).toBeTruthy();
  660. expect(page1).toBeTruthy();
  661. expect(page2).toBeNull();
  662. await Page.create(pathN, 'new body', dummyUser1, { grant: Page.GRANT_PUBLIC });
  663. const _pageT = await Page.findOne({ path: pathT });
  664. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  665. const _page2 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC, isEmpty: true });
  666. const _pageN = await Page.findOne({ path: pathN, grant: Page.GRANT_PUBLIC }); // newly crated
  667. expect(_pageT).toBeTruthy();
  668. expect(_page1).toBeTruthy();
  669. expect(_page2).toBeTruthy();
  670. expect(_pageN).toBeTruthy();
  671. expect(_pageN.parent).toStrictEqual(_page2._id);
  672. expect(_pageT.descendantCount).toStrictEqual(1);
  673. });
  674. });
  675. });
  676. describe('update', () => {
  677. const updatePage = async(page, newRevisionBody, oldRevisionBody, user, options = {}) => {
  678. const mockedRenameSubOperation = jest.spyOn(Page, 'emitPageEventUpdate').mockReturnValue(null);
  679. const savedPage = await Page.updatePage(page, newRevisionBody, oldRevisionBody, user, options);
  680. mockedRenameSubOperation.mockRestore();
  681. return savedPage;
  682. };
  683. describe('Changing grant from PUBLIC to RESTRICTED of', () => {
  684. test('an only-child page will delete its empty parent page', async() => {
  685. const pathT = '/mup13_top';
  686. const path1 = '/mup13_top/mup1_emp';
  687. const path2 = '/mup13_top/mup1_emp/mup2_pub';
  688. const pageT = await Page.findOne({ path: pathT, descendantCount: 2 });
  689. const page1 = await Page.findOne({ path: path1, isEmpty: true });
  690. const page2 = await Page.findOne({ path: path2, grant: Page.GRANT_PUBLIC });
  691. expect(pageT).toBeTruthy();
  692. expect(page1).toBeTruthy();
  693. expect(page2).toBeTruthy();
  694. const options = { grant: Page.GRANT_RESTRICTED, grantUserGroupId: null };
  695. await Page.updatePage(page2, 'newRevisionBody', 'oldRevisionBody', dummyUser1, options);
  696. const _pageT = await Page.findOne({ path: pathT });
  697. const _page1 = await Page.findOne({ path: path1 });
  698. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_RESTRICTED });
  699. expect(_pageT).toBeTruthy();
  700. expect(_page1).toBeNull();
  701. expect(_page2).toBeTruthy();
  702. expect(_pageT.descendantCount).toBe(1);
  703. });
  704. test('a page that has children will create an empty page with the same path and it becomes a new parent', async() => {
  705. const pathT = '/mup14_top';
  706. const path1 = '/mup14_top/mup6_pub';
  707. const path2 = '/mup14_top/mup6_pub/mup7_pub';
  708. const top = await Page.findOne({ path: pathT, descendantCount: 2 });
  709. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  710. const page2 = await Page.findOne({ path: path2, grant: Page.GRANT_PUBLIC });
  711. expect(top).toBeTruthy();
  712. expect(page1).toBeTruthy();
  713. expect(page2).toBeTruthy();
  714. await Page.updatePage(page1, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  715. const _top = await Page.findOne({ path: pathT });
  716. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  717. const _page2 = await Page.findOne({ path: path2 });
  718. const _pageN = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  719. expect(_page1).toBeTruthy();
  720. expect(_page2).toBeTruthy();
  721. expect(_pageN).toBeTruthy();
  722. expect(_page1.parent).toBeNull();
  723. expect(_page2.parent).toStrictEqual(_pageN._id);
  724. expect(_pageN.parent).toStrictEqual(top._id);
  725. expect(_pageN.isEmpty).toBe(true);
  726. expect(_pageN.descendantCount).toBe(1);
  727. expect(_top.descendantCount).toBe(1);
  728. });
  729. test('of a leaf page will NOT have an empty page with the same path', async() => {
  730. const pathT = '/mup15_top';
  731. const path1 = '/mup15_top/mup8_pub';
  732. const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
  733. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  734. const count = await Page.count({ path: path1 });
  735. expect(pageT).toBeTruthy();
  736. expect(page1).toBeTruthy();
  737. expect(count).toBe(1);
  738. await Page.updatePage(page1, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  739. const _pageT = await Page.findOne({ path: pathT });
  740. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  741. const _pageNotExist = await Page.findOne({ path: path1, isEmpty: true });
  742. expect(_pageT).toBeTruthy();
  743. expect(_page1).toBeTruthy();
  744. expect(_pageNotExist).toBeNull();
  745. expect(_pageT.descendantCount).toBe(0);
  746. });
  747. });
  748. describe('Changing grant to GRANT_RESTRICTED', () => {
  749. test('successfully change to GRANT_RESTRICTED from GRANT_OWNER', async() => {
  750. const path = '/mup40';
  751. const _page = await Page.findOne({ path, grant: Page.GRANT_OWNER, grantedUsers: [dummyUser1._id] });
  752. expect(_page).toBeTruthy();
  753. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  754. const page = await Page.findOne({ path });
  755. expect(page).toBeTruthy();
  756. expect(page.grant).toBe(Page.GRANT_RESTRICTED);
  757. expect(page.grantedUsers).toStrictEqual([]);
  758. });
  759. });
  760. describe('Changing grant from RESTRICTED to PUBLIC of', () => {
  761. test('a page will create ancestors if they do not exist', async() => {
  762. const pathT = '/mup16_top';
  763. const path1 = '/mup16_top/mup9_pub';
  764. const path2 = '/mup16_top/mup9_pub/mup10_pub';
  765. const path3 = '/mup16_top/mup9_pub/mup10_pub/mup11_awl';
  766. const top = await Page.findOne({ path: pathT });
  767. const page1 = await Page.findOne({ path: path1 });
  768. const page2 = await Page.findOne({ path: path2 });
  769. const page3 = await Page.findOne({ path: path3, grant: Page.GRANT_RESTRICTED });
  770. expect(top).toBeTruthy();
  771. expect(page3).toBeTruthy();
  772. expect(page1).toBeNull();
  773. expect(page2).toBeNull();
  774. await Page.updatePage(page3, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_PUBLIC });
  775. const _pageT = await Page.findOne({ path: pathT });
  776. const _page1 = await Page.findOne({ path: path1, isEmpty: true });
  777. const _page2 = await Page.findOne({ path: path2, isEmpty: true });
  778. const _page3 = await Page.findOne({ path: path3, grant: Page.GRANT_PUBLIC });
  779. expect(_page1).toBeTruthy();
  780. expect(_page2).toBeTruthy();
  781. expect(_page3).toBeTruthy();
  782. expect(_page1.parent).toStrictEqual(top._id);
  783. expect(_page2.parent).toStrictEqual(_page1._id);
  784. expect(_page3.parent).toStrictEqual(_page2._id);
  785. expect(_pageT.descendantCount).toBe(1);
  786. });
  787. test('a page will replace an empty page with the same path if any', async() => {
  788. const pathT = '/mup17_top';
  789. const path1 = '/mup17_top/mup12_emp';
  790. const path2 = '/mup17_top/mup12_emp/mup18_pub';
  791. const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
  792. const page1 = await Page.findOne({ path: path1, isEmpty: true });
  793. const page2 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED, isEmpty: false });
  794. const page3 = await Page.findOne({ path: path2 });
  795. expect(pageT).toBeTruthy();
  796. expect(page1).toBeTruthy();
  797. expect(page2).toBeTruthy();
  798. expect(page3).toBeTruthy();
  799. await Page.updatePage(page2, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_PUBLIC });
  800. const _pageT = await Page.findOne({ path: pathT });
  801. const _page1 = await Page.findOne({ path: path1, isEmpty: true }); // should be replaced
  802. const _page2 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  803. const _page3 = await Page.findOne({ path: path2 });
  804. expect(_pageT).toBeTruthy();
  805. expect(_page1).toBeNull();
  806. expect(_page2).toBeTruthy();
  807. expect(_page3).toBeTruthy();
  808. expect(_page2.grant).toBe(Page.GRANT_PUBLIC);
  809. expect(_page2.parent).toStrictEqual(_pageT._id);
  810. expect(_page3.parent).toStrictEqual(_page2._id);
  811. expect(_pageT.descendantCount).toBe(2);
  812. });
  813. });
  814. describe('Changing grant to GRANT_OWNER(onlyme)', () => {
  815. test('successfully change to GRANT_OWNER from GRANT_PUBLIC', async() => {
  816. const path = '/mup19';
  817. const _page = await Page.findOne({ path, grant: Page.GRANT_PUBLIC });
  818. expect(_page).toBeTruthy();
  819. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_OWNER });
  820. const page = await Page.findOne({ path });
  821. expect(page.grant).toBe(Page.GRANT_OWNER);
  822. expect(page.grantedUsers).toStrictEqual([dummyUser1._id]);
  823. });
  824. test('successfully change to GRANT_OWNER from GRANT_USER_GROUP', async() => {
  825. const path = '/mup20';
  826. const _page = await Page.findOne({ path, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  827. expect(_page).toBeTruthy();
  828. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', pModelUser1, { grant: Page.GRANT_OWNER });
  829. const page = await Page.findOne({ path });
  830. expect(page.grant).toBe(Page.GRANT_OWNER);
  831. expect(page.grantedUsers).toStrictEqual([pModelUser1._id]);
  832. expect(page.grantedGroup).toBeNull();
  833. });
  834. test('successfully change to GRANT_OWNER from GRANT_RESTRICTED', async() => {
  835. const path = '/mup21';
  836. const _page = await Page.findOne({ path, grant: Page.GRANT_RESTRICTED });
  837. expect(_page).toBeTruthy();
  838. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_OWNER });
  839. const page = await Page.findOne({ path });
  840. expect(page.grant).toBe(Page.GRANT_OWNER);
  841. expect(page.grantedUsers).toStrictEqual([dummyUser1._id]);
  842. });
  843. test('Failed to change to GRANT_OWNER if one of the ancestors is GRANT_USER_GROUP page', async() => {
  844. const path1 = '/mup22';
  845. const path2 = '/mup22/mup23';
  846. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  847. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  848. expect(_page1).toBeTruthy();
  849. expect(_page2).toBeTruthy();
  850. await expect(updatePage(_page1, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_OWNER }))
  851. .rejects.toThrow(new Error('The selected grant or grantedGroup is not assignable to this page.'));
  852. const page1 = await Page.findOne({ path1 });
  853. expect(page1).toBeTruthy();
  854. expect(page1.grant).toBe(Page.GRANT_PUBLIC);
  855. expect(page1.grantedUsers).not.toStrictEqual([dummyUser1._id]);
  856. });
  857. });
  858. describe('Changing grant to GRANT_USER_GROUP', () => {
  859. describe('update grant of a page under a page with GRANT_PUBLIC', () => {
  860. test('successfully change to GRANT_USER_GROUP from GRANT_PUBLIC if parent page is GRANT_PUBLIC', async() => {
  861. const path1 = '/mup24_pub';
  862. const path2 = '/mup24_pub/mup25_pub';
  863. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  864. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_PUBLIC });
  865. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdA };
  866. expect(_page1).toBeTruthy();
  867. expect(_page2).toBeTruthy();
  868. const updatedPage = await updatePage(_page2, 'new', 'old', pModelUser1, options);
  869. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  870. const page2 = await Page.findOne({ path: path2 });
  871. expect(page1).toBeTruthy();
  872. expect(page2).toBeTruthy();
  873. expect(updatedPage).toBeTruthy();
  874. expect(updatedPage._id).toStrictEqual(page2._id);
  875. expect(page2.grant).toBe(Page.GRANT_USER_GROUP);
  876. expect(page2.grantedGroup._id).toStrictEqual(groupIdA);
  877. });
  878. test('successfully change to GRANT_USER_GROUP from GRANT_RESTRICTED if parent page is GRANT_PUBLIC', async() => {
  879. const path1 = '/mup26_awl';
  880. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  881. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdA };
  882. expect(_page1).toBeTruthy();
  883. const updatedPage = await updatePage(_page1, 'new', 'old', pModelUser1, options);
  884. const page1 = await Page.findOne({ path: path1 });
  885. expect(page1).toBeTruthy();
  886. expect(updatedPage).toBeTruthy();
  887. expect(updatedPage._id).toStrictEqual(page1._id);
  888. expect(page1.grant).toBe(Page.GRANT_USER_GROUP);
  889. expect(page1.grantedGroup._id).toStrictEqual(groupIdA);
  890. expect(page1.parent).toStrictEqual(rootPage._id);
  891. });
  892. test('successfully change to GRANT_USER_GROUP from GRANT_OWNER if parent page is GRANT_PUBLIC', async() => {
  893. const path1 = '/mup27_pub';
  894. const path2 = '/mup27_pub/mup28_owner';
  895. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  896. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser1] });
  897. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdA };
  898. expect(_page1).toBeTruthy();
  899. expect(_page2).toBeTruthy();
  900. const updatedPage = await updatePage(_page2, 'new', 'old', pModelUser1, options);
  901. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  902. const page2 = await Page.findOne({ path: path2 });
  903. expect(page1).toBeTruthy();
  904. expect(page2).toBeTruthy();
  905. expect(updatedPage).toBeTruthy();
  906. expect(updatedPage._id).toStrictEqual(page2._id);
  907. expect(page2.grant).toBe(Page.GRANT_USER_GROUP);
  908. expect(page2.grantedGroup._id).toStrictEqual(groupIdA);
  909. expect(page2.grantedUsers.length).toBe(0);
  910. });
  911. });
  912. describe('update grant of a page under a page with GRANT_USER_GROUP', () => {
  913. test('successfully change to GRANT_USER_GROUP if the group to set is the child or descendant of the parent page group', async() => {
  914. const path1 = '/mup29_A';
  915. const path2 = '/mup29_A/mup30_owner';
  916. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  917. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser1] });
  918. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdB }; // change to groupB
  919. expect(_page1).toBeTruthy();
  920. expect(_page2).toBeTruthy();
  921. const updatedPage = await updatePage(_page2, 'new', 'old', pModelUser3, options);
  922. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  923. const page2 = await Page.findOne({ path: path2 });
  924. expect(page1).toBeTruthy();
  925. expect(page2).toBeTruthy();
  926. expect(updatedPage).toBeTruthy();
  927. expect(updatedPage._id).toStrictEqual(page2._id);
  928. expect(page2.grant).toBe(Page.GRANT_USER_GROUP);
  929. expect(page2.grantedGroup._id).toStrictEqual(groupIdB);
  930. expect(page2.grantedUsers.length).toBe(0);
  931. // second round to change to grandchild group
  932. const secondTimesOptions = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdC }; // change to groupC
  933. const secondTimesUpdatedPage = await updatePage(_page2, 'new', 'old', pModelUser3, secondTimesOptions);
  934. expect(secondTimesUpdatedPage).toBeTruthy();
  935. expect(secondTimesUpdatedPage.grant).toBe(Page.GRANT_USER_GROUP);
  936. expect(secondTimesUpdatedPage.grantedGroup._id).toStrictEqual(groupIdC);
  937. });
  938. test('Fail to change to GRANT_USER_GROUP if the group to set is NOT the child or descendant of the parent page group', async() => {
  939. const path1 = '/mup31_A';
  940. const path2 = '/mup31_A/mup32_owner';
  941. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  942. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser1] });
  943. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdIsolate }; // change to isolated group
  944. expect(_page1).toBeTruthy();
  945. expect(_page2).toBeTruthy();
  946. await expect(updatePage(_page2, 'new', 'old', pModelUser1, options))
  947. .rejects.toThrow(new Error('The selected grant or grantedGroup is not assignable to this page.'));
  948. const page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser1] });
  949. const pageN = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedGroup: groupIdIsolate }); // not exist
  950. expect(page2).toBeTruthy();
  951. expect(pageN).toBeNull();
  952. expect(page2.grant).toBe(Page.GRANT_OWNER);
  953. expect(page2.grantedUsers).toStrictEqual([pModelUser1._id]);
  954. });
  955. test('Fail to change to GRANT_USER_GROUP if the group to set is an ancestor of the parent page group', async() => {
  956. const path1 = '/mup33_C';
  957. const path2 = '/mup33_C/mup34_owner';
  958. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdC }); // groupC
  959. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser3] });
  960. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdA }; // change to groupA which is the grandParent
  961. expect(_page1).toBeTruthy();
  962. expect(_page2).toBeTruthy();
  963. await expect(updatePage(_page2, 'new', 'old', pModelUser3, options))
  964. .rejects.toThrow(new Error('The selected grant or grantedGroup is not assignable to this page.'));
  965. const page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser3] });
  966. const pageN = await Page.findOne({ path: path2, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdC }); // not exist
  967. expect(page2).toBeTruthy();
  968. expect(pageN).toBeNull();
  969. expect(page2.grant).toBe(Page.GRANT_OWNER);
  970. expect(page2.grantedUsers).toStrictEqual([pModelUser3._id]);
  971. });
  972. });
  973. describe('update grant of a page under a page with GRANT_OWNER', () => {
  974. test('Fail to change from GRNAT_OWNER', async() => {
  975. const path1 = '/mup35_owner';
  976. const path2 = '/mup35_owner/mup36_owner';
  977. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser1] });
  978. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_OWNER, grantedUsers: [pModelUser1] });
  979. const options = { grant: Page.GRANT_USER_GROUP, grantUserGroupId: groupIdA }; // change to groupA
  980. expect(_page1).toBeTruthy();
  981. expect(_page2).toBeTruthy();
  982. await expect(updatePage(_page2, 'new', 'old', pModelUser1, options))
  983. .rejects.toThrow(new Error('The selected grant or grantedGroup is not assignable to this page.'));
  984. const page2 = await Page.findOne({ path: path2 });
  985. const pageN = await Page.findOne({ path: path2, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA }); // not exist
  986. expect(page2).toBeTruthy();
  987. expect(pageN).toBeNull();
  988. expect(page2.grant).toBe(Page.GRANT_OWNER);
  989. expect(page2.grantedUsers).toStrictEqual([pModelUser1._id]);
  990. });
  991. });
  992. });
  993. });
  994. describe('getParentAndFillAncestors', () => {
  995. test('return parent if exist', async() => {
  996. const page1 = await Page.findOne({ path: '/PAF1' });
  997. const parent = await Page.getParentAndFillAncestors(page1.path, dummyUser1);
  998. expect(parent).toBeTruthy();
  999. expect(page1.parent).toStrictEqual(parent._id);
  1000. });
  1001. test('create parent and ancestors when they do not exist, and return the new parent', async() => {
  1002. const path1 = '/emp_anc1';
  1003. const path2 = '/emp_anc1/emp_anc2';
  1004. const path3 = '/emp_anc1/emp_anc2/PAF2';
  1005. const _page1 = await Page.findOne({ path: path1 }); // not exist
  1006. const _page2 = await Page.findOne({ path: path2 }); // not exist
  1007. const _page3 = await Page.findOne({ path: path3 }); // not exist
  1008. expect(_page1).toBeNull();
  1009. expect(_page2).toBeNull();
  1010. expect(_page3).toBeNull();
  1011. const parent = await Page.getParentAndFillAncestors(path3, dummyUser1);
  1012. const page1 = await Page.findOne({ path: path1 });
  1013. const page2 = await Page.findOne({ path: path2 });
  1014. const page3 = await Page.findOne({ path: path3 });
  1015. expect(parent._id).toStrictEqual(page2._id);
  1016. expect(parent.path).toStrictEqual(page2.path);
  1017. expect(parent.parent).toStrictEqual(page2.parent);
  1018. expect(parent).toBeTruthy();
  1019. expect(page1).toBeTruthy();
  1020. expect(page2).toBeTruthy();
  1021. expect(page3).toBeNull();
  1022. expect(page1.parent).toStrictEqual(rootPage._id);
  1023. expect(page2.parent).toStrictEqual(page1._id);
  1024. });
  1025. test('return parent even if the parent page is empty', async() => {
  1026. const path1 = '/emp_anc3';
  1027. const path2 = '/emp_anc3/PAF3';
  1028. const _page1 = await Page.findOne({ path: path1, isEmpty: true });
  1029. const _page2 = await Page.findOne({ path: path2, isEmpty: false });
  1030. expect(_page1).toBeTruthy();
  1031. expect(_page2).toBeTruthy();
  1032. const parent = await Page.getParentAndFillAncestors(_page2.path, dummyUser1);
  1033. const page1 = await Page.findOne({ path: path1, isEmpty: true }); // parent
  1034. const page2 = await Page.findOne({ path: path2, isEmpty: false });
  1035. // check for the parent (should be the same as page1)
  1036. expect(parent._id).toStrictEqual(page1._id);
  1037. expect(parent.path).toStrictEqual(page1.path);
  1038. expect(parent.parent).toStrictEqual(page1.parent);
  1039. expect(page1.parent).toStrictEqual(rootPage._id);
  1040. expect(page2.parent).toStrictEqual(page1._id);
  1041. });
  1042. test("should find parent while NOT updating private legacy page's parent", async() => {
  1043. const path1 = '/emp_anc4';
  1044. const path2 = '/emp_anc4/PAF4';
  1045. const _page1 = await Page.findOne({ path: path1, isEmpty: true, grant: Page.GRANT_PUBLIC });
  1046. const _page2 = await Page.findOne({ path: path2, isEmpty: false, grant: Page.GRANT_PUBLIC });
  1047. const _page3 = await Page.findOne({ path: path1, isEmpty: false, grant: Page.GRANT_OWNER });
  1048. expect(_page1).toBeTruthy();
  1049. expect(_page2).toBeTruthy();
  1050. expect(_page3).toBeTruthy();
  1051. expect(_page3.parent).toBeNull();
  1052. const parent = await Page.getParentAndFillAncestors(_page2.path, dummyUser1);
  1053. const page1 = await Page.findOne({ path: path1, isEmpty: true, grant: Page.GRANT_PUBLIC });
  1054. const page2 = await Page.findOne({ path: path2, isEmpty: false, grant: Page.GRANT_PUBLIC });
  1055. const page3 = await Page.findOne({ path: path1, isEmpty: false, grant: Page.GRANT_OWNER });
  1056. expect(page1).toBeTruthy();
  1057. expect(page2).toBeTruthy();
  1058. expect(page3).toBeTruthy();
  1059. expect(page3.parent).toBeNull(); // parent property of page in private legacy pages should be null
  1060. expect(page1._id).toStrictEqual(parent._id);
  1061. expect(page2.parent).toStrictEqual(parent._id);
  1062. });
  1063. });
  1064. });