page.test.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. const mongoose = require('mongoose');
  2. const { getInstance } = require('../setup-crowi');
  3. let testUser0;
  4. let testUser1;
  5. let testUser2;
  6. let testGroup0;
  7. let parentPage;
  8. describe('Page', () => {
  9. // biome-ignore lint/correctness/noUnusedVariables: ignore
  10. let crowi;
  11. let Page;
  12. let PageQueryBuilder;
  13. let User;
  14. let UserGroup;
  15. let UserGroupRelation;
  16. beforeAll(async () => {
  17. crowi = await getInstance();
  18. User = mongoose.model('User');
  19. UserGroup = mongoose.model('UserGroup');
  20. UserGroupRelation = mongoose.model('UserGroupRelation');
  21. Page = mongoose.model('Page');
  22. PageQueryBuilder = Page.PageQueryBuilder;
  23. await User.insertMany([
  24. {
  25. name: 'Anon 0',
  26. username: 'anonymous0',
  27. email: 'anonymous0@example.com',
  28. },
  29. {
  30. name: 'Anon 1',
  31. username: 'anonymous1',
  32. email: 'anonymous1@example.com',
  33. },
  34. {
  35. name: 'Anon 2',
  36. username: 'anonymous2',
  37. email: 'anonymous2@example.com',
  38. },
  39. ]);
  40. await UserGroup.insertMany([
  41. { name: 'TestGroup0' },
  42. { name: 'TestGroup1' },
  43. ]);
  44. testUser0 = await User.findOne({ username: 'anonymous0' });
  45. testUser1 = await User.findOne({ username: 'anonymous1' });
  46. testUser2 = await User.findOne({ username: 'anonymous2' });
  47. testGroup0 = await UserGroup.findOne({ name: 'TestGroup0' });
  48. await UserGroupRelation.insertMany([
  49. {
  50. relatedGroup: testGroup0,
  51. relatedUser: testUser0,
  52. },
  53. {
  54. relatedGroup: testGroup0,
  55. relatedUser: testUser1,
  56. },
  57. ]);
  58. await Page.insertMany([
  59. {
  60. path: '/user/anonymous0/memo',
  61. grant: Page.GRANT_RESTRICTED,
  62. grantedUsers: [testUser0],
  63. creator: testUser0,
  64. },
  65. {
  66. path: '/grant',
  67. grant: Page.GRANT_PUBLIC,
  68. grantedUsers: [testUser0],
  69. creator: testUser0,
  70. },
  71. {
  72. path: '/grant/public',
  73. grant: Page.GRANT_PUBLIC,
  74. grantedUsers: [testUser0],
  75. creator: testUser0,
  76. },
  77. {
  78. path: '/grant/restricted',
  79. grant: Page.GRANT_RESTRICTED,
  80. grantedUsers: [testUser0],
  81. creator: testUser0,
  82. },
  83. {
  84. path: '/grant/specified',
  85. grant: Page.GRANT_SPECIFIED,
  86. grantedUsers: [testUser0],
  87. creator: testUser0,
  88. },
  89. {
  90. path: '/grant/owner',
  91. grant: Page.GRANT_OWNER,
  92. grantedUsers: [testUser0],
  93. creator: testUser0,
  94. },
  95. {
  96. path: '/page/child/without/parents',
  97. grant: Page.GRANT_PUBLIC,
  98. creator: testUser0,
  99. },
  100. {
  101. path: '/grant/groupacl',
  102. grant: Page.GRANT_USER_GROUP,
  103. grantedUsers: [],
  104. grantedGroups: [{ item: testGroup0, type: 'UserGroup' }],
  105. creator: testUser1,
  106. },
  107. {
  108. path: '/page1',
  109. grant: Page.GRANT_PUBLIC,
  110. creator: testUser0,
  111. },
  112. {
  113. path: '/page1/child1',
  114. grant: Page.GRANT_PUBLIC,
  115. creator: testUser0,
  116. },
  117. {
  118. path: '/page2',
  119. grant: Page.GRANT_PUBLIC,
  120. creator: testUser0,
  121. },
  122. ]);
  123. parentPage = await Page.findOne({ path: '/grant' });
  124. });
  125. describe('.isPublic', () => {
  126. describe('with a public page', () => {
  127. test('should return true', async () => {
  128. const page = await Page.findOne({ path: '/grant/public' });
  129. expect(page.isPublic()).toEqual(true);
  130. });
  131. });
  132. ['restricted', 'specified', 'owner'].forEach((grant) => {
  133. describe(`with a ${grant} page`, () => {
  134. test('should return false', async () => {
  135. const page = await Page.findOne({ path: `/grant/${grant}` });
  136. expect(page.isPublic()).toEqual(false);
  137. });
  138. });
  139. });
  140. });
  141. describe('.getDeletedPageName', () => {
  142. test('should return trash page name', () => {
  143. expect(Page.getDeletedPageName('/hoge')).toEqual('/trash/hoge');
  144. expect(Page.getDeletedPageName('hoge')).toEqual('/trash/hoge');
  145. });
  146. });
  147. describe('.getRevertDeletedPageName', () => {
  148. test('should return reverted trash page name', () => {
  149. expect(Page.getRevertDeletedPageName('/hoge')).toEqual('/hoge');
  150. expect(Page.getRevertDeletedPageName('/trash/hoge')).toEqual('/hoge');
  151. expect(Page.getRevertDeletedPageName('/trash/hoge/trash')).toEqual(
  152. '/hoge/trash',
  153. );
  154. });
  155. });
  156. describe('.isAccessiblePageByViewer', () => {
  157. describe('with a granted page', () => {
  158. test('should return true with granted user', async () => {
  159. const user = await User.findOne({ email: 'anonymous0@example.com' });
  160. const page = await Page.findOne({ path: '/user/anonymous0/memo' });
  161. const bool = await Page.isAccessiblePageByViewer(page.id, user);
  162. expect(bool).toEqual(true);
  163. });
  164. test('should return false without user', async () => {
  165. const user = null;
  166. const page = await Page.findOne({ path: '/user/anonymous0/memo' });
  167. const bool = await Page.isAccessiblePageByViewer(page.id, user);
  168. expect(bool).toEqual(true);
  169. });
  170. });
  171. describe('with a public page', () => {
  172. test('should return true with user', async () => {
  173. const user = await User.findOne({ email: 'anonymous1@example.com' });
  174. const page = await Page.findOne({ path: '/grant/public' });
  175. const bool = await Page.isAccessiblePageByViewer(page.id, user);
  176. expect(bool).toEqual(true);
  177. });
  178. test('should return true with out', async () => {
  179. const user = null;
  180. const page = await Page.findOne({ path: '/grant/public' });
  181. const bool = await Page.isAccessiblePageByViewer(page.id, user);
  182. expect(bool).toEqual(true);
  183. });
  184. });
  185. describe('with a restricted page', () => {
  186. test('should return false with user who has no grant', async () => {
  187. const user = await User.findOne({ email: 'anonymous1@example.com' });
  188. const page = await Page.findOne({ path: '/grant/owner' });
  189. const bool = await Page.isAccessiblePageByViewer(page.id, user);
  190. expect(bool).toEqual(false);
  191. });
  192. test('should return false without user', async () => {
  193. const user = null;
  194. const page = await Page.findOne({ path: '/grant/owner' });
  195. const bool = await Page.isAccessiblePageByViewer(page.id, user);
  196. expect(bool).toEqual(false);
  197. });
  198. });
  199. });
  200. describe('.findPage', () => {
  201. describe('findByIdAndViewer', () => {
  202. test('should find page (public)', async () => {
  203. const expectedPage = await Page.findOne({ path: '/grant/public' });
  204. const page = await Page.findByIdAndViewer(expectedPage.id, testUser0);
  205. expect(page).not.toBeNull();
  206. expect(page.path).toEqual(expectedPage.path);
  207. });
  208. test('should find page (anyone knows link)', async () => {
  209. const expectedPage = await Page.findOne({ path: '/grant/restricted' });
  210. const page = await Page.findByIdAndViewer(expectedPage.id, testUser1);
  211. expect(page).not.toBeNull();
  212. expect(page.path).toEqual(expectedPage.path);
  213. });
  214. test('should find page (only me)', async () => {
  215. const expectedPage = await Page.findOne({ path: '/grant/owner' });
  216. const page = await Page.findByIdAndViewer(expectedPage.id, testUser0);
  217. expect(page).not.toBeNull();
  218. expect(page.path).toEqual(expectedPage.path);
  219. });
  220. test('should not be found by grant (only me)', async () => {
  221. const expectedPage = await Page.findOne({ path: '/grant/owner' });
  222. const page = await Page.findByIdAndViewer(expectedPage.id, testUser1);
  223. expect(page).toBeNull();
  224. });
  225. });
  226. describe('findByIdAndViewer granted userGroup', () => {
  227. test('should find page', async () => {
  228. const expectedPage = await Page.findOne({ path: '/grant/groupacl' });
  229. const page = await Page.findByIdAndViewer(expectedPage.id, testUser0);
  230. expect(page).not.toBeNull();
  231. expect(page.path).toEqual(expectedPage.path);
  232. });
  233. test('should not be found by grant', async () => {
  234. const expectedPage = await Page.findOne({ path: '/grant/groupacl' });
  235. const page = await Page.findByIdAndViewer(expectedPage.id, testUser2);
  236. expect(page).toBeNull();
  237. });
  238. });
  239. });
  240. describe('PageQueryBuilder.addConditionToListWithDescendants', () => {
  241. test('can retrieve descendants of /page', async () => {
  242. const builder = new PageQueryBuilder(Page.find());
  243. builder.addConditionToListWithDescendants('/page');
  244. const result = await builder.query.exec();
  245. // assert totalCount
  246. expect(result.length).toEqual(1);
  247. // assert paths
  248. const pagePaths = result.map((page) => {
  249. return page.path;
  250. });
  251. expect(pagePaths).toContainEqual('/page/child/without/parents');
  252. });
  253. test('can retrieve descendants of /page1', async () => {
  254. const builder = new PageQueryBuilder(Page.find());
  255. builder.addConditionToListWithDescendants('/page1/');
  256. const result = await builder.query.exec();
  257. // assert totalCount
  258. expect(result.length).toEqual(2);
  259. // assert paths
  260. const pagePaths = result.map((page) => {
  261. return page.path;
  262. });
  263. expect(pagePaths).toContainEqual('/page1');
  264. expect(pagePaths).toContainEqual('/page1/child1');
  265. });
  266. });
  267. describe('PageQueryBuilder.addConditionToListOnlyDescendants', () => {
  268. test('can retrieve only descendants of /page', async () => {
  269. const builder = new PageQueryBuilder(Page.find());
  270. builder.addConditionToListOnlyDescendants('/page');
  271. const result = await builder.query.exec();
  272. // assert totalCount
  273. expect(result.length).toEqual(1);
  274. // assert paths
  275. const pagePaths = result.map((page) => {
  276. return page.path;
  277. });
  278. expect(pagePaths).toContainEqual('/page/child/without/parents');
  279. });
  280. test('can retrieve only descendants of /page1', async () => {
  281. const builder = new PageQueryBuilder(Page.find());
  282. builder.addConditionToListOnlyDescendants('/page1');
  283. const result = await builder.query.exec();
  284. // assert totalCount
  285. expect(result.length).toEqual(1);
  286. // assert paths
  287. const pagePaths = result.map((page) => {
  288. return page.path;
  289. });
  290. expect(pagePaths).toContainEqual('/page1/child1');
  291. });
  292. });
  293. describe('PageQueryBuilder.addConditionToListByStartWith', () => {
  294. test('can retrieve pages which starts with /page', async () => {
  295. const builder = new PageQueryBuilder(Page.find());
  296. builder.addConditionToListByStartWith('/page');
  297. const result = await builder.query.exec();
  298. // assert totalCount
  299. expect(result.length).toEqual(4);
  300. // assert paths
  301. const pagePaths = result.map((page) => {
  302. return page.path;
  303. });
  304. expect(pagePaths).toContainEqual('/page/child/without/parents');
  305. expect(pagePaths).toContainEqual('/page1');
  306. expect(pagePaths).toContainEqual('/page1/child1');
  307. expect(pagePaths).toContainEqual('/page2');
  308. });
  309. });
  310. describe('.findListWithDescendants', () => {
  311. test('can retrieve all pages with testUser0', async () => {
  312. const result = await Page.findListWithDescendants('/grant', testUser0);
  313. const { pages } = result;
  314. // assert totalCount
  315. expect(pages.length).toEqual(5);
  316. // assert paths
  317. const pagePaths = await pages.map((page) => {
  318. return page.path;
  319. });
  320. expect(pagePaths).toContainEqual('/grant/groupacl');
  321. expect(pagePaths).toContainEqual('/grant/specified');
  322. expect(pagePaths).toContainEqual('/grant/owner');
  323. expect(pagePaths).toContainEqual('/grant/public');
  324. expect(pagePaths).toContainEqual('/grant');
  325. });
  326. test('can retrieve all pages with testUser1', async () => {
  327. const result = await Page.findListWithDescendants('/grant', testUser1);
  328. const { pages } = result;
  329. // assert totalCount
  330. expect(pages.length).toEqual(5);
  331. // assert paths
  332. const pagePaths = await pages.map((page) => {
  333. return page.path;
  334. });
  335. expect(pagePaths).toContainEqual('/grant/groupacl');
  336. expect(pagePaths).toContainEqual('/grant/specified');
  337. expect(pagePaths).toContainEqual('/grant/owner');
  338. expect(pagePaths).toContainEqual('/grant/public');
  339. expect(pagePaths).toContainEqual('/grant');
  340. });
  341. test('can retrieve all pages with testUser2', async () => {
  342. const result = await Page.findListWithDescendants('/grant', testUser2);
  343. const { pages } = result;
  344. // assert totalCount
  345. expect(pages.length).toEqual(5);
  346. // assert paths
  347. const pagePaths = await pages.map((page) => {
  348. return page.path;
  349. });
  350. expect(pagePaths).toContainEqual('/grant/groupacl');
  351. expect(pagePaths).toContainEqual('/grant/specified');
  352. expect(pagePaths).toContainEqual('/grant/owner');
  353. expect(pagePaths).toContainEqual('/grant/public');
  354. expect(pagePaths).toContainEqual('/grant');
  355. });
  356. test('can retrieve all pages without user', async () => {
  357. const result = await Page.findListWithDescendants('/grant', null);
  358. const { pages } = result;
  359. // assert totalCount
  360. expect(pages.length).toEqual(5);
  361. // assert paths
  362. const pagePaths = await pages.map((page) => {
  363. return page.path;
  364. });
  365. expect(pagePaths).toContainEqual('/grant/groupacl');
  366. expect(pagePaths).toContainEqual('/grant/specified');
  367. expect(pagePaths).toContainEqual('/grant/owner');
  368. expect(pagePaths).toContainEqual('/grant/public');
  369. expect(pagePaths).toContainEqual('/grant');
  370. });
  371. });
  372. describe('.findManageableListWithDescendants', () => {
  373. test('can retrieve all pages with testUser0', async () => {
  374. const pages = await Page.findManageableListWithDescendants(
  375. parentPage,
  376. testUser0,
  377. );
  378. // assert totalCount
  379. expect(pages.length).toEqual(5);
  380. // assert paths
  381. const pagePaths = await pages.map((page) => {
  382. return page.path;
  383. });
  384. expect(pagePaths).toContainEqual('/grant/groupacl');
  385. expect(pagePaths).toContainEqual('/grant/specified');
  386. expect(pagePaths).toContainEqual('/grant/owner');
  387. expect(pagePaths).toContainEqual('/grant/public');
  388. expect(pagePaths).toContainEqual('/grant');
  389. });
  390. test('can retrieve group page and public page which starts with testUser1', async () => {
  391. const pages = await Page.findManageableListWithDescendants(
  392. parentPage,
  393. testUser1,
  394. );
  395. // assert totalCount
  396. expect(pages.length).toEqual(3);
  397. // assert paths
  398. const pagePaths = await pages.map((page) => {
  399. return page.path;
  400. });
  401. expect(pagePaths).toContainEqual('/grant/groupacl');
  402. expect(pagePaths).toContainEqual('/grant/public');
  403. expect(pagePaths).toContainEqual('/grant');
  404. });
  405. test('can retrieve only public page which starts with testUser2', async () => {
  406. const pages = await Page.findManageableListWithDescendants(
  407. parentPage,
  408. testUser2,
  409. );
  410. // assert totalCount
  411. expect(pages.length).toEqual(2);
  412. // assert paths
  413. const pagePaths = await pages.map((page) => {
  414. return page.path;
  415. });
  416. expect(pagePaths).toContainEqual('/grant/public');
  417. expect(pagePaths).toContainEqual('/grant');
  418. });
  419. test('can retrieve only public page which starts without user', async () => {
  420. const pages = await Page.findManageableListWithDescendants(
  421. parentPage,
  422. null,
  423. );
  424. // assert totalCount
  425. expect(pages).toBeNull();
  426. });
  427. });
  428. });