page.test.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. /* eslint-disable no-unused-vars */
  2. const mongoose = require('mongoose');
  3. const { getInstance } = require('../setup-crowi');
  4. let testUser1;
  5. let testUser2;
  6. let parentTag;
  7. let childTag;
  8. let parentForRename1;
  9. let parentForRename2;
  10. let parentForRename3;
  11. let parentForRename4;
  12. let parentForDuplicate;
  13. let parentForDelete;
  14. let parentForDeleteCompletely;
  15. let parentForRevert;
  16. let childForRename;
  17. let childForDuplicate;
  18. let childForDelete;
  19. let childForDeleteCompletely;
  20. let childForRevert;
  21. describe('PageService', () => {
  22. let crowi;
  23. let Page;
  24. let Revision;
  25. let User;
  26. let Tag;
  27. let PageTagRelation;
  28. let xssSpy;
  29. beforeAll(async(done) => {
  30. crowi = await getInstance();
  31. User = mongoose.model('User');
  32. Page = mongoose.model('Page');
  33. Revision = mongoose.model('Revision');
  34. Tag = mongoose.model('Tag');
  35. PageTagRelation = mongoose.model('PageTagRelation');
  36. await User.insertMany([
  37. { name: 'someone1', username: 'someone1', email: 'someone1@example.com' },
  38. { name: 'someone2', username: 'someone2', email: 'someone2@example.com' },
  39. ]);
  40. testUser1 = await User.findOne({ username: 'someone1' });
  41. testUser2 = await User.findOne({ username: 'someone2' });
  42. await Page.insertMany([
  43. {
  44. path: '/parentForRename1',
  45. grant: Page.GRANT_PUBLIC,
  46. creator: testUser1,
  47. lastUpdateUser: testUser1,
  48. },
  49. {
  50. path: '/parentForRename2',
  51. grant: Page.GRANT_PUBLIC,
  52. creator: testUser1,
  53. lastUpdateUser: testUser1,
  54. },
  55. {
  56. path: '/parentForRename3',
  57. grant: Page.GRANT_PUBLIC,
  58. creator: testUser1,
  59. lastUpdateUser: testUser1,
  60. },
  61. {
  62. path: '/parentForRename4',
  63. grant: Page.GRANT_PUBLIC,
  64. creator: testUser1,
  65. lastUpdateUser: testUser1,
  66. },
  67. {
  68. path: '/parentForRename1/child',
  69. grant: Page.GRANT_PUBLIC,
  70. creator: testUser1,
  71. lastUpdateUser: testUser1,
  72. },
  73. {
  74. path: '/parentForDuplicate',
  75. grant: Page.GRANT_PUBLIC,
  76. creator: testUser1,
  77. lastUpdateUser: testUser1,
  78. revision: '600d395667536503354cbe91',
  79. },
  80. {
  81. path: '/parentForDuplicate/child',
  82. grant: Page.GRANT_PUBLIC,
  83. creator: testUser1,
  84. lastUpdateUser: testUser1,
  85. },
  86. {
  87. path: '/parentForDelete',
  88. grant: Page.GRANT_PUBLIC,
  89. creator: testUser1,
  90. lastUpdateUser: testUser1,
  91. },
  92. {
  93. path: '/parentForDelete/child',
  94. grant: Page.GRANT_PUBLIC,
  95. creator: testUser1,
  96. lastUpdateUser: testUser1,
  97. },
  98. {
  99. path: '/parentForDeleteCompletely',
  100. grant: Page.GRANT_PUBLIC,
  101. creator: testUser1,
  102. lastUpdateUser: testUser1,
  103. },
  104. {
  105. path: '/parentForDeleteCompletely/child',
  106. grant: Page.GRANT_PUBLIC,
  107. creator: testUser1,
  108. lastUpdateUser: testUser1,
  109. },
  110. {
  111. path: '/parentForRevert',
  112. grant: Page.GRANT_PUBLIC,
  113. creator: testUser1,
  114. lastUpdateUser: testUser1,
  115. },
  116. {
  117. path: '/parentForRevert/child',
  118. grant: Page.GRANT_PUBLIC,
  119. creator: testUser1,
  120. lastUpdateUser: testUser1,
  121. },
  122. ]);
  123. parentForRename1 = await Page.findOne({ path: '/parentForRename1' });
  124. parentForRename2 = await Page.findOne({ path: '/parentForRename2' });
  125. parentForRename3 = await Page.findOne({ path: '/parentForRename3' });
  126. parentForRename4 = await Page.findOne({ path: '/parentForRename4' });
  127. parentForDuplicate = await Page.findOne({ path: '/parentForDuplicate' });
  128. parentForDelete = await Page.findOne({ path: '/parentForDelete' });
  129. parentForDeleteCompletely = await Page.findOne({ path: '/parentForDeleteCompletely' });
  130. parentForRevert = await Page.findOne({ path: '/parentForRevert' });
  131. childForRename = await Page.findOne({ path: '/parentForRename1/child' });
  132. childForDuplicate = await Page.findOne({ path: '/parentForDuplicate/child' });
  133. childForDelete = await Page.findOne({ path: '/parentForDelete/child' });
  134. childForDeleteCompletely = await Page.findOne({ path: '/parentForDeleteCompletely/child' });
  135. childForRevert = await Page.findOne({ path: '/parentForRevert/child' });
  136. await Tag.insertMany([
  137. { name: 'Parent' },
  138. { name: 'Child' },
  139. ]);
  140. parentTag = await Tag.findOne({ name: 'Parent' });
  141. childTag = await Tag.findOne({ name: 'Child' });
  142. await PageTagRelation.insertMany([
  143. { relatedPage: parentForDuplicate, relatedTag: parentTag },
  144. { relatedPage: childForDuplicate, relatedTag: childTag },
  145. ]);
  146. await Revision.insertMany([
  147. {
  148. _id: '600d395667536503354cbe91',
  149. path: parentForDuplicate,
  150. body: 'duplicateBody',
  151. },
  152. ]);
  153. xssSpy = jest.spyOn(crowi.xss, 'process').mockImplementation(path => path);
  154. done();
  155. });
  156. describe('rename page', () => {
  157. let pageEventSpy;
  158. let renameDescendantsWithStreamSpy;
  159. const dateToUse = new Date('2000-01-01');
  160. const socketClientId = null;
  161. beforeEach(async(done) => {
  162. jest.spyOn(global.Date, 'now').mockImplementation(() => dateToUse);
  163. pageEventSpy = jest.spyOn(crowi.pageService.pageEvent, 'emit').mockImplementation();
  164. renameDescendantsWithStreamSpy = jest.spyOn(crowi.pageService, 'renameDescendantsWithStream').mockImplementation();
  165. done();
  166. });
  167. describe('renamePage()', () => {
  168. test('rename page without options', async() => {
  169. const resultPage = await crowi.pageService.renamePage(parentForRename1, '/renamed1', testUser2, {});
  170. const redirectedFromPage = await Page.findOne({ path: '/parentForRename1' });
  171. const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename1' });
  172. expect(xssSpy).toHaveBeenCalled();
  173. expect(renameDescendantsWithStreamSpy).not.toHaveBeenCalled();
  174. expect(pageEventSpy).toHaveBeenCalledWith('delete', parentForRename1, testUser2, socketClientId);
  175. expect(pageEventSpy).toHaveBeenCalledWith('create', resultPage, testUser2, socketClientId);
  176. expect(resultPage.path).toBe('/renamed1');
  177. expect(resultPage.updatedAt).toEqual(parentForRename1.updatedAt);
  178. expect(resultPage.lastUpdateUser).toEqual(testUser1._id);
  179. expect(redirectedFromPage).toBeNull();
  180. expect(redirectedFromPageRevision).toBeNull();
  181. });
  182. test('rename page with updateMetadata option', async() => {
  183. const resultPage = await crowi.pageService.renamePage(parentForRename2, '/renamed2', testUser2, { updateMetadata: true });
  184. const redirectedFromPage = await Page.findOne({ path: '/parentForRename2' });
  185. const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename2' });
  186. expect(xssSpy).toHaveBeenCalled();
  187. expect(renameDescendantsWithStreamSpy).not.toHaveBeenCalled();
  188. expect(pageEventSpy).toHaveBeenCalledWith('delete', parentForRename2, testUser2, socketClientId);
  189. expect(pageEventSpy).toHaveBeenCalledWith('create', resultPage, testUser2, socketClientId);
  190. expect(resultPage.path).toBe('/renamed2');
  191. expect(resultPage.updatedAt).toEqual(dateToUse);
  192. expect(resultPage.lastUpdateUser).toEqual(testUser2._id);
  193. expect(redirectedFromPage).toBeNull();
  194. expect(redirectedFromPageRevision).toBeNull();
  195. });
  196. test('rename page with createRedirectPage option', async() => {
  197. const resultPage = await crowi.pageService.renamePage(parentForRename3, '/renamed3', testUser2, { createRedirectPage: true });
  198. const redirectedFromPage = await Page.findOne({ path: '/parentForRename3' });
  199. const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename3' });
  200. expect(xssSpy).toHaveBeenCalled();
  201. expect(renameDescendantsWithStreamSpy).not.toHaveBeenCalled();
  202. expect(pageEventSpy).toHaveBeenCalledWith('delete', parentForRename3, testUser2, socketClientId);
  203. expect(pageEventSpy).toHaveBeenCalledWith('create', resultPage, testUser2, socketClientId);
  204. expect(resultPage.path).toBe('/renamed3');
  205. expect(resultPage.updatedAt).toEqual(parentForRename3.updatedAt);
  206. expect(resultPage.lastUpdateUser).toEqual(testUser1._id);
  207. expect(redirectedFromPage).not.toBeNull();
  208. expect(redirectedFromPage.path).toBe('/parentForRename3');
  209. expect(redirectedFromPage.redirectTo).toBe('/renamed3');
  210. expect(redirectedFromPageRevision).not.toBeNull();
  211. expect(redirectedFromPageRevision.path).toBe('/parentForRename3');
  212. expect(redirectedFromPageRevision.body).toBe('redirect /renamed3');
  213. });
  214. test('rename page with isRecursively', async() => {
  215. const resultPage = await crowi.pageService.renamePage(parentForRename4, '/renamed4', testUser2, { }, true);
  216. const redirectedFromPage = await Page.findOne({ path: '/parentForRename4' });
  217. const redirectedFromPageRevision = await Revision.findOne({ path: '/parentForRename4' });
  218. expect(xssSpy).toHaveBeenCalled();
  219. expect(renameDescendantsWithStreamSpy).toHaveBeenCalled();
  220. expect(pageEventSpy).toHaveBeenCalledWith('delete', parentForRename4, testUser2, socketClientId);
  221. expect(pageEventSpy).toHaveBeenCalledWith('create', resultPage, testUser2, socketClientId);
  222. expect(resultPage.path).toBe('/renamed4');
  223. expect(resultPage.updatedAt).toEqual(parentForRename4.updatedAt);
  224. expect(resultPage.lastUpdateUser).toEqual(testUser1._id);
  225. expect(redirectedFromPage).toBeNull();
  226. expect(redirectedFromPageRevision).toBeNull();
  227. });
  228. });
  229. test('renameDescendants()', () => {
  230. expect(3).toBe(3);
  231. });
  232. });
  233. describe('duplicate page', () => {
  234. let duplicateDescendantsWithStreamSpy;
  235. jest.mock('../../server/models/serializers/page-serializer');
  236. const { serializePageSecurely } = require('../../server/models/serializers/page-serializer');
  237. serializePageSecurely.mockImplementation(page => page);
  238. beforeEach(async(done) => {
  239. duplicateDescendantsWithStreamSpy = jest.spyOn(crowi.pageService, 'duplicateDescendantsWithStream').mockImplementation();
  240. done();
  241. });
  242. test('duplicate page (isRecursively: false)', async() => {
  243. const dummyId = '600d395667536503354c9999';
  244. crowi.models.Page.findRelatedTagsById = jest.fn().mockImplementation(() => { return parentTag });
  245. const originTagsMock = jest.spyOn(Page, 'findRelatedTagsById').mockImplementation(() => { return parentTag });
  246. jest.spyOn(PageTagRelation, 'updatePageTags').mockImplementation(() => { return [dummyId, parentTag.name] });
  247. jest.spyOn(PageTagRelation, 'listTagNamesByPage').mockImplementation(() => { return [parentTag.name] });
  248. const resultPage = await crowi.pageService.duplicate(parentForDuplicate, '/newParentDuplicate', testUser2, false);
  249. const duplicatedToPageRevision = await Revision.findOne({ path: '/newParentDuplicate' });
  250. expect(xssSpy).toHaveBeenCalled();
  251. expect(duplicateDescendantsWithStreamSpy).not.toHaveBeenCalled();
  252. expect(serializePageSecurely).toHaveBeenCalled();
  253. expect(resultPage.path).toBe('/newParentDuplicate');
  254. expect(resultPage.lastUpdateUser._id).toEqual(testUser2._id);
  255. expect(duplicatedToPageRevision._id).not.toEqual(parentForDuplicate.revision._id);
  256. expect(resultPage.grant).toEqual(parentForDuplicate.grant);
  257. expect(resultPage.tags).toEqual([originTagsMock().name]);
  258. });
  259. test('duplicate page (isRecursively: true)', async() => {
  260. const dummyId = '600d395667536503354c9999';
  261. crowi.models.Page.findRelatedTagsById = jest.fn().mockImplementation(() => { return parentTag });
  262. const originTagsMock = jest.spyOn(Page, 'findRelatedTagsById').mockImplementation(() => { return parentTag });
  263. jest.spyOn(PageTagRelation, 'updatePageTags').mockImplementation(() => { return [dummyId, parentTag.name] });
  264. jest.spyOn(PageTagRelation, 'listTagNamesByPage').mockImplementation(() => { return [parentTag.name] });
  265. const resultPageRecursivly = await crowi.pageService.duplicate(parentForDuplicate, '/newParentDuplicateRecursively', testUser2, true);
  266. const duplicatedRecursivelyToPageRevision = await Revision.findOne({ path: '/newParentDuplicateRecursively' });
  267. expect(xssSpy).toHaveBeenCalled();
  268. expect(duplicateDescendantsWithStreamSpy).toHaveBeenCalled();
  269. expect(serializePageSecurely).toHaveBeenCalled();
  270. expect(resultPageRecursivly.path).toBe('/newParentDuplicateRecursively');
  271. expect(resultPageRecursivly.lastUpdateUser._id).toEqual(testUser2._id);
  272. expect(duplicatedRecursivelyToPageRevision._id).not.toEqual(parentForDuplicate.revision._id);
  273. expect(resultPageRecursivly.grant).toEqual(parentForDuplicate.grant);
  274. expect(resultPageRecursivly.tags).toEqual([originTagsMock().name]);
  275. });
  276. test('duplicateDescendants()', () => {
  277. expect(3).toBe(3);
  278. });
  279. test('duplicateTags()', async() => {
  280. const newPageDummy = [];
  281. newPageDummy.push({
  282. _id: '60110bdd85339d7dc732dddd',
  283. path: '/newPageDummyPath',
  284. creator: parentForDuplicate._id,
  285. grant: parentForDuplicate.grant,
  286. grantedGroup: parentForDuplicate.grantedGroup,
  287. grantedUsers: parentForDuplicate.grantedUsers,
  288. lastUpdateUser: parentForDuplicate._id,
  289. redirectTo: null,
  290. revision: parentForDuplicate.revisionId,
  291. });
  292. const pageIdMapping = {};
  293. pageIdMapping[parentForDuplicate._id] = newPageDummy[0]._id;
  294. await crowi.pageService.duplicateTags(pageIdMapping);
  295. const parentoForDuplicateTags = await PageTagRelation.find({ relatedPage: parentForDuplicate });
  296. const pageTagRelationAfterDuplicated = await PageTagRelation.find({ relatedPage: newPageDummy });
  297. expect(pageTagRelationAfterDuplicated.relatedTag).toEqual(parentoForDuplicateTags.relatedTag);
  298. });
  299. });
  300. describe('delete page', () => {
  301. test('deletePage()', () => {
  302. expect(3).toBe(3);
  303. });
  304. test('deleteDescendants()', () => {
  305. expect(3).toBe(3);
  306. });
  307. });
  308. describe('delete page completely', () => {
  309. test('deleteCompletely()', () => {
  310. expect(3).toBe(3);
  311. });
  312. test('deleteMultipleCompletely()', () => {
  313. expect(3).toBe(3);
  314. });
  315. });
  316. describe('revert page', () => {
  317. test('revertDeletedPage()', () => {
  318. expect(3).toBe(3);
  319. });
  320. test('revertDeletedPages()', () => {
  321. expect(3).toBe(3);
  322. });
  323. });
  324. });