v5.page.test.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  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 PageTagRelation;
  9. let Bookmark;
  10. let Comment;
  11. let ShareLink;
  12. let PageRedirect;
  13. let UserGroup;
  14. let UserGroupRelation;
  15. let xssSpy;
  16. let rootPage;
  17. let dummyUser1;
  18. let pModelUser1;
  19. let pModelUser2;
  20. let pModelUser3;
  21. let groupIdIsolate;
  22. let groupIdA;
  23. let groupIdB;
  24. let groupIdC;
  25. beforeAll(async() => {
  26. crowi = await getInstance();
  27. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', { 'app:isV5Compatible': true });
  28. jest.restoreAllMocks();
  29. User = mongoose.model('User');
  30. Page = mongoose.model('Page');
  31. Revision = mongoose.model('Revision');
  32. PageTagRelation = mongoose.model('PageTagRelation');
  33. Bookmark = mongoose.model('Bookmark');
  34. Comment = mongoose.model('Comment');
  35. ShareLink = mongoose.model('ShareLink');
  36. PageRedirect = mongoose.model('PageRedirect');
  37. UserGroup = mongoose.model('UserGroup');
  38. UserGroupRelation = mongoose.model('UserGroupRelation');
  39. dummyUser1 = await User.findOne({ username: 'v5DummyUser1' });
  40. rootPage = await Page.findOne({ path: '/' });
  41. const pModelUserId1 = new mongoose.Types.ObjectId();
  42. const pModelUserId2 = new mongoose.Types.ObjectId();
  43. const pModelUserId3 = new mongoose.Types.ObjectId();
  44. await User.insertMany([
  45. {
  46. _id: pModelUserId1,
  47. name: 'pmodelUser1',
  48. username: 'pmodelUser1',
  49. email: 'pmodelUser1@example.com',
  50. },
  51. {
  52. _id: pModelUserId2,
  53. name: 'pmodelUser2',
  54. username: 'pmodelUser2',
  55. email: 'pmodelUser2@example.com',
  56. },
  57. {
  58. _id: pModelUserId3,
  59. name: 'pModelUser3',
  60. username: 'pModelUser3',
  61. email: 'pModelUser3@example.com',
  62. },
  63. ]);
  64. pModelUser1 = await User.findOne({ _id: pModelUserId1 });
  65. pModelUser2 = await User.findOne({ _id: pModelUserId2 });
  66. pModelUser3 = await User.findOne({ _id: pModelUserId3 });
  67. groupIdIsolate = new mongoose.Types.ObjectId();
  68. groupIdA = new mongoose.Types.ObjectId();
  69. groupIdB = new mongoose.Types.ObjectId();
  70. groupIdC = new mongoose.Types.ObjectId();
  71. await UserGroup.insertMany([
  72. {
  73. _id: groupIdIsolate,
  74. name: 'pModel_groupIsolate',
  75. },
  76. {
  77. _id: groupIdA,
  78. name: 'pModel_groupA',
  79. },
  80. {
  81. _id: groupIdB,
  82. name: 'pModel_groupB',
  83. parent: groupIdA,
  84. },
  85. {
  86. _id: groupIdC,
  87. name: 'pModel_groupC',
  88. parent: groupIdB,
  89. },
  90. ]);
  91. await UserGroupRelation.insertMany([
  92. {
  93. relatedGroup: groupIdIsolate,
  94. relatedUser: pModelUserId1,
  95. createdAt: new Date(),
  96. },
  97. {
  98. relatedGroup: groupIdIsolate,
  99. relatedUser: pModelUserId2,
  100. createdAt: new Date(),
  101. },
  102. {
  103. relatedGroup: groupIdA,
  104. relatedUser: pModelUserId1,
  105. createdAt: new Date(),
  106. },
  107. {
  108. relatedGroup: groupIdA,
  109. relatedUser: pModelUserId2,
  110. createdAt: new Date(),
  111. },
  112. {
  113. relatedGroup: groupIdA,
  114. relatedUser: pModelUserId3,
  115. createdAt: new Date(),
  116. },
  117. {
  118. relatedGroup: groupIdB,
  119. relatedUser: pModelUserId2,
  120. createdAt: new Date(),
  121. },
  122. {
  123. relatedGroup: groupIdB,
  124. relatedUser: pModelUserId3,
  125. createdAt: new Date(),
  126. },
  127. {
  128. relatedGroup: groupIdC,
  129. relatedUser: pModelUserId3,
  130. createdAt: new Date(),
  131. },
  132. ]);
  133. /**
  134. * update
  135. * mup_ => model update
  136. * emp => empty => page with isEmpty: true
  137. * pub => public => GRANT_PUBLIC
  138. * awl => Anyone with the link => GRANT_RESTRICTED
  139. */
  140. const pageIdUpd1 = new mongoose.Types.ObjectId();
  141. const pageIdUpd2 = new mongoose.Types.ObjectId();
  142. const pageIdUpd3 = new mongoose.Types.ObjectId();
  143. const pageIdUpd4 = new mongoose.Types.ObjectId();
  144. const pageIdUpd5 = new mongoose.Types.ObjectId();
  145. const pageIdUpd6 = new mongoose.Types.ObjectId();
  146. const pageIdUpd7 = new mongoose.Types.ObjectId();
  147. const pageIdUpd8 = new mongoose.Types.ObjectId();
  148. const pageIdUpd9 = new mongoose.Types.ObjectId();
  149. const pageIdUpd10 = new mongoose.Types.ObjectId();
  150. const pageIdUpd11 = new mongoose.Types.ObjectId();
  151. const pageIdUpd12 = new mongoose.Types.ObjectId();
  152. const pageIdUpd13 = new mongoose.Types.ObjectId();
  153. await Page.insertMany([
  154. {
  155. _id: pageIdUpd1,
  156. path: '/mup13_top/mup1_emp',
  157. grant: Page.GRANT_PUBLIC,
  158. parent: pageIdUpd8._id,
  159. isEmpty: true,
  160. },
  161. {
  162. _id: pageIdUpd2,
  163. path: '/mup13_top/mup1_emp/mup2_pub',
  164. grant: Page.GRANT_PUBLIC,
  165. parent: pageIdUpd1._id,
  166. creator: dummyUser1,
  167. lastUpdateUser: dummyUser1._id,
  168. isEmpty: false,
  169. },
  170. {
  171. _id: pageIdUpd3,
  172. path: '/mup14_top/mup6_pub',
  173. grant: Page.GRANT_PUBLIC,
  174. creator: dummyUser1,
  175. lastUpdateUser: dummyUser1._id,
  176. parent: pageIdUpd9,
  177. isEmpty: false,
  178. descendantCount: 1,
  179. },
  180. {
  181. path: '/mup14_top/mup6_pub/mup7_pub',
  182. grant: Page.GRANT_PUBLIC,
  183. creator: dummyUser1,
  184. lastUpdateUser: dummyUser1._id,
  185. parent: pageIdUpd3,
  186. isEmpty: false,
  187. descendantCount: 0,
  188. },
  189. {
  190. _id: pageIdUpd4,
  191. path: '/mup15_top/mup8_pub',
  192. grant: Page.GRANT_PUBLIC,
  193. creator: dummyUser1,
  194. lastUpdateUser: dummyUser1._id,
  195. parent: pageIdUpd10._id,
  196. isEmpty: false,
  197. },
  198. {
  199. _id: pageIdUpd5,
  200. path: '/mup16_top/mup9_pub/mup10_pub/mup11_awl',
  201. grant: Page.GRANT_RESTRICTED,
  202. creator: dummyUser1,
  203. lastUpdateUser: dummyUser1._id,
  204. isEmpty: false,
  205. },
  206. {
  207. _id: pageIdUpd6,
  208. path: '/mup17_top/mup12_emp',
  209. isEmpty: true,
  210. parent: pageIdUpd12._id,
  211. descendantCount: 1,
  212. },
  213. {
  214. _id: pageIdUpd7,
  215. path: '/mup17_top/mup12_emp',
  216. grant: Page.GRANT_RESTRICTED,
  217. creator: dummyUser1,
  218. lastUpdateUser: dummyUser1._id,
  219. isEmpty: false,
  220. },
  221. {
  222. path: '/mup17_top/mup12_emp/mup18_pub',
  223. isEmpty: false,
  224. creator: dummyUser1,
  225. lastUpdateUser: dummyUser1._id,
  226. parent: pageIdUpd6._id,
  227. },
  228. {
  229. _id: pageIdUpd8,
  230. path: '/mup13_top',
  231. grant: Page.GRANT_PUBLIC,
  232. creator: dummyUser1,
  233. lastUpdateUser: dummyUser1._id,
  234. isEmpty: false,
  235. parent: rootPage._id,
  236. descendantCount: 2,
  237. },
  238. {
  239. _id: pageIdUpd9,
  240. path: '/mup14_top',
  241. grant: Page.GRANT_PUBLIC,
  242. creator: dummyUser1,
  243. lastUpdateUser: dummyUser1._id,
  244. isEmpty: false,
  245. parent: rootPage._id,
  246. descendantCount: 2,
  247. },
  248. {
  249. _id: pageIdUpd10,
  250. path: '/mup15_top',
  251. grant: Page.GRANT_PUBLIC,
  252. creator: dummyUser1,
  253. lastUpdateUser: dummyUser1._id,
  254. isEmpty: false,
  255. parent: rootPage._id,
  256. descendantCount: 1,
  257. },
  258. {
  259. _id: pageIdUpd11,
  260. path: '/mup16_top',
  261. grant: Page.GRANT_PUBLIC,
  262. creator: dummyUser1,
  263. lastUpdateUser: dummyUser1._id,
  264. isEmpty: false,
  265. parent: rootPage._id,
  266. descendantCount: 0,
  267. },
  268. {
  269. _id: pageIdUpd12,
  270. path: '/mup17_top',
  271. grant: Page.GRANT_PUBLIC,
  272. creator: dummyUser1,
  273. lastUpdateUser: dummyUser1._id,
  274. isEmpty: false,
  275. parent: rootPage._id,
  276. descendantCount: 1,
  277. },
  278. {
  279. path: '/mup19',
  280. grant: Page.GRANT_PUBLIC,
  281. creator: dummyUser1,
  282. lastUpdateUser: dummyUser1._id,
  283. isEmpty: false,
  284. parent: rootPage._id,
  285. descendantCount: 0,
  286. },
  287. {
  288. path: '/mup20',
  289. grant: Page.GRANT_USER_GROUP,
  290. grantedGroup: groupIdA,
  291. creator: pModelUserId1,
  292. lastUpdateUser: pModelUserId1,
  293. isEmpty: false,
  294. parent: rootPage._id,
  295. descendantCount: 0,
  296. },
  297. {
  298. path: '/mup21',
  299. grant: Page.GRANT_RESTRICTED,
  300. creator: dummyUser1,
  301. lastUpdateUser: dummyUser1._id,
  302. isEmpty: false,
  303. descendantCount: 0,
  304. },
  305. {
  306. _id: pageIdUpd13,
  307. path: '/mup22',
  308. grant: Page.GRANT_PUBLIC,
  309. creator: pModelUser1,
  310. lastUpdateUser: pModelUser1._id,
  311. isEmpty: false,
  312. parent: rootPage._id,
  313. descendantCount: 1,
  314. },
  315. {
  316. path: '/mup22/mup23',
  317. grant: Page.GRANT_USER_GROUP,
  318. grantedGroup: groupIdA,
  319. creator: pModelUserId1,
  320. lastUpdateUser: pModelUserId1,
  321. isEmpty: false,
  322. parent: pageIdUpd13,
  323. descendantCount: 0,
  324. },
  325. {
  326. path: '/mup24',
  327. grant: Page.GRANT_OWNER,
  328. grantedUsers: [dummyUser1._id],
  329. creator: dummyUser1,
  330. lastUpdateUser: dummyUser1._id,
  331. isEmpty: false,
  332. parent: rootPage._id,
  333. descendantCount: 0,
  334. },
  335. ]);
  336. /**
  337. * getParentAndFillAncestors
  338. */
  339. const pageIdPAF1 = new mongoose.Types.ObjectId();
  340. const pageIdPAF2 = new mongoose.Types.ObjectId();
  341. const pageIdPAF3 = new mongoose.Types.ObjectId();
  342. await Page.insertMany([
  343. {
  344. _id: pageIdPAF1,
  345. path: '/PAF1',
  346. grant: Page.GRANT_PUBLIC,
  347. creator: dummyUser1,
  348. lastUpdateUser: dummyUser1._id,
  349. isEmpty: false,
  350. parent: rootPage._id,
  351. descendantCount: 0,
  352. },
  353. {
  354. _id: pageIdPAF2,
  355. path: '/emp_anc3',
  356. grant: Page.GRANT_PUBLIC,
  357. isEmpty: true,
  358. descendantCount: 1,
  359. parent: rootPage._id,
  360. },
  361. {
  362. path: '/emp_anc3/PAF3',
  363. grant: Page.GRANT_PUBLIC,
  364. creator: dummyUser1,
  365. lastUpdateUser: dummyUser1._id,
  366. isEmpty: false,
  367. descendantCount: 0,
  368. parent: pageIdPAF2,
  369. },
  370. {
  371. _id: pageIdPAF3,
  372. path: '/emp_anc4',
  373. grant: Page.GRANT_PUBLIC,
  374. isEmpty: true,
  375. descendantCount: 1,
  376. parent: rootPage._id,
  377. },
  378. {
  379. path: '/emp_anc4/PAF4',
  380. grant: Page.GRANT_PUBLIC,
  381. creator: dummyUser1,
  382. lastUpdateUser: dummyUser1._id,
  383. isEmpty: false,
  384. descendantCount: 0,
  385. parent: pageIdPAF3,
  386. },
  387. {
  388. path: '/emp_anc4',
  389. grant: Page.GRANT_OWNER,
  390. grantedUsers: [dummyUser1._id],
  391. creator: dummyUser1,
  392. lastUpdateUser: dummyUser1._id,
  393. isEmpty: false,
  394. },
  395. {
  396. path: '/get_parent_A',
  397. creator: dummyUser1,
  398. lastUpdateUser: dummyUser1,
  399. parent: null,
  400. },
  401. {
  402. path: '/get_parent_A/get_parent_B',
  403. creator: dummyUser1,
  404. lastUpdateUser: dummyUser1,
  405. parent: null,
  406. },
  407. {
  408. path: '/get_parent_C',
  409. creator: dummyUser1,
  410. lastUpdateUser: dummyUser1,
  411. parent: rootPage._id,
  412. },
  413. {
  414. path: '/get_parent_C/get_parent_D',
  415. creator: dummyUser1,
  416. lastUpdateUser: dummyUser1,
  417. parent: null,
  418. },
  419. ]);
  420. });
  421. describe('update', () => {
  422. const updatePage = async(page, newRevisionBody, oldRevisionBody, user, options = {}) => {
  423. const mockedRenameSubOperation = jest.spyOn(Page, 'emitPageEventUpdate').mockReturnValue(null);
  424. const savedPage = await Page.updatePage(page, newRevisionBody, oldRevisionBody, user, options);
  425. mockedRenameSubOperation.mockRestore();
  426. return savedPage;
  427. };
  428. describe('Changing grant from PUBLIC to RESTRICTED of', () => {
  429. test('an only-child page will delete its empty parent page', async() => {
  430. const pathT = '/mup13_top';
  431. const path1 = '/mup13_top/mup1_emp';
  432. const path2 = '/mup13_top/mup1_emp/mup2_pub';
  433. const pageT = await Page.findOne({ path: pathT, descendantCount: 2 });
  434. const page1 = await Page.findOne({ path: path1, isEmpty: true });
  435. const page2 = await Page.findOne({ path: path2, grant: Page.GRANT_PUBLIC });
  436. expect(pageT).toBeTruthy();
  437. expect(page1).toBeTruthy();
  438. expect(page2).toBeTruthy();
  439. const options = { grant: Page.GRANT_RESTRICTED, grantUserGroupId: null };
  440. await Page.updatePage(page2, 'newRevisionBody', 'oldRevisionBody', dummyUser1, options);
  441. const _pageT = await Page.findOne({ path: pathT });
  442. const _page1 = await Page.findOne({ path: path1 });
  443. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_RESTRICTED });
  444. expect(_pageT).toBeTruthy();
  445. expect(_page1).toBeNull();
  446. expect(_page2).toBeTruthy();
  447. expect(_pageT.descendantCount).toBe(1);
  448. });
  449. test('a page that has children will create an empty page with the same path and it becomes a new parent', async() => {
  450. const pathT = '/mup14_top';
  451. const path1 = '/mup14_top/mup6_pub';
  452. const path2 = '/mup14_top/mup6_pub/mup7_pub';
  453. const top = await Page.findOne({ path: pathT, descendantCount: 2 });
  454. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  455. const page2 = await Page.findOne({ path: path2, grant: Page.GRANT_PUBLIC });
  456. expect(top).toBeTruthy();
  457. expect(page1).toBeTruthy();
  458. expect(page2).toBeTruthy();
  459. await Page.updatePage(page1, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  460. const _top = await Page.findOne({ path: pathT });
  461. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  462. const _page2 = await Page.findOne({ path: path2 });
  463. const _pageN = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  464. expect(_page1).toBeTruthy();
  465. expect(_page2).toBeTruthy();
  466. expect(_pageN).toBeTruthy();
  467. expect(_page1.parent).toBeNull();
  468. expect(_page2.parent).toStrictEqual(_pageN._id);
  469. expect(_pageN.parent).toStrictEqual(top._id);
  470. expect(_pageN.isEmpty).toBe(true);
  471. expect(_pageN.descendantCount).toBe(1);
  472. expect(_top.descendantCount).toBe(1);
  473. });
  474. test('of a leaf page will NOT have an empty page with the same path', async() => {
  475. const pathT = '/mup15_top';
  476. const path1 = '/mup15_top/mup8_pub';
  477. const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
  478. const page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  479. const count = await Page.count({ path: path1 });
  480. expect(pageT).toBeTruthy();
  481. expect(page1).toBeTruthy();
  482. expect(count).toBe(1);
  483. await Page.updatePage(page1, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  484. const _pageT = await Page.findOne({ path: pathT });
  485. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED });
  486. const _pageNotExist = await Page.findOne({ path: path1, isEmpty: true });
  487. expect(_pageT).toBeTruthy();
  488. expect(_page1).toBeTruthy();
  489. expect(_pageNotExist).toBeNull();
  490. expect(_pageT.descendantCount).toBe(0);
  491. });
  492. });
  493. describe('Changing grant to GRANT_RESTRICTED', () => {
  494. test('successfully change to GRANT_RESTRICTED from GRANT_OWNER', async() => {
  495. const path = '/mup24';
  496. const _page = await Page.findOne({ path, grant: Page.GRANT_OWNER, grantedUsers: [dummyUser1._id] });
  497. expect(_page).toBeTruthy();
  498. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_RESTRICTED });
  499. const page = await Page.findOne({ path });
  500. expect(page).toBeTruthy();
  501. expect(page.grant).toBe(Page.GRANT_RESTRICTED);
  502. expect(page.grantedUsers).toStrictEqual([]);
  503. });
  504. });
  505. describe('Changing grant from RESTRICTED to PUBLIC of', () => {
  506. test('a page will create ancestors if they do not exist', async() => {
  507. const pathT = '/mup16_top';
  508. const path1 = '/mup16_top/mup9_pub';
  509. const path2 = '/mup16_top/mup9_pub/mup10_pub';
  510. const path3 = '/mup16_top/mup9_pub/mup10_pub/mup11_awl';
  511. const top = await Page.findOne({ path: pathT });
  512. const page1 = await Page.findOne({ path: path1 });
  513. const page2 = await Page.findOne({ path: path2 });
  514. const page3 = await Page.findOne({ path: path3, grant: Page.GRANT_RESTRICTED });
  515. expect(top).toBeTruthy();
  516. expect(page3).toBeTruthy();
  517. expect(page1).toBeNull();
  518. expect(page2).toBeNull();
  519. await Page.updatePage(page3, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_PUBLIC });
  520. const _pageT = await Page.findOne({ path: pathT });
  521. const _page1 = await Page.findOne({ path: path1, isEmpty: true });
  522. const _page2 = await Page.findOne({ path: path2, isEmpty: true });
  523. const _page3 = await Page.findOne({ path: path3, grant: Page.GRANT_PUBLIC });
  524. expect(_page1).toBeTruthy();
  525. expect(_page2).toBeTruthy();
  526. expect(_page3).toBeTruthy();
  527. expect(_page1.parent).toStrictEqual(top._id);
  528. expect(_page2.parent).toStrictEqual(_page1._id);
  529. expect(_page3.parent).toStrictEqual(_page2._id);
  530. expect(_pageT.descendantCount).toBe(1);
  531. });
  532. test('a page will replace an empty page with the same path if any', async() => {
  533. const pathT = '/mup17_top';
  534. const path1 = '/mup17_top/mup12_emp';
  535. const path2 = '/mup17_top/mup12_emp/mup18_pub';
  536. const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
  537. const page1 = await Page.findOne({ path: path1, isEmpty: true });
  538. const page2 = await Page.findOne({ path: path1, grant: Page.GRANT_RESTRICTED, isEmpty: false });
  539. const page3 = await Page.findOne({ path: path2 });
  540. expect(pageT).toBeTruthy();
  541. expect(page1).toBeTruthy();
  542. expect(page2).toBeTruthy();
  543. expect(page3).toBeTruthy();
  544. await Page.updatePage(page2, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_PUBLIC });
  545. const _pageT = await Page.findOne({ path: pathT });
  546. const _page1 = await Page.findOne({ path: path1, isEmpty: true }); // should be replaced
  547. const _page2 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  548. const _page3 = await Page.findOne({ path: path2 });
  549. expect(_pageT).toBeTruthy();
  550. expect(_page1).toBeNull();
  551. expect(_page2).toBeTruthy();
  552. expect(_page3).toBeTruthy();
  553. expect(_page2.grant).toBe(Page.GRANT_PUBLIC);
  554. expect(_page2.parent).toStrictEqual(_pageT._id);
  555. expect(_page3.parent).toStrictEqual(_page2._id);
  556. expect(_pageT.descendantCount).toBe(2);
  557. });
  558. });
  559. describe('Changing grant to GRANT_OWNER(onlyme)', () => {
  560. test('successfully change to GRANT_OWNER from GRANT_PUBLIC', async() => {
  561. const path = '/mup19';
  562. const _page = await Page.findOne({ path, grant: Page.GRANT_PUBLIC });
  563. expect(_page).toBeTruthy();
  564. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_OWNER });
  565. const page = await Page.findOne({ path });
  566. expect(page.grant).toBe(Page.GRANT_OWNER);
  567. expect(page.grantedUsers).toStrictEqual([dummyUser1._id]);
  568. });
  569. test('successfully change to GRANT_OWNER from GRANT_USER_GROUP', async() => {
  570. const path = '/mup20';
  571. const _page = await Page.findOne({ path, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  572. expect(_page).toBeTruthy();
  573. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', pModelUser1, { grant: Page.GRANT_OWNER });
  574. const page = await Page.findOne({ path });
  575. expect(page.grant).toBe(Page.GRANT_OWNER);
  576. expect(page.grantedUsers).toStrictEqual([pModelUser1._id]);
  577. expect(page.grantedGroup).toBeNull();
  578. });
  579. test('successfully change to GRANT_OWNER from GRANT_RESTRICTED', async() => {
  580. const path = '/mup21';
  581. const _page = await Page.findOne({ path, grant: Page.GRANT_RESTRICTED });
  582. expect(_page).toBeTruthy();
  583. await updatePage(_page, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_OWNER });
  584. const page = await Page.findOne({ path });
  585. expect(page.grant).toBe(Page.GRANT_OWNER);
  586. expect(page.grantedUsers).toStrictEqual([dummyUser1._id]);
  587. });
  588. test('Failed to change to GRANT_OWNER if one of the ancestors is GRANT_USER_GROUP page', async() => {
  589. const path1 = '/mup22';
  590. const path2 = '/mup22/mup23';
  591. const _page1 = await Page.findOne({ path: path1, grant: Page.GRANT_PUBLIC });
  592. const _page2 = await Page.findOne({ path: path2, grant: Page.GRANT_USER_GROUP, grantedGroup: groupIdA });
  593. expect(_page1).toBeTruthy();
  594. expect(_page2).toBeTruthy();
  595. await expect(updatePage(_page1, 'newRevisionBody', 'oldRevisionBody', dummyUser1, { grant: Page.GRANT_OWNER }))
  596. .rejects.toThrow(new Error('The selected grant or grantedGroup is not assignable to this page.'));
  597. const page1 = await Page.findOne({ path1 });
  598. expect(page1).toBeTruthy();
  599. expect(page1.grant).toBe(Page.GRANT_PUBLIC);
  600. expect(page1.grantedUsers).not.toStrictEqual([dummyUser1._id]);
  601. });
  602. });
  603. });
  604. describe('getParentAndFillAncestors', () => {
  605. test('return parent if exist', async() => {
  606. const page1 = await Page.findOne({ path: '/PAF1' });
  607. const parent = await crowi.pageService.getParentAndFillAncestorsByUser(dummyUser1, page1.path);
  608. expect(parent).toBeTruthy();
  609. expect(page1.parent).toStrictEqual(parent._id);
  610. });
  611. test('create parent and ancestors when they do not exist, and return the new parent', async() => {
  612. const path1 = '/emp_anc1';
  613. const path2 = '/emp_anc1/emp_anc2';
  614. const path3 = '/emp_anc1/emp_anc2/PAF2';
  615. const _page1 = await Page.findOne({ path: path1 }); // not exist
  616. const _page2 = await Page.findOne({ path: path2 }); // not exist
  617. const _page3 = await Page.findOne({ path: path3 }); // not exist
  618. expect(_page1).toBeNull();
  619. expect(_page2).toBeNull();
  620. expect(_page3).toBeNull();
  621. const parent = await crowi.pageService.getParentAndFillAncestorsByUser(dummyUser1, path3);
  622. const page1 = await Page.findOne({ path: path1 });
  623. const page2 = await Page.findOne({ path: path2 });
  624. const page3 = await Page.findOne({ path: path3 });
  625. expect(parent._id).toStrictEqual(page2._id);
  626. expect(parent.path).toStrictEqual(page2.path);
  627. expect(parent.parent).toStrictEqual(page2.parent);
  628. expect(parent).toBeTruthy();
  629. expect(page1).toBeTruthy();
  630. expect(page2).toBeTruthy();
  631. expect(page3).toBeNull();
  632. expect(page1.parent).toStrictEqual(rootPage._id);
  633. expect(page2.parent).toStrictEqual(page1._id);
  634. });
  635. test('return parent even if the parent page is empty', async() => {
  636. const path1 = '/emp_anc3';
  637. const path2 = '/emp_anc3/PAF3';
  638. const _page1 = await Page.findOne({ path: path1, isEmpty: true });
  639. const _page2 = await Page.findOne({ path: path2, isEmpty: false });
  640. expect(_page1).toBeTruthy();
  641. expect(_page2).toBeTruthy();
  642. const parent = await crowi.pageService.getParentAndFillAncestorsByUser(dummyUser1, _page2.path);
  643. const page1 = await Page.findOne({ path: path1, isEmpty: true }); // parent
  644. const page2 = await Page.findOne({ path: path2, isEmpty: false });
  645. // check for the parent (should be the same as page1)
  646. expect(parent._id).toStrictEqual(page1._id);
  647. expect(parent.path).toStrictEqual(page1.path);
  648. expect(parent.parent).toStrictEqual(page1.parent);
  649. expect(page1.parent).toStrictEqual(rootPage._id);
  650. expect(page2.parent).toStrictEqual(page1._id);
  651. });
  652. test('should find parent while NOT updating private legacy page\'s parent', async() => {
  653. const path1 = '/emp_anc4';
  654. const path2 = '/emp_anc4/PAF4';
  655. const _page1 = await Page.findOne({ path: path1, isEmpty: true, grant: Page.GRANT_PUBLIC });
  656. const _page2 = await Page.findOne({ path: path2, isEmpty: false, grant: Page.GRANT_PUBLIC });
  657. const _page3 = await Page.findOne({ path: path1, isEmpty: false, grant: Page.GRANT_OWNER });
  658. expect(_page1).toBeTruthy();
  659. expect(_page2).toBeTruthy();
  660. expect(_page3).toBeTruthy();
  661. expect(_page3.parent).toBeNull();
  662. const parent = await crowi.pageService.getParentAndFillAncestorsByUser(dummyUser1, _page2.path);
  663. const page1 = await Page.findOne({ path: path1, isEmpty: true, grant: Page.GRANT_PUBLIC });
  664. const page2 = await Page.findOne({ path: path2, isEmpty: false, grant: Page.GRANT_PUBLIC });
  665. const page3 = await Page.findOne({ path: path1, isEmpty: false, grant: Page.GRANT_OWNER });
  666. expect(page1).toBeTruthy();
  667. expect(page2).toBeTruthy();
  668. expect(page3).toBeTruthy();
  669. expect(page3.parent).toBeNull(); // parent property of page in private legacy pages should be null
  670. expect(page1._id).toStrictEqual(parent._id);
  671. expect(page2.parent).toStrictEqual(parent._id);
  672. });
  673. test('should find parent while NOT creating unnecessary empty pages with all v4 public pages', async() => {
  674. // All pages does not have parent (v4 schema)
  675. const _pageA = await Page.findOne({
  676. path: '/get_parent_A',
  677. grant: Page.GRANT_PUBLIC,
  678. isEmpty: false,
  679. parent: null,
  680. });
  681. const _pageAB = await Page.findOne({
  682. path: '/get_parent_A/get_parent_B',
  683. grant: Page.GRANT_PUBLIC,
  684. isEmpty: false,
  685. parent: null,
  686. });
  687. const _emptyA = await Page.findOne({
  688. path: '/get_parent_A',
  689. grant: Page.GRANT_PUBLIC,
  690. isEmpty: true,
  691. });
  692. const _emptyAB = await Page.findOne({
  693. path: '/get_parent_A/get_parent_B',
  694. grant: Page.GRANT_PUBLIC,
  695. isEmpty: true,
  696. });
  697. expect(_pageA).not.toBeNull();
  698. expect(_pageAB).not.toBeNull();
  699. expect(_emptyA).toBeNull();
  700. expect(_emptyAB).toBeNull();
  701. const parent = await crowi.pageService.getParentAndFillAncestorsByUser(dummyUser1, '/get_parent_A/get_parent_B/get_parent_C');
  702. const pageA = await Page.findOne({ path: '/get_parent_A', grant: Page.GRANT_PUBLIC, isEmpty: false });
  703. const pageAB = await Page.findOne({ path: '/get_parent_A/get_parent_B', grant: Page.GRANT_PUBLIC, isEmpty: false });
  704. const emptyA = await Page.findOne({ path: '/get_parent_A', grant: Page.GRANT_PUBLIC, isEmpty: true });
  705. const emptyAB = await Page.findOne({ path: '/get_parent_A/get_parent_B', grant: Page.GRANT_PUBLIC, isEmpty: true });
  706. // -- Check existance
  707. expect(parent).not.toBeNull();
  708. expect(pageA).not.toBeNull();
  709. expect(pageAB).not.toBeNull();
  710. expect(emptyA).toBeNull();
  711. expect(emptyAB).toBeNull();
  712. // -- Check parent
  713. expect(pageA.parent).not.toBeNull();
  714. expect(pageAB.parent).not.toBeNull();
  715. });
  716. test('should find parent while NOT creating unnecessary empty pages with some v5 public pages', async() => {
  717. const _pageC = await Page.findOne({
  718. path: '/get_parent_C',
  719. grant: Page.GRANT_PUBLIC,
  720. isEmpty: false,
  721. parent: { $ne: null },
  722. });
  723. const _pageCD = await Page.findOne({
  724. path: '/get_parent_C/get_parent_D',
  725. grant: Page.GRANT_PUBLIC,
  726. isEmpty: false,
  727. });
  728. const _emptyC = await Page.findOne({
  729. path: '/get_parent_C',
  730. grant: Page.GRANT_PUBLIC,
  731. isEmpty: true,
  732. });
  733. const _emptyCD = await Page.findOne({
  734. path: '/get_parent_C/get_parent_D',
  735. grant: Page.GRANT_PUBLIC,
  736. isEmpty: true,
  737. });
  738. expect(_pageC).not.toBeNull();
  739. expect(_pageCD).not.toBeNull();
  740. expect(_emptyC).toBeNull();
  741. expect(_emptyCD).toBeNull();
  742. const parent = await crowi.pageService.getParentAndFillAncestorsByUser(dummyUser1, '/get_parent_C/get_parent_D/get_parent_E');
  743. const pageC = await Page.findOne({ path: '/get_parent_C', grant: Page.GRANT_PUBLIC, isEmpty: false });
  744. const pageCD = await Page.findOne({ path: '/get_parent_C/get_parent_D', grant: Page.GRANT_PUBLIC, isEmpty: false });
  745. const emptyC = await Page.findOne({ path: '/get_parent_C', grant: Page.GRANT_PUBLIC, isEmpty: true });
  746. const emptyCD = await Page.findOne({ path: '/get_parent_C/get_parent_D', grant: Page.GRANT_PUBLIC, isEmpty: true });
  747. // -- Check existance
  748. expect(parent).not.toBeNull();
  749. expect(pageC).not.toBeNull();
  750. expect(pageCD).not.toBeNull();
  751. expect(emptyC).toBeNull();
  752. expect(emptyCD).toBeNull();
  753. // -- Check parent attribute
  754. expect(pageC.parent).toStrictEqual(rootPage._id);
  755. expect(pageCD.parent).toStrictEqual(pageC._id);
  756. // -- Check the found parent
  757. expect(parent.toObject()).toStrictEqual(pageCD.toObject());
  758. });
  759. });
  760. });