page.test.js 15 KB

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