v5.migration.test.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119
  1. /* eslint-disable max-len */
  2. const mongoose = require('mongoose');
  3. const { getInstance } = require('../setup-crowi');
  4. describe('V5 page migration', () => {
  5. let crowi;
  6. let Page;
  7. let User;
  8. let UserGroup;
  9. let UserGroupRelation;
  10. let testUser1;
  11. let rootUser;
  12. let rootPage;
  13. const rootUserGroupId = new mongoose.Types.ObjectId();
  14. const testUser1GroupId = new mongoose.Types.ObjectId();
  15. const groupIdIsolate = new mongoose.Types.ObjectId();
  16. const groupIdA = new mongoose.Types.ObjectId();
  17. const groupIdB = new mongoose.Types.ObjectId();
  18. const groupIdC = new mongoose.Types.ObjectId();
  19. const pageId1 = new mongoose.Types.ObjectId();
  20. const pageId2 = new mongoose.Types.ObjectId();
  21. const pageId3 = new mongoose.Types.ObjectId();
  22. const pageId4 = new mongoose.Types.ObjectId();
  23. const pageId5 = new mongoose.Types.ObjectId();
  24. const pageId6 = new mongoose.Types.ObjectId();
  25. const pageId7 = new mongoose.Types.ObjectId();
  26. const pageId8 = new mongoose.Types.ObjectId();
  27. const pageId9 = new mongoose.Types.ObjectId();
  28. const pageId10 = new mongoose.Types.ObjectId();
  29. const pageId11 = new mongoose.Types.ObjectId();
  30. beforeAll(async() => {
  31. jest.restoreAllMocks();
  32. crowi = await getInstance();
  33. Page = mongoose.model('Page');
  34. User = mongoose.model('User');
  35. UserGroup = mongoose.model('UserGroup');
  36. UserGroupRelation = mongoose.model('UserGroupRelation');
  37. await crowi.configManager.updateConfigsInTheSameNamespace('crowi', { 'app:isV5Compatible': true });
  38. await User.insertMany([
  39. { name: 'rootUser', username: 'rootUser', email: 'rootUser@example.com' },
  40. { name: 'testUser1', username: 'testUser1', email: 'testUser1@example.com' },
  41. ]);
  42. rootUser = await User.findOne({ username: 'rootUser' });
  43. testUser1 = await User.findOne({ username: 'testUser1' });
  44. rootPage = await Page.findOne({ path: '/' });
  45. await UserGroup.insertMany([
  46. {
  47. _id: rootUserGroupId,
  48. name: 'rootUserGroup',
  49. },
  50. {
  51. _id: testUser1GroupId,
  52. name: 'testUser1Group',
  53. },
  54. {
  55. _id: groupIdIsolate,
  56. name: 'groupIsolate',
  57. },
  58. {
  59. _id: groupIdA,
  60. name: 'groupA',
  61. },
  62. {
  63. _id: groupIdB,
  64. name: 'groupB',
  65. parent: groupIdA,
  66. },
  67. {
  68. _id: groupIdC,
  69. name: 'groupC',
  70. parent: groupIdB,
  71. },
  72. ]);
  73. await UserGroupRelation.insertMany([
  74. {
  75. relatedGroup: rootUserGroupId,
  76. relatedUser: rootUser._id,
  77. },
  78. {
  79. relatedGroup: testUser1GroupId,
  80. relatedUser: testUser1._id,
  81. },
  82. {
  83. relatedGroup: groupIdIsolate,
  84. relatedUser: testUser1._id,
  85. },
  86. {
  87. relatedGroup: groupIdA,
  88. relatedUser: testUser1._id,
  89. },
  90. {
  91. relatedGroup: groupIdB,
  92. relatedUser: testUser1._id,
  93. },
  94. {
  95. relatedGroup: groupIdC,
  96. relatedUser: testUser1._id,
  97. },
  98. ]);
  99. await Page.insertMany([
  100. {
  101. path: '/private1',
  102. grant: Page.GRANT_OWNER,
  103. creator: testUser1,
  104. lastUpdateUser: testUser1,
  105. grantedUsers: [testUser1._id],
  106. },
  107. {
  108. path: '/dummyParent/private1',
  109. grant: Page.GRANT_OWNER,
  110. creator: testUser1,
  111. lastUpdateUser: testUser1,
  112. grantedUsers: [testUser1._id],
  113. },
  114. {
  115. path: '/dummyParent/private1/private2',
  116. grant: Page.GRANT_OWNER,
  117. creator: testUser1,
  118. lastUpdateUser: testUser1,
  119. grantedUsers: [testUser1._id],
  120. },
  121. {
  122. path: '/dummyParent/private1/private3',
  123. grant: Page.GRANT_OWNER,
  124. creator: testUser1,
  125. lastUpdateUser: testUser1,
  126. grantedUsers: [testUser1._id],
  127. },
  128. {
  129. _id: pageId1,
  130. path: '/normalize_1',
  131. parent: rootPage._id,
  132. grant: Page.GRANT_PUBLIC,
  133. isEmpty: true,
  134. },
  135. {
  136. _id: pageId2,
  137. path: '/normalize_1/normalize_2',
  138. parent: pageId1,
  139. grant: Page.GRANT_USER_GROUP,
  140. grantedGroup: groupIdB,
  141. grantedUsers: [testUser1._id],
  142. },
  143. {
  144. _id: pageId3,
  145. path: '/normalize_1',
  146. grant: Page.GRANT_USER_GROUP,
  147. grantedGroup: groupIdA,
  148. grantedUsers: [testUser1._id],
  149. },
  150. {
  151. _id: pageId4,
  152. path: '/normalize_4',
  153. parent: rootPage._id,
  154. grant: Page.GRANT_PUBLIC,
  155. isEmpty: true,
  156. },
  157. {
  158. _id: pageId5,
  159. path: '/normalize_4/normalize_5',
  160. parent: pageId4,
  161. grant: Page.GRANT_USER_GROUP,
  162. grantedGroup: groupIdA,
  163. grantedUsers: [testUser1._id],
  164. },
  165. {
  166. _id: pageId6,
  167. path: '/normalize_4',
  168. grant: Page.GRANT_USER_GROUP,
  169. grantedGroup: groupIdIsolate,
  170. grantedUsers: [testUser1._id],
  171. },
  172. {
  173. path: '/normalize_7/normalize_8_gA',
  174. grant: Page.GRANT_USER_GROUP,
  175. creator: testUser1,
  176. grantedGroup: groupIdA,
  177. grantedUsers: [testUser1._id],
  178. },
  179. {
  180. path: '/normalize_7/normalize_8_gA/normalize_9_gB',
  181. grant: Page.GRANT_USER_GROUP,
  182. creator: testUser1,
  183. grantedGroup: groupIdB,
  184. grantedUsers: [testUser1._id],
  185. },
  186. {
  187. path: '/normalize_7/normalize_8_gC',
  188. grant: Page.GRANT_USER_GROUP,
  189. grantedGroup: groupIdC,
  190. grantedUsers: [testUser1._id],
  191. },
  192. {
  193. _id: pageId7,
  194. path: '/normalize_10',
  195. grant: Page.GRANT_PUBLIC,
  196. isEmpty: true,
  197. parent: rootPage._id,
  198. descendantCount: 3,
  199. },
  200. {
  201. _id: pageId8,
  202. path: '/normalize_10/normalize_11_gA',
  203. isEmpty: true,
  204. parent: pageId7,
  205. descendantCount: 1,
  206. },
  207. {
  208. _id: pageId9, // not v5
  209. path: '/normalize_10/normalize_11_gA',
  210. grant: Page.GRANT_USER_GROUP,
  211. grantedGroup: groupIdA,
  212. },
  213. {
  214. _id: pageId10,
  215. path: '/normalize_10/normalize_11_gA/normalize_11_gB',
  216. grant: Page.GRANT_USER_GROUP,
  217. grantedGroup: groupIdB,
  218. parent: pageId8,
  219. descendantCount: 0,
  220. },
  221. {
  222. _id: pageId11,
  223. path: '/normalize_10/normalize_12_gC',
  224. grant: Page.GRANT_USER_GROUP,
  225. grantedGroup: groupIdC,
  226. grantedUsers: [testUser1._id],
  227. parent: pageId7,
  228. descendantCount: 0,
  229. },
  230. ]);
  231. });
  232. const normalizeParentRecursivelyByPages = async(pages, user) => {
  233. return crowi.pageService.normalizeParentRecursivelyByPages(pages, user);
  234. };
  235. const normalizeParentByPage = async(page, user) => {
  236. return crowi.pageService.normalizeParentByPage(page, user);
  237. };
  238. describe('normalizeParentRecursivelyByPages()', () => {
  239. test('should migrate all pages specified by pageIds', async() => {
  240. jest.restoreAllMocks();
  241. const pagesToRun = await Page.find({ path: { $in: ['/private1', '/dummyParent/private1'] } });
  242. // migrate
  243. await normalizeParentRecursivelyByPages(pagesToRun, testUser1);
  244. const migratedPages = await Page.find({
  245. path: {
  246. $in: ['/private1', '/dummyParent', '/dummyParent/private1', '/dummyParent/private1/private2', '/dummyParent/private1/private3'],
  247. },
  248. });
  249. const migratedPagePaths = migratedPages.filter(doc => doc.parent != null).map(doc => doc.path);
  250. const expected = ['/private1', '/dummyParent', '/dummyParent/private1', '/dummyParent/private1/private2', '/dummyParent/private1/private3'];
  251. expect(migratedPagePaths.sort()).toStrictEqual(expected.sort());
  252. });
  253. test('should change all v4 pages with usergroup to v5 compatible and create new parent page', async() => {
  254. const page8 = await Page.findOne({ path: '/normalize_7/normalize_8_gA' });
  255. const page9 = await Page.findOne({ path: '/normalize_7/normalize_8_gA/normalize_9_gB' });
  256. const page10 = await Page.findOne({ path: '/normalize_7/normalize_8_gC' });
  257. const page11 = await Page.findOne({ path: '/normalize_7' });
  258. expect(page8).toBeTruthy();
  259. expect(page9).toBeTruthy();
  260. expect(page10).toBeTruthy();
  261. expect(page11).toBeNull();
  262. await normalizeParentRecursivelyByPages([page8, page9, page10], testUser1);
  263. // AM => After Migration
  264. const page7 = await Page.findOne({ path: '/normalize_7' });
  265. const page8AM = await Page.findOne({ path: '/normalize_7/normalize_8_gA' });
  266. const page9AM = await Page.findOne({ path: '/normalize_7/normalize_8_gA/normalize_9_gB' });
  267. const page10AM = await Page.findOne({ path: '/normalize_7/normalize_8_gC' });
  268. expect(page7).toBeTruthy();
  269. expect(page8AM).toBeTruthy();
  270. expect(page9AM).toBeTruthy();
  271. expect(page10AM).toBeTruthy();
  272. expect(page7.isEmpty).toBe(true);
  273. expect(page7.parent).toStrictEqual(rootPage._id);
  274. expect(page8AM.parent).toStrictEqual(page7._id);
  275. expect(page9AM.parent).toStrictEqual(page8AM._id);
  276. expect(page10AM.parent).toStrictEqual(page7._id);
  277. });
  278. test('should replace empty page with same path with new non-empty page and update all related children\'s parent', async() => {
  279. const page1 = await Page.findOne({ path: '/normalize_10', isEmpty: true, parent: { $ne: null } });
  280. const page2 = await Page.findOne({
  281. path: '/normalize_10/normalize_11_gA', _id: pageId8, isEmpty: true, parent: { $ne: null },
  282. });
  283. const page3 = await Page.findOne({ path: '/normalize_10/normalize_11_gA', _id: pageId9, parent: null }); // not v5
  284. const page4 = await Page.findOne({ path: '/normalize_10/normalize_11_gA/normalize_11_gB', parent: { $ne: null } });
  285. const page5 = await Page.findOne({ path: '/normalize_10/normalize_12_gC', parent: { $ne: null } });
  286. expect(page1).toBeTruthy();
  287. expect(page2).toBeTruthy();
  288. expect(page3).toBeTruthy();
  289. expect(page4).toBeTruthy();
  290. expect(page5).toBeTruthy();
  291. await normalizeParentRecursivelyByPages([page3], testUser1);
  292. // AM => After Migration
  293. const page1AM = await Page.findOne({ path: '/normalize_10' });
  294. const page2AM = await Page.findOne({ path: '/normalize_10/normalize_11_gA', _id: pageId8 });
  295. const page3AM = await Page.findOne({ path: '/normalize_10/normalize_11_gA', _id: pageId9 });
  296. const page4AM = await Page.findOne({ path: '/normalize_10/normalize_11_gA/normalize_11_gB' });
  297. const page5AM = await Page.findOne({ path: '/normalize_10/normalize_12_gC' });
  298. expect(page1AM).toBeTruthy();
  299. expect(page3AM).toBeTruthy();
  300. expect(page4AM).toBeTruthy();
  301. expect(page5AM).toBeTruthy();
  302. expect(page2AM).toBeNull();
  303. expect(page1AM.isEmpty).toBeTruthy();
  304. expect(page3AM.parent).toStrictEqual(page1AM._id);
  305. expect(page4AM.parent).toStrictEqual(page3AM._id);
  306. expect(page5AM.parent).toStrictEqual(page1AM._id);
  307. expect(page3AM.isEmpty).toBe(false);
  308. });
  309. });
  310. describe('should normalize only selected pages recursively (while observing the page permission rule)', () => {
  311. /*
  312. * # Test flow 1
  313. * - Existing pages
  314. * - v5 compatible pages
  315. * - /normalize_a (empty)
  316. * - /normalize_a/normalize_b (public)
  317. * - v4 pages
  318. * - /normalize_a (user group)
  319. * - /normalize_c (user group)
  320. *
  321. * - Normalize /normalize_a (user group)
  322. * - Expect
  323. * - Error should be thrown
  324. *
  325. *
  326. * # Test flow 2
  327. * - Existing pages
  328. * - v5 compatible pages
  329. * - /normalize_d (empty)
  330. * - /normalize_d/normalize_e (user group)
  331. * - v4 pages
  332. * - /normalize_d (user group)
  333. * - /normalize_f (user group)
  334. *
  335. * - Normalize /normalize_d (user group)
  336. * - Expect
  337. * - Normalization succeeds
  338. * - /normalize_f (user group) remains in v4 schema
  339. *
  340. *
  341. * # Test flow 3 (should replace all unnecessary empty pages)
  342. * - Existing pages
  343. * - v5 compatible pages
  344. * - / (root)
  345. * - /normalize_g (public)
  346. * - v4 pages
  347. * - /normalize_g/normalize_h (only me)
  348. * - /normalize_g/normalize_i (only me)
  349. * - /normalize_g/normalize_h/normalize_j (only me)
  350. * - /normalize_g/normalize_i/normalize_k (only me)
  351. *
  352. * - Normalize /normalize_g/normalize_h/normalize_j (only me) & /normalize_g/normalize_i/normalize_k (only me)
  353. * - Expect
  354. * - /normalize_g/normalize_h (empty)
  355. * - parent is /normalize_g (public)
  356. * - /normalize_g/normalize_i (empty)
  357. * - parent is /normalize_g (public)
  358. * - /normalize_g/normalize_h/normalize_j (only me) is normalized
  359. * - /normalize_g/normalize_i/normalize_k (only me) is normalized
  360. */
  361. const public = filter => ({ grant: Page.GRANT_PUBLIC, ...filter });
  362. const owned = filter => ({ grant: Page.GRANT_OWNER, grantedUsers: [testUser1._id], ...filter });
  363. const testUser1Group = filter => ({ grantedGroup: testUser1GroupId, ...filter });
  364. const normalized = { parent: { $ne: null } };
  365. const notNormalized = { parent: null };
  366. const empty = { isEmpty: true };
  367. beforeAll(async() => {
  368. // Prepare data
  369. const id1 = new mongoose.Types.ObjectId();
  370. const id2 = new mongoose.Types.ObjectId();
  371. const id3 = new mongoose.Types.ObjectId();
  372. const id4 = new mongoose.Types.ObjectId();
  373. await Page.insertMany([
  374. // 1
  375. {
  376. _id: id3,
  377. path: '/deep_path',
  378. grant: Page.GRANT_PUBLIC,
  379. parent: rootPage._id,
  380. },
  381. {
  382. _id: id1,
  383. path: '/deep_path/normalize_a',
  384. isEmpty: true,
  385. parent: id3,
  386. },
  387. {
  388. path: '/deep_path/normalize_a/normalize_b',
  389. grant: Page.GRANT_PUBLIC,
  390. parent: id1,
  391. },
  392. {
  393. path: '/deep_path/normalize_a',
  394. grant: Page.GRANT_USER_GROUP,
  395. grantedGroup: testUser1GroupId,
  396. parent: null,
  397. },
  398. {
  399. path: '/deep_path/normalize_c',
  400. grant: Page.GRANT_USER_GROUP,
  401. grantedGroup: testUser1GroupId,
  402. parent: null,
  403. },
  404. // 2
  405. {
  406. _id: id2,
  407. path: '/normalize_d',
  408. isEmpty: true,
  409. parent: rootPage._id,
  410. },
  411. {
  412. path: '/normalize_d',
  413. grant: Page.GRANT_USER_GROUP,
  414. grantedGroup: testUser1GroupId,
  415. parent: null,
  416. },
  417. {
  418. path: '/normalize_d/normalize_e',
  419. grant: Page.GRANT_USER_GROUP,
  420. grantedGroup: testUser1GroupId,
  421. parent: id2,
  422. },
  423. {
  424. path: '/normalize_f',
  425. grant: Page.GRANT_USER_GROUP,
  426. grantedGroup: testUser1GroupId,
  427. parent: null,
  428. },
  429. // 3
  430. {
  431. _id: id4,
  432. path: '/normalize_g',
  433. parent: rootPage._id,
  434. },
  435. {
  436. path: '/normalize_g/normalize_h',
  437. grant: Page.GRANT_OWNER,
  438. grantedUsers: [testUser1._id],
  439. parent: null,
  440. },
  441. {
  442. path: '/normalize_g/normalize_i',
  443. grant: Page.GRANT_OWNER,
  444. grantedUsers: [testUser1._id],
  445. parent: null,
  446. },
  447. {
  448. path: '/normalize_g/normalize_h/normalize_j',
  449. grant: Page.GRANT_OWNER,
  450. grantedUsers: [testUser1._id],
  451. parent: null,
  452. },
  453. {
  454. path: '/normalize_g/normalize_i/normalize_k',
  455. grant: Page.GRANT_OWNER,
  456. grantedUsers: [testUser1._id],
  457. parent: null,
  458. },
  459. ]);
  460. });
  461. test('should not run normalization when the target page is GRANT_USER_GROUP surrounded by public pages', async() => {
  462. const mockMainOperation = jest.spyOn(crowi.pageService, 'normalizeParentRecursivelyMainOperation').mockImplementation(v => v);
  463. const _page1 = await Page.findOne(public({ path: '/deep_path/normalize_a', ...empty }));
  464. const _page2 = await Page.findOne(public({ path: '/deep_path/normalize_a/normalize_b', ...normalized }));
  465. const _page3 = await Page.findOne(testUser1Group({ path: '/deep_path/normalize_a', ...notNormalized }));
  466. const _page4 = await Page.findOne(testUser1Group({ path: '/deep_path/normalize_c', ...notNormalized }));
  467. expect(_page1).not.toBeNull();
  468. expect(_page2).not.toBeNull();
  469. expect(_page3).not.toBeNull();
  470. expect(_page4).not.toBeNull();
  471. // Normalize
  472. await normalizeParentRecursivelyByPages([_page3], testUser1);
  473. expect(mockMainOperation).not.toHaveBeenCalled();
  474. mockMainOperation.mockRestore();
  475. });
  476. test('should not include siblings', async() => {
  477. const _page1 = await Page.findOne(public({ path: '/normalize_d', ...empty }));
  478. const _page2 = await Page.findOne(testUser1Group({ path: '/normalize_d/normalize_e', ...normalized }));
  479. const _page3 = await Page.findOne(testUser1Group({ path: '/normalize_d', ...notNormalized }));
  480. const _page4 = await Page.findOne(testUser1Group({ path: '/normalize_f', ...notNormalized }));
  481. expect(_page1).not.toBeNull();
  482. expect(_page2).not.toBeNull();
  483. expect(_page3).not.toBeNull();
  484. expect(_page4).not.toBeNull();
  485. // Normalize
  486. await normalizeParentRecursivelyByPages([_page3], testUser1);
  487. const page1 = await Page.findOne(testUser1Group({ path: '/normalize_d/normalize_e' }));
  488. const page2 = await Page.findOne(testUser1Group({ path: '/normalize_d' }));
  489. const page3 = await Page.findOne(testUser1Group({ path: '/normalize_f' }));
  490. const empty4 = await Page.findOne(public({ path: '/normalize_d', ...empty }));
  491. expect(page1).not.toBeNull();
  492. expect(page2).not.toBeNull();
  493. expect(page3).not.toBeNull();
  494. expect(empty4).toBeNull(); // empty page should be removed
  495. // Check parent
  496. expect(page1.parent).toStrictEqual(page2._id);
  497. expect(page2.parent).toStrictEqual(rootPage._id);
  498. expect(page3.parent).toBeNull(); // should not be normalized
  499. // Check descendantCount
  500. expect(page1.descendantCount).toBe(0);
  501. expect(page2.descendantCount).toBe(1);
  502. expect(page3.descendantCount).toBe(0); // should not be normalized
  503. });
  504. test('should replace all unnecessary empty pages and normalization succeeds', async() => {
  505. const _pageG = await Page.findOne(public({ path: '/normalize_g', ...normalized }));
  506. const _pageGH = await Page.findOne(owned({ path: '/normalize_g/normalize_h', ...notNormalized }));
  507. const _pageGI = await Page.findOne(owned({ path: '/normalize_g/normalize_i', ...notNormalized }));
  508. const _pageGHJ = await Page.findOne(owned({ path: '/normalize_g/normalize_h/normalize_j', ...notNormalized }));
  509. const _pageGIK = await Page.findOne(owned({ path: '/normalize_g/normalize_i/normalize_k', ...notNormalized }));
  510. expect(_pageG).not.toBeNull();
  511. expect(_pageGH).not.toBeNull();
  512. expect(_pageGI).not.toBeNull();
  513. expect(_pageGHJ).not.toBeNull();
  514. expect(_pageGIK).not.toBeNull();
  515. // Normalize
  516. await normalizeParentRecursivelyByPages([_pageGHJ, _pageGIK], testUser1);
  517. const countG = await Page.count({ path: '/normalize_g' });
  518. const countGH = await Page.count({ path: '/normalize_g/normalize_h' });
  519. const countGI = await Page.count({ path: '/normalize_g/normalize_i' });
  520. const countGHJ = await Page.count({ path: '/normalize_g/normalize_h/normalize_j' });
  521. const countGIK = await Page.count({ path: '/normalize_g/normalize_i/normalize_k' });
  522. expect(countG).toBe(1);
  523. expect(countGH).toBe(2);
  524. expect(countGI).toBe(2);
  525. expect(countGHJ).toBe(1);
  526. expect(countGIK).toBe(1);
  527. // -- normalized pages
  528. const pageG = await Page.findOne(public({ path: '/normalize_g' }));
  529. const emptyGH = await Page.findOne({ path: '/normalize_g/normalize_h', ...empty });
  530. const emptyGI = await Page.findOne({ path: '/normalize_g/normalize_i', ...empty });
  531. const pageGHJ = await Page.findOne({ path: '/normalize_g/normalize_h/normalize_j' });
  532. const pageGIK = await Page.findOne({ path: '/normalize_g/normalize_i/normalize_k' });
  533. // Check existence
  534. expect(pageG).not.toBeNull();
  535. expect(pageGHJ).not.toBeNull();
  536. expect(pageGIK).not.toBeNull();
  537. expect(emptyGH).not.toBeNull();
  538. expect(emptyGI).not.toBeNull();
  539. // Check parent
  540. expect(pageG.parent).toStrictEqual(rootPage._id);
  541. expect(emptyGH.parent).toStrictEqual(pageG._id);
  542. expect(emptyGI.parent).toStrictEqual(pageG._id);
  543. expect(pageGHJ.parent).toStrictEqual(emptyGH._id);
  544. expect(pageGIK.parent).toStrictEqual(emptyGI._id);
  545. // Check descendantCount
  546. expect(pageG.descendantCount).toStrictEqual(2);
  547. expect(emptyGH.descendantCount).toStrictEqual(1);
  548. expect(emptyGI.descendantCount).toStrictEqual(1);
  549. expect(pageGHJ.descendantCount).toStrictEqual(0);
  550. expect(pageGIK.descendantCount).toStrictEqual(0);
  551. // -- not normalized pages
  552. const pageGH = await Page.findOne(owned({ path: '/normalize_g/normalize_h' }));
  553. const pageGI = await Page.findOne(owned({ path: '/normalize_g/normalize_i' }));
  554. // Check existence
  555. expect(pageGH).not.toBeNull();
  556. expect(pageGI).not.toBeNull();
  557. // Check parent
  558. expect(pageGH.parent).toBeNull(); // should not be normalized
  559. expect(pageGI.parent).toBeNull(); // should not be normalized
  560. // Check descendantCount
  561. expect(pageGH.descendantCount).toStrictEqual(0); // should not be normalized
  562. expect(pageGI.descendantCount).toStrictEqual(0); // should not be normalized
  563. });
  564. });
  565. describe('should normalize only selected pages recursively (especially should NOT normalize non-selected ancestors)', () => {
  566. /*
  567. * # Test flow
  568. * - Existing pages
  569. * - All pages are NOT normalized
  570. * - A, B, C, and D are owned by "testUser1"
  571. * A. /normalize_A_owned
  572. * B. /normalize_A_owned/normalize_B_owned
  573. * C. /normalize_A_owned/normalize_B_owned/normalize_C_owned
  574. * D. /normalize_A_owned/normalize_B_owned/normalize_C_owned/normalize_D_owned
  575. * E. /normalize_A_owned/normalize_B_owned/normalize_C_owned/normalize_D_root
  576. * - Owned by "rootUser"
  577. * F. /normalize_A_owned/normalize_B_owned/normalize_C_owned/normalize_D_group
  578. * - Owned by the userGroup "groupIdIsolate"
  579. *
  580. * 1. Normalize A and B one by one.
  581. * - Expect
  582. * - A and B are normalized
  583. * - C and D are NOT normalized
  584. * - E and F are NOT normalized
  585. * 2. Recursively normalize D.
  586. * - Expect
  587. * - A, B, and D are normalized
  588. * - C is NOT normalized
  589. * - C is substituted by an empty page whose path is "/normalize_A_owned/normalize_B_owned/normalize_C_owned"
  590. * - E and F are NOT normalized
  591. * 3. Recursively normalize C.
  592. * - Expect
  593. * - A, B, C, and D are normalized
  594. * - An empty page at "/normalize_A_owned/normalize_B_owned/normalize_C_owned" does NOT exist (removed)
  595. * - E and F are NOT normalized
  596. */
  597. const owned = filter => ({ grantedUsers: [testUser1._id], ...filter });
  598. const root = filter => ({ grantedUsers: [rootUser._id], ...filter });
  599. const rootUserGroup = filter => ({ grantedGroup: rootUserGroupId, ...filter });
  600. const testUser1Group = filter => ({ grantedGroup: testUser1GroupId, ...filter });
  601. const normalized = { parent: { $ne: null } };
  602. const notNormalized = { parent: null };
  603. const empty = { isEmpty: true };
  604. beforeAll(async() => {
  605. // Prepare data
  606. const id17 = new mongoose.Types.ObjectId();
  607. const id21 = new mongoose.Types.ObjectId();
  608. const id22 = new mongoose.Types.ObjectId();
  609. const id23 = new mongoose.Types.ObjectId();
  610. await Page.insertMany([
  611. // 1
  612. {
  613. path: '/normalize_13_owned',
  614. grant: Page.GRANT_OWNER,
  615. grantedUsers: [testUser1._id],
  616. },
  617. {
  618. path: '/normalize_13_owned/normalize_14_owned',
  619. grant: Page.GRANT_OWNER,
  620. grantedUsers: [testUser1._id],
  621. },
  622. {
  623. path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned',
  624. grant: Page.GRANT_OWNER,
  625. grantedUsers: [testUser1._id],
  626. },
  627. {
  628. path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_owned',
  629. grant: Page.GRANT_OWNER,
  630. grantedUsers: [testUser1._id],
  631. },
  632. {
  633. path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_root',
  634. grant: Page.GRANT_OWNER,
  635. grantedUsers: [rootUser._id],
  636. },
  637. {
  638. path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_group',
  639. grant: Page.GRANT_USER_GROUP,
  640. grantedGroup: testUser1GroupId,
  641. },
  642. // 2
  643. {
  644. _id: id17,
  645. path: '/normalize_17_owned',
  646. grant: Page.GRANT_OWNER,
  647. grantedUsers: [testUser1._id],
  648. parent: rootPage._id,
  649. },
  650. {
  651. path: '/normalize_17_owned/normalize_18_owned',
  652. grant: Page.GRANT_OWNER,
  653. grantedUsers: [testUser1._id],
  654. parent: id17,
  655. },
  656. {
  657. path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned',
  658. grant: Page.GRANT_OWNER,
  659. grantedUsers: [testUser1._id],
  660. },
  661. {
  662. path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_owned',
  663. grant: Page.GRANT_OWNER,
  664. grantedUsers: [testUser1._id],
  665. },
  666. {
  667. path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_root',
  668. grant: Page.GRANT_OWNER,
  669. grantedUsers: [rootUser._id],
  670. },
  671. {
  672. path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_group',
  673. grant: Page.GRANT_USER_GROUP,
  674. grantedGroup: rootUserGroupId,
  675. },
  676. // 3
  677. {
  678. _id: id21,
  679. path: '/normalize_21_owned',
  680. grant: Page.GRANT_OWNER,
  681. grantedUsers: [testUser1._id],
  682. parent: rootPage._id,
  683. },
  684. {
  685. _id: id22,
  686. path: '/normalize_21_owned/normalize_22_owned',
  687. grant: Page.GRANT_OWNER,
  688. grantedUsers: [testUser1._id],
  689. parent: id21,
  690. },
  691. {
  692. path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned',
  693. grant: Page.GRANT_OWNER,
  694. grantedUsers: [testUser1._id],
  695. parent: null,
  696. },
  697. {
  698. _id: id23,
  699. path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned',
  700. isEmpty: true,
  701. parent: id22,
  702. },
  703. {
  704. path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_owned',
  705. grant: Page.GRANT_OWNER,
  706. grantedUsers: [testUser1._id],
  707. parent: id23,
  708. },
  709. {
  710. path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_root',
  711. grant: Page.GRANT_OWNER,
  712. grantedUsers: [rootUser._id],
  713. },
  714. {
  715. path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_rootGroup',
  716. grant: Page.GRANT_USER_GROUP,
  717. grantedGroup: rootUserGroupId,
  718. },
  719. ]);
  720. });
  721. test('Should normalize a single page without including other pages', async() => {
  722. const _owned13 = await Page.findOne(owned({ path: '/normalize_13_owned', ...notNormalized }));
  723. const _owned14 = await Page.findOne(owned({ path: '/normalize_13_owned/normalize_14_owned', ...notNormalized }));
  724. const _owned15 = await Page.findOne(owned({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned', ...notNormalized }));
  725. const _owned16 = await Page.findOne(owned({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_owned', ...notNormalized }));
  726. const _root16 = await Page.findOne(root({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_root', ...notNormalized }));
  727. const _group16 = await Page.findOne(testUser1Group({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_group', ...notNormalized }));
  728. expect(_owned13).not.toBeNull();
  729. expect(_owned14).not.toBeNull();
  730. expect(_owned15).not.toBeNull();
  731. expect(_owned16).not.toBeNull();
  732. expect(_root16).not.toBeNull();
  733. expect(_group16).not.toBeNull();
  734. // Normalize
  735. await normalizeParentByPage(_owned14, testUser1);
  736. const owned13 = await Page.findOne({ path: '/normalize_13_owned' });
  737. const empty13 = await Page.findOne({ path: '/normalize_13_owned', ...empty });
  738. const owned14 = await Page.findOne({ path: '/normalize_13_owned/normalize_14_owned' });
  739. const owned15 = await Page.findOne({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned' });
  740. const owned16 = await Page.findOne({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_owned' });
  741. const root16 = await Page.findOne(root({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_root' }));
  742. const group16 = await Page.findOne(testUser1Group({ path: '/normalize_13_owned/normalize_14_owned/normalize_15_owned/normalize_16_group' }));
  743. expect(owned13).not.toBeNull();
  744. expect(empty13).not.toBeNull();
  745. expect(owned14).not.toBeNull();
  746. expect(owned15).not.toBeNull();
  747. expect(owned16).not.toBeNull();
  748. expect(root16).not.toBeNull();
  749. expect(group16).not.toBeNull();
  750. // Check parent
  751. expect(owned13.parent).toBeNull();
  752. expect(empty13.parent).toStrictEqual(rootPage._id);
  753. expect(owned14.parent).toStrictEqual(empty13._id);
  754. expect(owned15.parent).toBeNull();
  755. expect(owned16.parent).toBeNull();
  756. expect(root16.parent).toBeNull();
  757. expect(group16.parent).toBeNull();
  758. // Check descendantCount
  759. expect(owned13.descendantCount).toBe(0);
  760. expect(empty13.descendantCount).toBe(1);
  761. expect(owned14.descendantCount).toBe(0);
  762. });
  763. test('Should normalize pages recursively excluding the pages not selected', async() => {
  764. const _owned17 = await Page.findOne(owned({ path: '/normalize_17_owned', ...normalized }));
  765. const _owned18 = await Page.findOne(owned({ path: '/normalize_17_owned/normalize_18_owned', ...normalized }));
  766. const _owned19 = await Page.findOne(owned({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned', ...notNormalized }));
  767. const _owned20 = await Page.findOne(owned({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_owned', ...notNormalized }));
  768. const _root20 = await Page.findOne(root({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_root', ...notNormalized }));
  769. const _group20 = await Page.findOne(rootUserGroup({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_group', ...notNormalized }));
  770. expect(_owned17).not.toBeNull();
  771. expect(_owned18).not.toBeNull();
  772. expect(_owned19).not.toBeNull();
  773. expect(_owned20).not.toBeNull();
  774. expect(_root20).not.toBeNull();
  775. expect(_group20).not.toBeNull();
  776. // Normalize
  777. await normalizeParentRecursivelyByPages([_owned20], testUser1);
  778. const owned17 = await Page.findOne({ path: '/normalize_17_owned' });
  779. const owned18 = await Page.findOne({ path: '/normalize_17_owned/normalize_18_owned' });
  780. const owned19 = await Page.findOne({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned' });
  781. const empty19 = await Page.findOne({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned', ...empty });
  782. const owned20 = await Page.findOne({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_owned' });
  783. const root20 = await Page.findOne(root({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_root' }));
  784. const group20 = await Page.findOne(rootUserGroup({ path: '/normalize_17_owned/normalize_18_owned/normalize_19_owned/normalize_20_group' }));
  785. expect(owned17).not.toBeNull();
  786. expect(owned18).not.toBeNull();
  787. expect(owned19).not.toBeNull();
  788. expect(empty19).not.toBeNull();
  789. expect(owned20).not.toBeNull();
  790. expect(root20).not.toBeNull();
  791. expect(group20).not.toBeNull();
  792. // Check parent
  793. expect(owned17.parent).toStrictEqual(rootPage._id);
  794. expect(owned18.parent).toStrictEqual(owned17._id);
  795. expect(owned19.parent).toBeNull();
  796. expect(empty19.parent).toStrictEqual(owned18._id);
  797. expect(owned20.parent).toStrictEqual(empty19._id);
  798. expect(root20.parent).toBeNull();
  799. expect(group20.parent).toBeNull();
  800. // Check isEmpty
  801. expect(owned17.isEmpty).toBe(false);
  802. expect(owned18.isEmpty).toBe(false);
  803. });
  804. test('Should normalize pages recursively excluding the pages of not user\'s & Should delete unnecessary empty pages', async() => {
  805. const _owned21 = await Page.findOne(owned({ path: '/normalize_21_owned', ...normalized }));
  806. const _owned22 = await Page.findOne(owned({ path: '/normalize_21_owned/normalize_22_owned', ...normalized }));
  807. const _owned23 = await Page.findOne(owned({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned', ...notNormalized }));
  808. const _empty23 = await Page.findOne({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned', ...normalized, ...empty });
  809. const _owned24 = await Page.findOne(owned({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_owned', ...normalized }));
  810. const _root24 = await Page.findOne(root({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_root', ...notNormalized }));
  811. const _rootGroup24 = await Page.findOne(rootUserGroup({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_rootGroup', ...notNormalized }));
  812. expect(_owned21).not.toBeNull();
  813. expect(_owned22).not.toBeNull();
  814. expect(_owned23).not.toBeNull();
  815. expect(_empty23).not.toBeNull();
  816. expect(_owned24).not.toBeNull();
  817. expect(_root24).not.toBeNull();
  818. expect(_rootGroup24).not.toBeNull();
  819. // Normalize
  820. await normalizeParentRecursivelyByPages([_owned23], testUser1);
  821. const owned21 = await Page.findOne({ path: '/normalize_21_owned' });
  822. const owned22 = await Page.findOne({ path: '/normalize_21_owned/normalize_22_owned' });
  823. const owned23 = await Page.findOne({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned' });
  824. const empty23 = await Page.findOne({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned', ...empty });
  825. const owned24 = await Page.findOne({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_owned' });
  826. const root24 = await Page.findOne(root({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_root' }));
  827. const rootGroup24 = await Page.findOne(rootUserGroup({ path: '/normalize_21_owned/normalize_22_owned/normalize_23_owned/normalize_24_rootGroup' }));
  828. expect(owned21).not.toBeNull();
  829. expect(owned22).not.toBeNull();
  830. expect(owned23).not.toBeNull();
  831. expect(empty23).toBeNull(); // removed
  832. expect(owned24).not.toBeNull();
  833. expect(root24).not.toBeNull();
  834. expect(rootGroup24).not.toBeNull();
  835. // Check parent
  836. expect(owned21.parent).toStrictEqual(rootPage._id);
  837. expect(owned22.parent).toStrictEqual(owned21._id);
  838. expect(owned23.parent).toStrictEqual(owned22._id);
  839. expect(owned24.parent).toStrictEqual(owned23._id); // not empty23._id
  840. expect(root24.parent).toBeNull();
  841. expect(rootGroup24.parent).toBeNull(); // excluded from the pages to be normalized
  842. // Check isEmpty
  843. expect(owned21.isEmpty).toBe(false);
  844. expect(owned22.isEmpty).toBe(false);
  845. expect(owned23.isEmpty).toBe(false);
  846. });
  847. });
  848. describe('normalizeAllPublicPages()', () => {
  849. jest.setTimeout(60000);
  850. let createPagePaths;
  851. let allPossiblePagePaths;
  852. beforeAll(async() => {
  853. createPagePaths = [
  854. '/publicA', '/publicA/privateB', '/publicA/privateB/publicC', '/parenthesis/(a)[b]{c}d', '/parenthesis/(a)[b]{c}d/public', '/migratedD',
  855. ];
  856. allPossiblePagePaths = [...createPagePaths, '/parenthesis', '/'];
  857. // initialize pages for test
  858. await Page.insertMany([
  859. {
  860. path: '/publicA',
  861. grant: Page.GRANT_PUBLIC,
  862. creator: testUser1,
  863. lastUpdateUser: testUser1,
  864. },
  865. {
  866. path: '/publicA/privateB',
  867. grant: Page.GRANT_OWNER,
  868. creator: testUser1,
  869. lastUpdateUser: testUser1,
  870. grantedUsers: [testUser1._id],
  871. },
  872. {
  873. path: '/publicA/privateB/publicC',
  874. grant: Page.GRANT_PUBLIC,
  875. creator: testUser1,
  876. lastUpdateUser: testUser1,
  877. },
  878. {
  879. path: '/parenthesis/(a)[b]{c}d',
  880. grant: Page.GRANT_PUBLIC,
  881. creator: testUser1,
  882. lastUpdateUser: testUser1,
  883. },
  884. {
  885. path: '/parenthesis/(a)[b]{c}d/public',
  886. grant: Page.GRANT_PUBLIC,
  887. creator: testUser1,
  888. lastUpdateUser: testUser1,
  889. },
  890. ]);
  891. const parent = await Page.find({ path: '/' });
  892. await Page.insertMany([
  893. {
  894. path: '/migratedD',
  895. grant: Page.GRANT_PUBLIC,
  896. creator: testUser1,
  897. lastUpdateUser: testUser1,
  898. parent: parent._id,
  899. },
  900. ]);
  901. // migrate
  902. await crowi.pageService.normalizeAllPublicPages(Page.GRANT_PUBLIC);
  903. jest.setTimeout(30000);
  904. });
  905. test('should migrate all public pages', async() => {
  906. const migratedPages = await Page.find({
  907. path: {
  908. $in: allPossiblePagePaths,
  909. },
  910. parent: { $ne: null },
  911. });
  912. const migratedEmptyPages = await Page.find({
  913. path: {
  914. $in: allPossiblePagePaths,
  915. },
  916. isEmpty: true,
  917. parent: { $ne: null },
  918. });
  919. const nonMigratedPages = await Page.find({
  920. path: {
  921. $in: allPossiblePagePaths,
  922. },
  923. parent: null,
  924. });
  925. const migratedPaths = migratedPages.map(page => page.path).sort();
  926. const migratedEmptyPaths = migratedEmptyPages.map(page => page.path).sort();
  927. const nonMigratedPaths = nonMigratedPages.map(page => page.path).sort();
  928. const expectedMigratedPaths = allPossiblePagePaths.filter(path => path !== '/').sort();
  929. const expectedMigratedEmptyPaths = ['/publicA/privateB', '/parenthesis'].sort();
  930. const expectedNonMigratedPaths = ['/publicA/privateB', '/'].sort();
  931. expect(migratedPaths).toStrictEqual(expectedMigratedPaths);
  932. expect(migratedEmptyPaths).toStrictEqual(expectedMigratedEmptyPaths);
  933. expect(nonMigratedPaths).toStrictEqual(expectedNonMigratedPaths);
  934. });
  935. });
  936. describe('normalizeParentByPage()', () => {
  937. test('it should normalize not v5 page with usergroup that has parent group', async() => {
  938. const page1 = await Page.findOne({ _id: pageId1, path: '/normalize_1', isEmpty: true });
  939. const page2 = await Page.findOne({ _id: pageId2, path: '/normalize_1/normalize_2', parent: page1._id });
  940. const page3 = await Page.findOne({ _id: pageId3, path: '/normalize_1' }); // NOT v5
  941. expect(page1).toBeTruthy();
  942. expect(page2).toBeTruthy();
  943. expect(page3).toBeTruthy();
  944. await normalizeParentByPage(page3, testUser1);
  945. // AM => After Migration
  946. const page1AM = await Page.findOne({ _id: pageId1, path: '/normalize_1', isEmpty: true });
  947. const page2AM = await Page.findOne({ _id: pageId2, path: '/normalize_1/normalize_2' });
  948. const page3AM = await Page.findOne({ _id: pageId3, path: '/normalize_1' }); // v5 compatible
  949. expect(page2AM).toBeTruthy();
  950. expect(page3AM).toBeTruthy();
  951. expect(page1AM).toBeNull();
  952. expect(page2AM.parent).toStrictEqual(page3AM._id);
  953. expect(page3AM.parent).toStrictEqual(rootPage._id);
  954. });
  955. test('should throw error if a page with isolated group becomes the parent of other page with different gourp after normalizing', async() => {
  956. const page4 = await Page.findOne({ _id: pageId4, path: '/normalize_4', isEmpty: true });
  957. const page5 = await Page.findOne({ _id: pageId5, path: '/normalize_4/normalize_5', parent: page4._id });
  958. const page6 = await Page.findOne({ _id: pageId6, path: '/normalize_4' }); // NOT v5
  959. expect(page4).toBeTruthy();
  960. expect(page5).toBeTruthy();
  961. expect(page6).toBeTruthy();
  962. let isThrown;
  963. try {
  964. await normalizeParentByPage(page6, testUser1);
  965. }
  966. catch (err) {
  967. isThrown = true;
  968. }
  969. // AM => After Migration
  970. const page4AM = await Page.findOne({ _id: pageId4, path: '/normalize_4', isEmpty: true });
  971. const page5AM = await Page.findOne({ _id: pageId5, path: '/normalize_4/normalize_5', parent: page4._id });
  972. const page6AM = await Page.findOne({ _id: pageId6, path: '/normalize_4' }); // NOT v5
  973. expect(isThrown).toBe(true);
  974. expect(page4AM).toBeTruthy();
  975. expect(page5AM).toBeTruthy();
  976. expect(page6AM).toBeTruthy();
  977. expect(page4AM).toStrictEqual(page4);
  978. expect(page5AM).toStrictEqual(page5);
  979. expect(page6AM).toStrictEqual(page6);
  980. });
  981. });
  982. test('replace private parents with empty pages', async() => {
  983. const replacedPathPages = await Page.find({ path: '/publicA/privateB' }); // ex-private page
  984. const _newEmptyPage = replacedPathPages.filter(page => page.parent != null)[0];
  985. const newEmptyPage = {
  986. path: _newEmptyPage.path,
  987. grant: _newEmptyPage.grant,
  988. isEmpty: _newEmptyPage.isEmpty,
  989. };
  990. const expectedNewEmptyPage = {
  991. path: '/publicA/privateB',
  992. grant: Page.GRANT_PUBLIC,
  993. isEmpty: true,
  994. };
  995. const _privatePage = replacedPathPages.filter(page => page.parent == null)[0];
  996. const privatePage = {
  997. path: _privatePage.path,
  998. grant: _privatePage.grant,
  999. isEmpty: _privatePage.isEmpty,
  1000. };
  1001. const expectedPrivatePage = {
  1002. path: '/publicA/privateB',
  1003. grant: Page.GRANT_OWNER,
  1004. isEmpty: false,
  1005. };
  1006. expect(replacedPathPages.length).toBe(2);
  1007. expect(newEmptyPage).toStrictEqual(expectedNewEmptyPage);
  1008. expect(privatePage).toStrictEqual(expectedPrivatePage);
  1009. });
  1010. });