| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379 |
- /* eslint-disable no-unused-vars */
- import {
- GroupType,
- type IGrantedGroup,
- type IPage,
- type IRevision,
- } from '@growi/core';
- import mongoose from 'mongoose';
- import { ExternalGroupProviderType } from '../../../src/features/external-user-group/interfaces/external-user-group';
- import ExternalUserGroup from '../../../src/features/external-user-group/server/models/external-user-group';
- import ExternalUserGroupRelation from '../../../src/features/external-user-group/server/models/external-user-group-relation';
- import type { IPageTagRelation } from '../../../src/interfaces/page-tag-relation';
- import type Crowi from '../../../src/server/crowi';
- import type { PageDocument, PageModel } from '../../../src/server/models/page';
- import PageTagRelation from '../../../src/server/models/page-tag-relation';
- import type {
- IRevisionDocument,
- IRevisionModel,
- } from '../../../src/server/models/revision';
- import Tag from '../../../src/server/models/tag';
- import UserGroup from '../../../src/server/models/user-group';
- import UserGroupRelation from '../../../src/server/models/user-group-relation';
- import { generalXssFilter } from '../../../src/services/general-xss-filter';
- import { getInstance } from '../setup-crowi';
- describe('PageService page operations with non-public pages', () => {
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
- let dummyUser1;
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
- let dummyUser2;
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
- let npDummyUser1;
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
- let npDummyUser2;
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
- let npDummyUser3;
- let groupIdIsolate: mongoose.Types.ObjectId;
- let groupIdA: mongoose.Types.ObjectId;
- let groupIdB: mongoose.Types.ObjectId;
- let groupIdC: mongoose.Types.ObjectId;
- let externalGroupIdIsolate: mongoose.Types.ObjectId;
- let externalGroupIdA: mongoose.Types.ObjectId;
- let externalGroupIdB: mongoose.Types.ObjectId;
- let externalGroupIdC: mongoose.Types.ObjectId;
- let crowi: Crowi;
- let Page: PageModel;
- let Revision: IRevisionModel;
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
- let User;
- let generalXssFilterProcessSpy: jest.SpyInstance;
- let rootPage: PageDocument;
- /**
- * Rename
- */
- const pageIdRename1 = new mongoose.Types.ObjectId();
- const pageIdRename2 = new mongoose.Types.ObjectId();
- const pageIdRename3 = new mongoose.Types.ObjectId();
- const pageIdRename4 = new mongoose.Types.ObjectId();
- const pageIdRename5 = new mongoose.Types.ObjectId();
- const pageIdRename6 = new mongoose.Types.ObjectId();
- const pageIdRename7 = new mongoose.Types.ObjectId();
- const pageIdRename8 = new mongoose.Types.ObjectId();
- const pageIdRename9 = new mongoose.Types.ObjectId();
- /**
- * Duplicate
- */
- // page id
- const pageIdDuplicate1 = new mongoose.Types.ObjectId();
- const pageIdDuplicate2 = new mongoose.Types.ObjectId();
- const pageIdDuplicate3 = new mongoose.Types.ObjectId();
- const pageIdDuplicate4 = new mongoose.Types.ObjectId();
- const pageIdDuplicate5 = new mongoose.Types.ObjectId();
- const pageIdDuplicate6 = new mongoose.Types.ObjectId();
- const pageIdDuplicate7 = new mongoose.Types.ObjectId();
- const pageIdDuplicate8 = new mongoose.Types.ObjectId();
- const pageIdDuplicate9 = new mongoose.Types.ObjectId();
- // revision id
- const revisionIdDuplicate1 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate2 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate3 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate4 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate5 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate6 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate7 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate8 = new mongoose.Types.ObjectId();
- const revisionIdDuplicate9 = new mongoose.Types.ObjectId();
- /**
- * Revert
- */
- // page id
- const pageIdRevert1 = new mongoose.Types.ObjectId();
- const pageIdRevert2 = new mongoose.Types.ObjectId();
- const pageIdRevert3 = new mongoose.Types.ObjectId();
- const pageIdRevert4 = new mongoose.Types.ObjectId();
- const pageIdRevert5 = new mongoose.Types.ObjectId();
- const pageIdRevert6 = new mongoose.Types.ObjectId();
- // revision id
- const revisionIdRevert1 = new mongoose.Types.ObjectId();
- const revisionIdRevert2 = new mongoose.Types.ObjectId();
- const revisionIdRevert3 = new mongoose.Types.ObjectId();
- const revisionIdRevert4 = new mongoose.Types.ObjectId();
- const revisionIdRevert5 = new mongoose.Types.ObjectId();
- const revisionIdRevert6 = new mongoose.Types.ObjectId();
- // tag id
- const tagIdRevert1 = new mongoose.Types.ObjectId();
- const tagIdRevert2 = new mongoose.Types.ObjectId();
- const create = async (path, body, user, options = {}) => {
- const mockedCreateSubOperation = jest
- .spyOn(crowi.pageService, 'createSubOperation')
- .mockReturnValue(null);
- const createdPage = await crowi.pageService.create(
- path,
- body,
- user,
- options,
- );
- const argsForCreateSubOperation = mockedCreateSubOperation.mock.calls[0];
- mockedCreateSubOperation.mockRestore();
- await crowi.pageService.createSubOperation(
- ...(argsForCreateSubOperation as Parameters<
- typeof crowi.pageService.createSubOperation
- >),
- );
- return createdPage;
- };
- // normalize for result comparison
- const normalizeGrantedGroups = (
- grantedGroups: IGrantedGroup[] | undefined,
- ) => {
- return grantedGroups?.map((group) => {
- const itemId =
- typeof group.item === 'string' ? group.item : group.item._id;
- return { item: itemId, type: group.type };
- });
- };
- beforeAll(async () => {
- crowi = await getInstance();
- await crowi.configManager.updateConfig('app:isV5Compatible', true);
- User = mongoose.model('User');
- Page = mongoose.model<IPage, PageModel>('Page');
- Revision = mongoose.model<IRevision, IRevisionModel>('Revision');
- /*
- * Common
- */
- const npUserId1 = new mongoose.Types.ObjectId();
- const npUserId2 = new mongoose.Types.ObjectId();
- const npUserId3 = new mongoose.Types.ObjectId();
- await User.insertMany([
- {
- _id: npUserId1,
- name: 'npUser1',
- username: 'npUser1',
- email: 'npUser1@example.com',
- },
- {
- _id: npUserId2,
- name: 'npUser2',
- username: 'npUser2',
- email: 'npUser2@example.com',
- },
- {
- _id: npUserId3,
- name: 'npUser3',
- username: 'npUser3',
- email: 'npUser3@example.com',
- },
- ]);
- groupIdIsolate = new mongoose.Types.ObjectId();
- groupIdA = new mongoose.Types.ObjectId();
- groupIdB = new mongoose.Types.ObjectId();
- groupIdC = new mongoose.Types.ObjectId();
- await UserGroup.insertMany([
- {
- _id: groupIdIsolate,
- name: 'np_groupIsolate',
- },
- {
- _id: groupIdA,
- name: 'np_groupA',
- },
- {
- _id: groupIdB,
- name: 'np_groupB',
- parent: groupIdA,
- },
- {
- _id: groupIdC,
- name: 'np_groupC',
- parent: groupIdB,
- },
- ]);
- await UserGroupRelation.insertMany([
- {
- relatedGroup: groupIdIsolate,
- relatedUser: npUserId1,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdIsolate,
- relatedUser: npUserId2,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdA,
- relatedUser: npUserId1,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdA,
- relatedUser: npUserId2,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdA,
- relatedUser: npUserId3,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdB,
- relatedUser: npUserId2,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdB,
- relatedUser: npUserId3,
- createdAt: new Date(),
- },
- {
- relatedGroup: groupIdC,
- relatedUser: npUserId3,
- createdAt: new Date(),
- },
- ]);
- // Insert ExternalUserGroups with the same group structure as UserGroups
- // Use to test
- // - ExternalUserGroup
- // - Case of multiple grantedGroups for Page
- externalGroupIdIsolate = new mongoose.Types.ObjectId();
- externalGroupIdA = new mongoose.Types.ObjectId();
- externalGroupIdB = new mongoose.Types.ObjectId();
- externalGroupIdC = new mongoose.Types.ObjectId();
- await ExternalUserGroup.insertMany([
- {
- _id: externalGroupIdIsolate,
- name: 'np_externalGroupIsolate',
- externalId: 'np_externalGroupIsolate',
- provider: ExternalGroupProviderType.ldap,
- },
- {
- _id: externalGroupIdA,
- name: 'np_externalGroupA',
- externalId: 'np_externalGroupA',
- provider: ExternalGroupProviderType.ldap,
- },
- {
- _id: externalGroupIdB,
- name: 'np_externalGroupB',
- externalId: 'np_externalGroupB',
- parent: externalGroupIdA,
- provider: ExternalGroupProviderType.ldap,
- },
- {
- _id: externalGroupIdC,
- name: 'np_externalGroupC',
- externalId: 'np_externalGroupC',
- parent: externalGroupIdB,
- provider: ExternalGroupProviderType.ldap,
- },
- ]);
- await ExternalUserGroupRelation.insertMany([
- {
- relatedGroup: externalGroupIdIsolate,
- relatedUser: npUserId1,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdIsolate,
- relatedUser: npUserId2,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdA,
- relatedUser: npUserId1,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdA,
- relatedUser: npUserId2,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdA,
- relatedUser: npUserId3,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdB,
- relatedUser: npUserId2,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdB,
- relatedUser: npUserId3,
- createdAt: new Date(),
- },
- {
- relatedGroup: externalGroupIdC,
- relatedUser: npUserId3,
- createdAt: new Date(),
- },
- ]);
- generalXssFilterProcessSpy = jest.spyOn(generalXssFilter, 'process');
- dummyUser1 = await User.findOne({ username: 'v5DummyUser1' });
- dummyUser2 = await User.findOne({ username: 'v5DummyUser2' });
- npDummyUser1 = await User.findOne({ username: 'npUser1' });
- npDummyUser2 = await User.findOne({ username: 'npUser2' });
- npDummyUser3 = await User.findOne({ username: 'npUser3' });
- rootPage = (await Page.findOne({ path: '/' }))!;
- if (rootPage == null) {
- const pages = await Page.insertMany([
- { path: '/', grant: Page.GRANT_PUBLIC },
- ]);
- rootPage = pages[0];
- }
- /**
- * create
- * mc_ => model create
- * emp => empty => page with isEmpty: true
- * pub => public => GRANT_PUBLIC
- */
- const pageIdCreate1 = new mongoose.Types.ObjectId();
- const pageIdCreate2 = new mongoose.Types.ObjectId();
- const pageIdCreate3 = new mongoose.Types.ObjectId();
- await Page.insertMany([
- {
- _id: pageIdCreate1,
- path: '/mc4_top/mc1_emp',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- parent: rootPage._id,
- isEmpty: true,
- },
- {
- path: '/mc4_top/mc1_emp/mc2_pub',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- parent: pageIdCreate1,
- isEmpty: false,
- },
- {
- path: '/mc5_top/mc3_awl',
- grant: Page.GRANT_RESTRICTED,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- },
- {
- _id: pageIdCreate2,
- path: '/mc4_top',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 1,
- },
- {
- _id: pageIdCreate3,
- path: '/mc5_top',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 0,
- },
- {
- path: '/mc6_top',
- grant: Page.GRANT_USER_GROUP,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 0,
- grantedGroups: [
- { item: groupIdIsolate, type: GroupType.userGroup },
- { item: groupIdB, type: GroupType.userGroup },
- ],
- },
- ]);
- /**
- * create
- * mc_ => model create
- * emp => empty => page with isEmpty: true
- * pub => public => GRANT_PUBLIC
- */
- const pageIdCreateBySystem1 = new mongoose.Types.ObjectId();
- const pageIdCreateBySystem2 = new mongoose.Types.ObjectId();
- const pageIdCreateBySystem3 = new mongoose.Types.ObjectId();
- await Page.insertMany([
- {
- _id: pageIdCreateBySystem1,
- path: '/mc4_top_by_system/mc1_emp_by_system',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- parent: rootPage._id,
- isEmpty: true,
- },
- {
- path: '/mc4_top_by_system/mc1_emp_by_system/mc2_pub_by_system',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- parent: pageIdCreateBySystem1,
- isEmpty: false,
- },
- {
- path: '/mc5_top_by_system/mc3_awl_by_system',
- grant: Page.GRANT_RESTRICTED,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- },
- {
- _id: pageIdCreateBySystem2,
- path: '/mc4_top_by_system',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 1,
- },
- {
- _id: pageIdCreateBySystem3,
- path: '/mc5_top_by_system',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1,
- lastUpdateUser: dummyUser1._id,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 0,
- },
- ]);
- /*
- * Rename
- */
- await Page.insertMany([
- {
- _id: pageIdRename1,
- path: '/np_rename1_destination',
- grant: Page.GRANT_PUBLIC,
- creator: dummyUser1._id,
- lastUpdateUser: dummyUser1._id,
- parent: rootPage._id,
- },
- {
- _id: pageIdRename2,
- path: '/np_rename2',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser2._id,
- lastUpdateUser: npDummyUser2._id,
- parent: rootPage._id,
- },
- {
- _id: pageIdRename3,
- path: '/np_rename2/np_rename3',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdC, type: GroupType.userGroup },
- { item: externalGroupIdC, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser3._id,
- lastUpdateUser: npDummyUser3._id,
- parent: pageIdRename2._id,
- },
- {
- _id: pageIdRename4,
- path: '/np_rename4_destination',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdIsolate, type: GroupType.userGroup },
- { item: externalGroupIdIsolate, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser3._id,
- lastUpdateUser: npDummyUser3._id,
- parent: rootPage._id,
- },
- {
- _id: pageIdRename5,
- path: '/np_rename5',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser2._id,
- lastUpdateUser: npDummyUser2._id,
- parent: rootPage._id,
- },
- {
- _id: pageIdRename6,
- path: '/np_rename5/np_rename6',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser2._id,
- lastUpdateUser: npDummyUser2._id,
- parent: pageIdRename5,
- },
- {
- _id: pageIdRename7,
- path: '/np_rename7_destination',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdIsolate, type: GroupType.userGroup },
- { item: externalGroupIdIsolate, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser2._id,
- lastUpdateUser: npDummyUser2._id,
- parent: pageIdRename5,
- },
- {
- _id: pageIdRename8,
- path: '/np_rename8',
- grant: Page.GRANT_RESTRICTED,
- creator: dummyUser1._id,
- lastUpdateUser: dummyUser1._id,
- },
- {
- _id: pageIdRename9,
- path: '/np_rename8/np_rename9',
- grant: Page.GRANT_RESTRICTED,
- creator: dummyUser2._id,
- lastUpdateUser: dummyUser2._id,
- },
- ]);
- /*
- * Duplicate
- */
- await Page.insertMany([
- {
- _id: pageIdDuplicate1,
- path: '/np_duplicate1',
- grant: Page.GRANT_RESTRICTED,
- creator: dummyUser1._id,
- lastUpdateUser: dummyUser1._id,
- revision: revisionIdDuplicate1,
- },
- {
- _id: pageIdDuplicate2,
- path: '/np_duplicate2',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser1._id,
- lastUpdateUser: npDummyUser1._id,
- revision: revisionIdDuplicate2,
- parent: rootPage._id,
- },
- {
- _id: pageIdDuplicate3,
- path: '/np_duplicate2/np_duplicate3',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- creator: npDummyUser2._id,
- lastUpdateUser: npDummyUser2._id,
- revision: revisionIdDuplicate3,
- parent: pageIdDuplicate2,
- },
- {
- _id: pageIdDuplicate4,
- path: '/np_duplicate4',
- grant: Page.GRANT_PUBLIC,
- creator: npDummyUser1._id,
- lastUpdateUser: npDummyUser1._id,
- revision: revisionIdDuplicate4,
- parent: rootPage._id,
- },
- {
- _id: pageIdDuplicate5,
- path: '/np_duplicate4/np_duplicate5',
- grant: Page.GRANT_RESTRICTED,
- creator: npDummyUser1._id,
- lastUpdateUser: npDummyUser1._id,
- revision: revisionIdDuplicate5,
- },
- {
- _id: pageIdDuplicate6,
- path: '/np_duplicate4/np_duplicate6',
- grant: Page.GRANT_PUBLIC,
- creator: npDummyUser1._id,
- lastUpdateUser: npDummyUser1._id,
- parent: pageIdDuplicate4,
- revision: revisionIdDuplicate6,
- },
- {
- _id: pageIdDuplicate7,
- path: '/np_duplicate7',
- grant: Page.GRANT_USER_GROUP,
- creator: npDummyUser1._id,
- lastUpdateUser: npDummyUser1._id,
- parent: rootPage._id,
- revision: revisionIdDuplicate7,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- },
- {
- _id: pageIdDuplicate8,
- path: '/np_duplicate7/np_duplicate8',
- grant: Page.GRANT_USER_GROUP,
- creator: npDummyUser3._id,
- lastUpdateUser: npDummyUser3._id,
- parent: pageIdDuplicate7,
- revision: revisionIdDuplicate8,
- grantedGroups: [
- { item: groupIdC, type: GroupType.userGroup },
- { item: externalGroupIdC, type: GroupType.externalUserGroup },
- ],
- },
- {
- _id: pageIdDuplicate9,
- path: '/np_duplicate7/np_duplicate9',
- grant: Page.GRANT_OWNER,
- creator: npDummyUser2._id,
- lastUpdateUser: npDummyUser2._id,
- parent: pageIdDuplicate7,
- revision: revisionIdDuplicate9,
- grantedUsers: [npDummyUser2._id],
- },
- ]);
- await Revision.insertMany([
- {
- _id: revisionIdDuplicate1,
- body: 'np_duplicate1',
- format: 'markdown',
- pageId: pageIdDuplicate1,
- author: npDummyUser1._id,
- },
- {
- _id: revisionIdDuplicate2,
- body: 'np_duplicate2',
- format: 'markdown',
- pageId: pageIdDuplicate2,
- author: npDummyUser2._id,
- },
- {
- _id: revisionIdDuplicate3,
- body: 'np_duplicate3',
- format: 'markdown',
- pageId: pageIdDuplicate3,
- author: npDummyUser2._id,
- },
- {
- _id: revisionIdDuplicate4,
- body: 'np_duplicate4',
- format: 'markdown',
- pageId: pageIdDuplicate4,
- author: npDummyUser2._id,
- },
- {
- _id: revisionIdDuplicate5,
- body: 'np_duplicate5',
- format: 'markdown',
- pageId: pageIdDuplicate5,
- author: npDummyUser2._id,
- },
- {
- _id: revisionIdDuplicate6,
- body: 'np_duplicate6',
- format: 'markdown',
- pageId: pageIdDuplicate6,
- author: npDummyUser1._id,
- },
- {
- _id: revisionIdDuplicate7,
- body: 'np_duplicate7',
- format: 'markdown',
- pageId: pageIdDuplicate7,
- author: npDummyUser1._id,
- },
- {
- _id: revisionIdDuplicate8,
- body: 'np_duplicate8',
- format: 'markdown',
- pageId: pageIdDuplicate8,
- author: npDummyUser3._id,
- },
- {
- _id: revisionIdDuplicate9,
- body: 'np_duplicate9',
- format: 'markdown',
- pageId: pageIdDuplicate9,
- author: npDummyUser2._id,
- },
- ]);
- /**
- * Delete
- */
- const pageIdDelete1 = new mongoose.Types.ObjectId();
- const pageIdDelete2 = new mongoose.Types.ObjectId();
- const pageIdDelete3 = new mongoose.Types.ObjectId();
- const pageIdDelete4 = new mongoose.Types.ObjectId();
- await Page.insertMany([
- {
- _id: pageIdDelete1,
- path: '/npdel1_awl',
- grant: Page.GRANT_RESTRICTED,
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- },
- {
- _id: pageIdDelete2,
- path: '/npdel2_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 0,
- },
- {
- _id: pageIdDelete3,
- path: '/npdel3_top',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: rootPage._id,
- descendantCount: 2,
- },
- {
- _id: pageIdDelete4,
- path: '/npdel3_top/npdel4_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: pageIdDelete3._id,
- descendantCount: 1,
- },
- {
- path: '/npdel3_top/npdel4_ug',
- grant: Page.GRANT_RESTRICTED,
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- },
- {
- path: '/npdel3_top/npdel4_ug/npdel5_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdC, type: GroupType.userGroup },
- { item: externalGroupIdC, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: pageIdDelete4._id,
- descendantCount: 0,
- },
- ]);
- /**
- * Delete completely
- */
- const pageIdDeleteComp1 = new mongoose.Types.ObjectId();
- const pageIdDeleteComp2 = new mongoose.Types.ObjectId();
- await Page.insertMany([
- {
- path: '/npdc1_awl',
- grant: Page.GRANT_RESTRICTED,
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- },
- {
- path: '/npdc2_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: rootPage._id,
- },
- {
- _id: pageIdDeleteComp1,
- path: '/npdc3_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: rootPage._id,
- },
- {
- _id: pageIdDeleteComp2,
- path: '/npdc3_ug/npdc4_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: pageIdDeleteComp1,
- },
- {
- path: '/npdc3_ug/npdc4_ug/npdc5_ug',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdC, type: GroupType.userGroup },
- { item: externalGroupIdC, type: GroupType.externalUserGroup },
- ],
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- parent: pageIdDeleteComp2,
- },
- {
- path: '/npdc3_ug/npdc4_ug',
- grant: Page.GRANT_RESTRICTED,
- status: Page.STATUS_PUBLISHED,
- isEmpty: false,
- },
- ]);
- /**
- * Revert
- */
- await Page.insertMany([
- {
- _id: pageIdRevert1,
- path: '/trash/np_revert1',
- grant: Page.GRANT_RESTRICTED,
- revision: revisionIdRevert1,
- status: Page.STATUS_DELETED,
- },
- {
- _id: pageIdRevert2,
- path: '/trash/np_revert2',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- revision: revisionIdRevert2,
- status: Page.STATUS_DELETED,
- },
- {
- _id: pageIdRevert3,
- path: '/trash/np_revert3',
- revision: revisionIdRevert3,
- status: Page.STATUS_DELETED,
- parent: rootPage._id,
- },
- {
- _id: pageIdRevert4,
- path: '/trash/np_revert3/middle/np_revert4',
- grant: Page.GRANT_RESTRICTED,
- revision: revisionIdRevert4,
- status: Page.STATUS_DELETED,
- },
- {
- _id: pageIdRevert5,
- path: '/trash/np_revert5',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- revision: revisionIdRevert5,
- status: Page.STATUS_DELETED,
- },
- {
- _id: pageIdRevert6,
- path: '/trash/np_revert5/middle/np_revert6',
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: [
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ],
- revision: revisionIdRevert6,
- status: Page.STATUS_DELETED,
- },
- ]);
- await Revision.insertMany([
- {
- _id: revisionIdRevert1,
- pageId: pageIdRevert1,
- body: 'np_revert1',
- format: 'markdown',
- author: dummyUser1._id,
- },
- {
- _id: revisionIdRevert2,
- pageId: pageIdRevert2,
- body: 'np_revert2',
- format: 'markdown',
- author: npDummyUser1,
- },
- {
- _id: revisionIdRevert3,
- pageId: pageIdRevert3,
- body: 'np_revert3',
- format: 'markdown',
- author: npDummyUser1,
- },
- {
- _id: revisionIdRevert4,
- pageId: pageIdRevert4,
- body: 'np_revert4',
- format: 'markdown',
- author: npDummyUser1,
- },
- {
- _id: revisionIdRevert5,
- pageId: pageIdRevert5,
- body: 'np_revert5',
- format: 'markdown',
- author: npDummyUser1,
- },
- {
- _id: revisionIdRevert6,
- pageId: pageIdRevert6,
- body: 'np_revert6',
- format: 'markdown',
- author: npDummyUser1,
- },
- ]);
- await Tag.insertMany([
- { _id: tagIdRevert1, name: 'np_revertTag1' },
- { _id: tagIdRevert2, name: 'np_revertTag2' },
- ]);
- await PageTagRelation.insertMany([
- {
- relatedPage: pageIdRevert1,
- relatedTag: tagIdRevert1,
- isPageTrashed: true,
- },
- {
- relatedPage: pageIdRevert2,
- relatedTag: tagIdRevert2,
- isPageTrashed: true,
- },
- ]);
- });
- describe('create', () => {
- describe('Creating a page using existing path', () => {
- test('with grant RESTRICTED should only create the page and change nothing else', async () => {
- const isGrantNormalizedSpy = jest.spyOn(
- crowi.pageGrantService,
- 'isGrantNormalized',
- );
- const pathT = '/mc4_top';
- const path1 = '/mc4_top/mc1_emp';
- const path2 = '/mc4_top/mc1_emp/mc2_pub';
- const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
- const page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- });
- const page2 = await Page.findOne({ path: path2 });
- const page3 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(pageT).toBeTruthy();
- expect(page1).toBeTruthy();
- expect(page2).toBeTruthy();
- expect(page3).toBeNull();
- // use existing path
- await create(path1, 'new body', dummyUser1, {
- grant: Page.GRANT_RESTRICTED,
- });
- const _pageT = await Page.findOne({ path: pathT });
- const _page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- });
- const _page2 = await Page.findOne({ path: path2 });
- const _page3 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(_pageT).toBeTruthy();
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- expect(_pageT?.descendantCount).toBe(1);
- // isGrantNormalized is not called when GRANT RESTRICTED
- expect(isGrantNormalizedSpy).toBeCalledTimes(0);
- });
- });
- describe('Creating a page under a page with grant RESTRICTED', () => {
- test('will create a new empty page with the same path as the grant RESTRECTED page and become a parent', async () => {
- const isGrantNormalizedSpy = jest.spyOn(
- crowi.pageGrantService,
- 'isGrantNormalized',
- );
- const pathT = '/mc5_top';
- const path1 = '/mc5_top/mc3_awl';
- const pathN = '/mc5_top/mc3_awl/mc4_pub'; // used to create
- const pageT = await Page.findOne({ path: pathT });
- const page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- const page2 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- });
- expect(pageT).toBeTruthy();
- expect(page1).toBeTruthy();
- expect(page2).toBeNull();
- await create(pathN, 'new body', dummyUser1, {
- grant: Page.GRANT_PUBLIC,
- });
- const _pageT = await Page.findOne({ path: pathT });
- const _page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- const _page2 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- isEmpty: true,
- });
- const _pageN = await Page.findOne({
- path: pathN,
- grant: Page.GRANT_PUBLIC,
- }); // newly crated
- expect(_pageT).toBeTruthy();
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_pageN).toBeTruthy();
- expect(_pageN?.parent).toStrictEqual(_page2?._id);
- expect(_pageT?.descendantCount).toStrictEqual(1);
- // isGrantNormalized is called when GRANT PUBLIC
- expect(isGrantNormalizedSpy).toBeCalledTimes(1);
- });
- });
- describe('Creating a page under a page with grant USER_GROUP', () => {
- describe('When onlyInheritUserRelatedGrantedGroups is true', () => {
- test('Only user related groups should be inherited', async () => {
- const pathT = '/mc6_top';
- const pageT = await Page.findOne({ path: pathT });
- expect(pageT).toBeTruthy();
- const pathN = '/mc6_top/onlyRelatedGroupsInherited'; // path to create
- await create(pathN, 'new body', npDummyUser1, {
- grant: Page.GRANT_USER_GROUP,
- onlyInheritUserRelatedGrantedGroups: true,
- });
- const _pageT = await Page.findOne({ path: pathT });
- const _pageN = await Page.findOne({
- path: pathN,
- grant: Page.GRANT_USER_GROUP,
- }); // newly crated
- expect(_pageT).toBeTruthy();
- expect(_pageN).toBeTruthy();
- expect(_pageN?.parent).toStrictEqual(_pageT?._id);
- expect(_pageT?.descendantCount).toStrictEqual(1);
- expect(normalizeGrantedGroups(_pageN?.grantedGroups)).toStrictEqual([
- { item: groupIdIsolate, type: GroupType.userGroup },
- ]);
- });
- });
- describe('When onlyInheritUserRelatedGrantedGroups is false', () => {
- test('All groups should be inherited', async () => {
- const pathT = '/mc6_top';
- const pageT = await Page.findOne({ path: pathT });
- expect(pageT).toBeTruthy();
- const pathN = '/mc6_top/allGroupsInherited'; // path to create
- await create(pathN, 'new body', npDummyUser1, {
- grant: Page.GRANT_USER_GROUP,
- onlyInheritUserRelatedGrantedGroups: false,
- });
- const _pageT = await Page.findOne({ path: pathT });
- const _pageN = await Page.findOne({
- path: pathN,
- grant: Page.GRANT_USER_GROUP,
- }); // newly crated
- expect(_pageT).toBeTruthy();
- expect(_pageN).toBeTruthy();
- expect(_pageN?.parent).toStrictEqual(_pageT?._id);
- expect(_pageT?.descendantCount).toStrictEqual(2);
- expect(normalizeGrantedGroups(_pageN?.grantedGroups)).toStrictEqual([
- { item: groupIdIsolate, type: GroupType.userGroup },
- { item: groupIdB, type: GroupType.userGroup },
- ]);
- });
- });
- });
- });
- describe('create by system', () => {
- describe('Creating a page using existing path', () => {
- test('with grant RESTRICTED should only create the page and change nothing else', async () => {
- const isGrantNormalizedSpy = jest.spyOn(
- crowi.pageGrantService,
- 'isGrantNormalized',
- );
- const pathT = '/mc4_top_by_system';
- const path1 = '/mc4_top_by_system/mc1_emp_by_system';
- const path2 = '/mc4_top_by_system/mc1_emp_by_system/mc2_pub_by_system';
- const pageT = await Page.findOne({ path: pathT, descendantCount: 1 });
- const page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- });
- const page2 = await Page.findOne({ path: path2 });
- const page3 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(pageT).toBeTruthy();
- expect(page1).toBeTruthy();
- expect(page2).toBeTruthy();
- expect(page3).toBeNull();
- // use existing path
- await crowi.pageService.forceCreateBySystem(path1, 'new body', {
- grant: Page.GRANT_RESTRICTED,
- });
- const _pageT = await Page.findOne({ path: pathT });
- const _page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- });
- const _page2 = await Page.findOne({ path: path2 });
- const _page3 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(_pageT).toBeTruthy();
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- expect(_pageT?.descendantCount).toBe(1);
- // isGrantNormalized is not called when create by ststem
- expect(isGrantNormalizedSpy).toBeCalledTimes(0);
- });
- });
- describe('Creating a page under a page with grant RESTRICTED', () => {
- test('will create a new empty page with the same path as the grant RESTRECTED page and become a parent', async () => {
- const isGrantNormalizedSpy = jest.spyOn(
- crowi.pageGrantService,
- 'isGrantNormalized',
- );
- const pathT = '/mc5_top_by_system';
- const path1 = '/mc5_top_by_system/mc3_awl_by_system';
- const pathN = '/mc5_top_by_system/mc3_awl_by_system/mc4_pub_by_system'; // used to create
- const pageT = await Page.findOne({ path: pathT });
- const page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- const page2 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- });
- expect(pageT).toBeTruthy();
- expect(page1).toBeTruthy();
- expect(page2).toBeNull();
- await crowi.pageService.forceCreateBySystem(pathN, 'new body', {
- grant: Page.GRANT_PUBLIC,
- });
- const _pageT = await Page.findOne({ path: pathT });
- const _page1 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_RESTRICTED,
- });
- const _page2 = await Page.findOne({
- path: path1,
- grant: Page.GRANT_PUBLIC,
- isEmpty: true,
- });
- const _pageN = await Page.findOne({
- path: pathN,
- grant: Page.GRANT_PUBLIC,
- }); // newly crated
- expect(_pageT).toBeTruthy();
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_pageN).toBeTruthy();
- expect(_pageN?.parent).toStrictEqual(_page2?._id);
- expect(_pageT?.descendantCount).toStrictEqual(1);
- // isGrantNormalized is not called when create by ststem
- expect(isGrantNormalizedSpy).toBeCalledTimes(0);
- });
- });
- });
- describe('Rename', () => {
- const renamePage = async (
- page,
- newPagePath,
- user,
- options,
- activityParameters?,
- ) => {
- // mock return value
- const mockedRenameSubOperation = jest
- .spyOn(crowi.pageService, 'renameSubOperation')
- .mockReturnValue(null);
- const renamedPage = await crowi.pageService.renamePage(
- page,
- newPagePath,
- user,
- options,
- activityParameters,
- );
- // retrieve the arguments passed when calling method renameSubOperation inside renamePage method
- const argsForRenameSubOperation = mockedRenameSubOperation.mock.calls[0];
- // restores the original implementation
- mockedRenameSubOperation.mockRestore();
- // rename descendants
- if (page.grant !== Page.GRANT_RESTRICTED) {
- await crowi.pageService.renameSubOperation(
- ...(argsForRenameSubOperation as Parameters<
- typeof crowi.pageService.renameSubOperation
- >),
- );
- }
- return renamedPage;
- };
- test('Should rename/move with descendants with grant normalized pages', async () => {
- const _pathD = '/np_rename1_destination';
- const _path2 = '/np_rename2';
- const _path3 = '/np_rename2/np_rename3';
- const _propertiesD = { grant: Page.GRANT_PUBLIC };
- const _properties2 = {
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- };
- const _properties3 = {
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdC } },
- };
- const _pageD = await Page.findOne({ path: _pathD, ..._propertiesD });
- const _page2 = await Page.findOne({ path: _path2, ..._properties2 });
- const _page3 = await Page.findOne({
- path: _path3,
- ..._properties3,
- parent: _page2?._id,
- });
- expect(_pageD).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- const newPathForPage2 = '/np_rename1_destination/np_rename2';
- const newPathForPage3 = '/np_rename1_destination/np_rename2/np_rename3';
- await renamePage(
- _page2,
- newPathForPage2,
- npDummyUser2,
- {},
- {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- activityId: '62e291bc10e0ab61bd691794',
- },
- );
- const pageD = await Page.findOne({ path: _pathD, ..._propertiesD });
- const page2 = await Page.findOne({ path: _path2, ..._properties2 }); // not exist
- const page3 = await Page.findOne({
- path: _path3,
- ..._properties3,
- parent: _page2?._id,
- }); // not exist
- const page2Renamed = await Page.findOne({ path: newPathForPage2 }); // renamed
- const page3Renamed = await Page.findOne({ path: newPathForPage3 }); // renamed
- expect(pageD).toBeTruthy();
- expect(page2).toBeNull();
- expect(page3).toBeNull();
- expect(page2Renamed).toBeTruthy();
- expect(page3Renamed).toBeTruthy();
- expect(page2Renamed?.parent).toStrictEqual(_pageD?._id);
- expect(page3Renamed?.parent).toStrictEqual(page2Renamed?._id);
- expect(normalizeGrantedGroups(page2Renamed?.grantedGroups)).toStrictEqual(
- normalizeGrantedGroups(_page2?.grantedGroups),
- );
- expect(normalizeGrantedGroups(page3Renamed?.grantedGroups)).toStrictEqual(
- normalizeGrantedGroups(_page3?.grantedGroups),
- );
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- });
- test('Should throw with NOT grant normalized pages', async () => {
- const _pathD = '/np_rename4_destination';
- const _path2 = '/np_rename5';
- const _path3 = '/np_rename5/np_rename6';
- const _propertiesD = {
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdIsolate } },
- };
- const _properties2 = {
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- };
- const _properties3 = {
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- };
- const _pageD = await Page.findOne({ path: _pathD, ..._propertiesD }); // isolate
- const _page2 = await Page.findOne({ path: _path2, ..._properties2 }); // groupIdB
- const _page3 = await Page.findOne({
- path: _path3,
- ..._properties3,
- parent: _page2,
- }); // groupIdB
- expect(_pageD).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- const newPathForPage2 = '/np_rename4_destination/np_rename5';
- const newPathForPage3 = '/np_rename4_destination/np_rename5/np_rename6';
- let isThrown = false;
- try {
- await renamePage(
- _page2,
- newPathForPage2,
- dummyUser1,
- {},
- {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- activityId: '62e291bc10e0ab61bd691794',
- },
- );
- } catch (err) {
- isThrown = true;
- }
- expect(isThrown).toBe(true);
- const page2 = await Page.findOne({ path: _path2 }); // not renamed thus exist
- const page3 = await Page.findOne({ path: _path3 }); // not renamed thus exist
- const page2Renamed = await Page.findOne({ path: newPathForPage2 }); // not exist
- const page3Renamed = await Page.findOne({ path: newPathForPage3 }); // not exist
- expect(page2).toBeTruthy();
- expect(page3).toBeTruthy();
- expect(page2Renamed).toBeNull();
- expect(page3Renamed).toBeNull();
- });
- test('Should rename/move multiple pages: child page with GRANT_RESTRICTED should NOT be renamed.', async () => {
- const _pathD = '/np_rename7_destination';
- const _path2 = '/np_rename8';
- const _path3 = '/np_rename8/np_rename9';
- const _pageD = await Page.findOne({
- path: _pathD,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdIsolate } },
- });
- const _page2 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_RESTRICTED,
- });
- const _page3 = await Page.findOne({
- path: _path3,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(_pageD).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- const newPathForPage2 = '/np_rename7_destination/np_rename8';
- const newpathForPage3 = '/np_rename7_destination/np_rename8/np_rename9';
- await renamePage(
- _page2,
- newPathForPage2,
- npDummyUser1,
- { isRecursively: true },
- {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- activityId: '62e291bc10e0ab61bd691794',
- },
- );
- const page2 = await Page.findOne({ path: _path2 }); // not exist
- const page3 = await Page.findOne({ path: _path3 }); // not renamed thus exist
- const page2Renamed = await Page.findOne({ path: newPathForPage2 }); // exist
- const page3Renamed = await Page.findOne({ path: newpathForPage3 }); // not exist
- expect(page2).toBeNull();
- expect(page3).toBeTruthy();
- expect(page2Renamed).toBeTruthy();
- expect(page3Renamed).toBeNull();
- expect(page2Renamed?.parent).toBeNull();
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- });
- });
- describe('Duplicate', () => {
- const duplicate = async (
- page,
- newPagePath: string,
- user,
- isRecursively: boolean,
- onlyDuplicateUserRelatedResources: boolean,
- ) => {
- // mock return value
- const mockedDuplicateRecursivelyMainOperation = jest
- .spyOn(crowi.pageService, 'duplicateRecursivelyMainOperation')
- .mockReturnValue(null);
- const duplicatedPage = await crowi.pageService.duplicate(
- page,
- newPagePath,
- user,
- isRecursively,
- onlyDuplicateUserRelatedResources,
- );
- // retrieve the arguments passed when calling method duplicateRecursivelyMainOperation inside duplicate method
- const argsForDuplicateRecursivelyMainOperation =
- mockedDuplicateRecursivelyMainOperation.mock.calls[0];
- // restores the original implementation
- mockedDuplicateRecursivelyMainOperation.mockRestore();
- // duplicate descendants
- if (page.grant !== Page.GRANT_RESTRICTED && isRecursively) {
- await crowi.pageService.duplicateRecursivelyMainOperation(
- ...(argsForDuplicateRecursivelyMainOperation as Parameters<
- typeof crowi.pageService.duplicateRecursivelyMainOperation
- >),
- );
- }
- return duplicatedPage;
- };
- test('Duplicate single page with GRANT_RESTRICTED', async () => {
- const _page = await Page.findOne({
- path: '/np_duplicate1',
- grant: Page.GRANT_RESTRICTED,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _revision = _page?.revision;
- expect(_page).toBeTruthy();
- expect(_revision).toBeTruthy();
- const newPagePath = '/dup_np_duplicate1';
- await duplicate(_page, newPagePath, npDummyUser1, false, false);
- const duplicatedPage = await Page.findOne({ path: newPagePath });
- const duplicatedRevision = await Revision.findOne({
- pageId: duplicatedPage?._id,
- });
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- expect(duplicatedPage).toBeTruthy();
- expect(duplicatedPage?._id).not.toStrictEqual(_page?._id);
- expect(duplicatedPage?.grant).toBe(_page?.grant);
- expect(duplicatedPage?.parent).toBeNull();
- expect(duplicatedPage?.parent).toStrictEqual(_page?.parent);
- expect(duplicatedPage?.revision).toStrictEqual(duplicatedRevision?._id);
- expect(duplicatedRevision?.body).toBe(_revision?.body);
- });
- test('Should duplicate multiple pages with GRANT_USER_GROUP', async () => {
- const _path1 = '/np_duplicate2';
- const _path2 = '/np_duplicate2/np_duplicate3';
- const _page1 = await Page.findOne({
- path: _path1,
- parent: rootPage._id,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _page2 = await Page.findOne({
- path: _path2,
- parent: _page1?._id,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _revision1 = _page1?.revision;
- const _revision2 = _page2?.revision;
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_revision1).toBeTruthy();
- expect(_revision2).toBeTruthy();
- const newPagePath = '/dup_np_duplicate2';
- await duplicate(_page1, newPagePath, npDummyUser2, true, false);
- const duplicatedPage1 = await Page.findOne({
- path: newPagePath,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage2 = await Page.findOne({
- path: '/dup_np_duplicate2/np_duplicate3',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedRevision1 = duplicatedPage1?.revision;
- const duplicatedRevision2 = duplicatedPage2?.revision;
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- expect(duplicatedPage1).toBeTruthy();
- expect(duplicatedPage2).toBeTruthy();
- expect(duplicatedRevision1).toBeTruthy();
- expect(duplicatedRevision2).toBeTruthy();
- expect(
- normalizeGrantedGroups(duplicatedPage1?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ]);
- expect(
- normalizeGrantedGroups(duplicatedPage2?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ]);
- expect(duplicatedPage1?.parent).toStrictEqual(_page1?.parent);
- expect(duplicatedPage2?.parent).toStrictEqual(duplicatedPage1?._id);
- expect(duplicatedRevision1?.body).toBe(_revision1?.body);
- expect(duplicatedRevision2?.body).toBe(_revision2?.body);
- expect(duplicatedRevision1?.pageId).toStrictEqual(duplicatedPage1?._id);
- expect(duplicatedRevision2?.pageId).toStrictEqual(duplicatedPage2?._id);
- });
- test('Should duplicate multiple pages. Page with GRANT_RESTRICTED should NOT be duplicated', async () => {
- const _path1 = '/np_duplicate4';
- const _path2 = '/np_duplicate4/np_duplicate5';
- const _path3 = '/np_duplicate4/np_duplicate6';
- const _page1 = await Page.findOne({
- path: _path1,
- parent: rootPage._id,
- grant: Page.GRANT_PUBLIC,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _page2 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_RESTRICTED,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _page3 = await Page.findOne({
- path: _path3,
- grant: Page.GRANT_PUBLIC,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const baseRevision1 = _page1?.revision;
- const baseRevision2 = _page2?.revision;
- const baseRevision3 = _page3?.revision;
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- expect(baseRevision1).toBeTruthy();
- expect(baseRevision2).toBeTruthy();
- const newPagePath = '/dup_np_duplicate4';
- await duplicate(_page1, newPagePath, npDummyUser1, true, false);
- const duplicatedPage1 = await Page.findOne({
- path: newPagePath,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage2 = await Page.findOne({
- path: '/dup_np_duplicate4/np_duplicate5',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage3 = await Page.findOne({
- path: '/dup_np_duplicate4/np_duplicate6',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedRevision1 = duplicatedPage1?.revision;
- const duplicatedRevision3 = duplicatedPage3?.revision;
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- expect(duplicatedPage1).toBeTruthy();
- expect(duplicatedPage2).toBeNull();
- expect(duplicatedPage3).toBeTruthy();
- expect(duplicatedRevision1).toBeTruthy();
- expect(duplicatedRevision3).toBeTruthy();
- expect(duplicatedPage1?.grant).toStrictEqual(Page.GRANT_PUBLIC);
- expect(duplicatedPage3?.grant).toStrictEqual(Page.GRANT_PUBLIC);
- expect(duplicatedPage1?.parent).toStrictEqual(_page1?.parent);
- expect(duplicatedPage3?.parent).toStrictEqual(duplicatedPage1?._id);
- expect(duplicatedRevision1?.body).toBe(baseRevision1?.body);
- expect(duplicatedRevision3?.body).toBe(baseRevision3?.body);
- expect(duplicatedRevision1?.pageId).toStrictEqual(duplicatedPage1?._id);
- expect(duplicatedRevision3?.pageId).toStrictEqual(duplicatedPage3?._id);
- });
- test('Should duplicate only user related pages and granted groups when onlyDuplicateUserRelatedResources is true', async () => {
- const _path1 = '/np_duplicate7';
- const _path2 = '/np_duplicate7/np_duplicate8';
- const _path3 = '/np_duplicate7/np_duplicate9';
- const _page1 = await Page.findOne({
- path: _path1,
- parent: rootPage._id,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _page2 = await Page.findOne({ path: _path2, parent: _page1?._id });
- const _page3 = await Page.findOne({ path: _path3, parent: _page1?._id });
- const _revision1 = _page1?.revision;
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- expect(_revision1).toBeTruthy();
- const newPagePath = '/dup_np_duplicate7';
- await duplicate(_page1, newPagePath, npDummyUser1, true, true);
- const duplicatedPage1 = await Page.findOne({
- path: newPagePath,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage2 = await Page.findOne({
- path: '/dup_np_duplicate7/np_duplicate8',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage3 = await Page.findOne({
- path: '/dup_np_duplicate7/np_duplicate9',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedRevision1 = duplicatedPage1?.revision;
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- expect(duplicatedPage1).toBeTruthy();
- expect(duplicatedPage2).toBeFalsy();
- expect(duplicatedPage3).toBeFalsy();
- expect(duplicatedRevision1).toBeTruthy();
- expect(
- normalizeGrantedGroups(duplicatedPage1?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ]);
- expect(duplicatedPage1?.parent).toStrictEqual(_page1?.parent);
- expect(duplicatedRevision1?.body).toBe(_revision1?.body);
- expect(duplicatedRevision1?.pageId).toStrictEqual(duplicatedPage1?._id);
- });
- test('Should duplicate all pages and granted groups when onlyDuplicateUserRelatedResources is false', async () => {
- const _path1 = '/np_duplicate7';
- const _path2 = '/np_duplicate7/np_duplicate8';
- const _path3 = '/np_duplicate7/np_duplicate9';
- const _page1 = await Page.findOne({
- path: _path1,
- parent: rootPage._id,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _page2 = await Page.findOne({
- path: _path2,
- parent: _page1?._id,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _page3 = await Page.findOne({
- path: _path3,
- parent: _page1?._id,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const _revision1 = _page1?.revision;
- const _revision2 = _page2?.revision;
- const _revision3 = _page3?.revision;
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- expect(_revision1).toBeTruthy();
- expect(_revision2).toBeTruthy();
- expect(_revision3).toBeTruthy();
- const newPagePath = '/dup2_np_duplicate7';
- await duplicate(_page1, newPagePath, npDummyUser1, true, false);
- const duplicatedPage1 = await Page.findOne({
- path: newPagePath,
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage2 = await Page.findOne({
- path: '/dup2_np_duplicate7/np_duplicate8',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedPage3 = await Page.findOne({
- path: '/dup2_np_duplicate7/np_duplicate9',
- }).populate<{ revision: IRevisionDocument }>({
- path: 'revision',
- model: 'Revision',
- });
- const duplicatedRevision1 = duplicatedPage1?.revision;
- const duplicatedRevision2 = duplicatedPage2?.revision;
- const duplicatedRevision3 = duplicatedPage3?.revision;
- expect(generalXssFilterProcessSpy).toHaveBeenCalled();
- expect(duplicatedPage1).toBeTruthy();
- expect(duplicatedPage2).toBeTruthy();
- expect(duplicatedPage3).toBeTruthy();
- expect(duplicatedRevision1).toBeTruthy();
- expect(duplicatedRevision2).toBeTruthy();
- expect(duplicatedRevision3).toBeTruthy();
- expect(
- normalizeGrantedGroups(duplicatedPage1?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ]);
- expect(duplicatedPage1?.parent).toStrictEqual(_page1?.parent);
- expect(duplicatedRevision1?.body).toBe(_revision1?.body);
- expect(duplicatedRevision1?.pageId).toStrictEqual(duplicatedPage1?._id);
- expect(
- normalizeGrantedGroups(duplicatedPage2?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdC, type: GroupType.userGroup },
- { item: externalGroupIdC, type: GroupType.externalUserGroup },
- ]);
- expect(duplicatedPage2?.parent).toStrictEqual(duplicatedPage1?._id);
- expect(duplicatedRevision2?.body).toBe(_revision2?.body);
- expect(duplicatedRevision2?.pageId).toStrictEqual(duplicatedPage2?._id);
- expect(duplicatedPage3?.grantedUsers).toStrictEqual([npDummyUser2?._id]);
- expect(duplicatedPage3?.parent).toStrictEqual(duplicatedPage1?._id);
- expect(duplicatedRevision3?.body).toBe(_revision3?.body);
- expect(duplicatedRevision3?.pageId).toStrictEqual(duplicatedPage3?._id);
- });
- });
- describe('Delete', () => {
- const deletePage = async (
- page,
- user,
- options,
- isRecursively,
- activityParameters?,
- ) => {
- const mockedDeleteRecursivelyMainOperation = jest
- .spyOn(crowi.pageService, 'deleteRecursivelyMainOperation')
- .mockReturnValue(null);
- const deletedPage = await crowi.pageService.deletePage(
- page,
- user,
- options,
- isRecursively,
- activityParameters,
- );
- const argsForDeleteRecursivelyMainOperation =
- mockedDeleteRecursivelyMainOperation.mock.calls[0];
- mockedDeleteRecursivelyMainOperation.mockRestore();
- if (isRecursively) {
- await crowi.pageService.deleteRecursivelyMainOperation(
- ...(argsForDeleteRecursivelyMainOperation as Parameters<
- typeof crowi.pageService.deleteRecursivelyMainOperation
- >),
- );
- }
- return deletedPage;
- };
- describe('Delete single page with grant RESTRICTED', () => {
- test('should be able to delete', async () => {
- const _pathT = '/npdel1_awl';
- const _pageT = await Page.findOne({
- path: _pathT,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(_pageT).toBeTruthy();
- const isRecursively = false;
- await deletePage(_pageT, dummyUser1, {}, isRecursively, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const pageT = await Page.findOne({ path: `/trash${_pathT}` });
- const pageN = await Page.findOne({ path: _pathT }); // should not exist
- expect(pageT).toBeTruthy();
- expect(pageN).toBeNull();
- expect(pageT?.grant).toBe(Page.GRANT_RESTRICTED);
- expect(pageT?.status).toBe(Page.STATUS_DELETED);
- });
- });
- describe('Delete single page with grant USER_GROUP', () => {
- test('should be able to delete', async () => {
- const _path = '/npdel2_ug';
- const _page1 = await Page.findOne({
- path: _path,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- expect(_page1).toBeTruthy();
- const isRecursively = false;
- await deletePage(_page1, npDummyUser1, {}, isRecursively, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const pageN = await Page.findOne({
- path: _path,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- const page1 = await Page.findOne({
- path: `/trash${_path}`,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- expect(pageN).toBeNull();
- expect(page1).toBeTruthy();
- expect(page1?.status).toBe(Page.STATUS_DELETED);
- expect(page1?.descendantCount).toBe(0);
- expect(page1?.parent).toBeNull();
- });
- });
- describe('Delete multiple pages with grant USER_GROUP', () => {
- test('should be able to delete all descendants except page with GRANT_RESTRICTED', async () => {
- const _pathT = '/npdel3_top';
- const _path1 = '/npdel3_top/npdel4_ug';
- const _path2 = '/npdel3_top/npdel4_ug/npdel5_ug';
- const _pageT = await Page.findOne({
- path: _pathT,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- }); // A
- const _page1 = await Page.findOne({
- path: _path1,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- }); // B
- const _page2 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdC } },
- }); // C
- const _pageR = await Page.findOne({
- path: _path1,
- grant: Page.GRANT_RESTRICTED,
- }); // Restricted
- expect(_pageT).toBeTruthy();
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_pageR).toBeTruthy();
- const isRecursively = true;
- await deletePage(_pageT, npDummyUser1, {}, isRecursively, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const pageTNotExist = await Page.findOne({
- path: _pathT,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- }); // A should not exist
- const page1NotExist = await Page.findOne({
- path: _path1,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- }); // B should not exist
- const page2NotExist = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdC } },
- }); // C should not exist
- const pageT = await Page.findOne({
- path: `/trash${_pathT}`,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- }); // A
- const page1 = await Page.findOne({
- path: `/trash${_path1}`,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- }); // B
- const page2 = await Page.findOne({
- path: `/trash${_path2}`,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdC } },
- }); // C
- const pageR = await Page.findOne({
- path: _path1,
- grant: Page.GRANT_RESTRICTED,
- }); // Restricted
- expect(page1NotExist).toBeNull();
- expect(pageTNotExist).toBeNull();
- expect(page2NotExist).toBeNull();
- expect(pageT).toBeTruthy();
- expect(page1).toBeTruthy();
- expect(page2).toBeTruthy();
- expect(pageR).toBeTruthy();
- expect(pageT?.status).toBe(Page.STATUS_DELETED);
- expect(pageT?.status).toBe(Page.STATUS_DELETED);
- expect(page1?.status).toBe(Page.STATUS_DELETED);
- expect(page1?.descendantCount).toBe(0);
- expect(page2?.descendantCount).toBe(0);
- expect(page2?.descendantCount).toBe(0);
- expect(pageT?.parent).toBeNull();
- expect(page1?.parent).toBeNull();
- expect(page2?.parent).toBeNull();
- });
- });
- });
- describe('Delete completely', () => {
- const deleteCompletely = async (
- page,
- user,
- options = {},
- isRecursively = false,
- preventEmitting = false,
- activityParameters?,
- ) => {
- const mockedDeleteCompletelyRecursivelyMainOperation = jest
- .spyOn(crowi.pageService, 'deleteCompletelyRecursivelyMainOperation')
- .mockReturnValue(null);
- await crowi.pageService.deleteCompletely(
- page,
- user,
- options,
- isRecursively,
- preventEmitting,
- activityParameters,
- );
- const argsForDeleteCompletelyRecursivelyMainOperation =
- mockedDeleteCompletelyRecursivelyMainOperation.mock.calls[0];
- mockedDeleteCompletelyRecursivelyMainOperation.mockRestore();
- if (isRecursively) {
- await crowi.pageService.deleteCompletelyRecursivelyMainOperation(
- ...(argsForDeleteCompletelyRecursivelyMainOperation as Parameters<
- typeof crowi.pageService.deleteCompletelyRecursivelyMainOperation
- >),
- );
- }
- return;
- };
- describe('Delete single page with grant RESTRICTED', () => {
- test('should be able to delete completely', async () => {
- const _path = '/npdc1_awl';
- const _page = await Page.findOne({
- path: _path,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(_page).toBeTruthy();
- await deleteCompletely(_page, dummyUser1, {}, false, false, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const page = await Page.findOne({
- path: _path,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(page).toBeNull();
- });
- });
- describe('Delete single page with grant USER_GROUP', () => {
- test('should be able to delete completely', async () => {
- const _path = '/npdc2_ug';
- const _page = await Page.findOne({
- path: _path,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- expect(_page).toBeTruthy();
- await deleteCompletely(_page, npDummyUser1, {}, false, false, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const page = await Page.findOne({
- path: _path,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- expect(page).toBeNull();
- });
- });
- describe('Delete multiple pages with grant USER_GROUP', () => {
- test('should be able to delete all descendants completely except page with GRANT_RESTRICTED', async () => {
- const _path1 = '/npdc3_ug';
- const _path2 = '/npdc3_ug/npdc4_ug';
- const _path3 = '/npdc3_ug/npdc4_ug/npdc5_ug';
- const _page1 = await Page.findOne({
- path: _path1,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- const _page2 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- });
- const _page3 = await Page.findOne({
- path: _path3,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdC } },
- });
- const _page4 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(_page1).toBeTruthy();
- expect(_page2).toBeTruthy();
- expect(_page3).toBeTruthy();
- expect(_page4).toBeTruthy();
- await deleteCompletely(_page1, npDummyUser1, {}, true, false, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const page1 = await Page.findOne({
- path: _path1,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- const page2 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- });
- const page3 = await Page.findOne({
- path: _path3,
- grant: Page.GRANT_USER_GROUP,
- grantedGroups: { $elemMatch: { item: groupIdC } },
- });
- const page4 = await Page.findOne({
- path: _path2,
- grant: Page.GRANT_RESTRICTED,
- });
- expect(page1).toBeNull();
- expect(page2).toBeNull();
- expect(page3).toBeNull();
- expect(page4).toBeTruthy();
- });
- });
- });
- describe('revert', () => {
- const revertDeletedPage = async (
- page,
- user,
- options = {},
- isRecursively = false,
- activityParameters?,
- ) => {
- // mock return value
- const mockedRevertRecursivelyMainOperation = jest
- .spyOn(crowi.pageService, 'revertRecursivelyMainOperation')
- .mockReturnValue(null);
- const revertedPage = await crowi.pageService.revertDeletedPage(
- page,
- user,
- options,
- isRecursively,
- activityParameters,
- );
- const argsForRecursivelyMainOperation =
- mockedRevertRecursivelyMainOperation.mock.calls[0];
- // restores the original implementation
- mockedRevertRecursivelyMainOperation.mockRestore();
- if (isRecursively) {
- await crowi.pageService.revertRecursivelyMainOperation(
- ...(argsForRecursivelyMainOperation as Parameters<
- typeof crowi.pageService.revertRecursivelyMainOperation
- >),
- );
- }
- return revertedPage;
- };
- test('should revert single deleted page with GRANT_RESTRICTED', async () => {
- const trashedPage = await Page.findOne({
- path: '/trash/np_revert1',
- status: Page.STATUS_DELETED,
- grant: Page.GRANT_RESTRICTED,
- });
- const revision = await Revision.findOne({ pageId: trashedPage?._id });
- const tag = await Tag.findOne({ name: 'np_revertTag1' });
- const deletedPageTagRelation = await PageTagRelation.findOne({
- relatedPage: trashedPage?._id,
- relatedTag: tag?._id,
- isPageTrashed: true,
- });
- expect(trashedPage).toBeTruthy();
- expect(revision).toBeTruthy();
- expect(tag).toBeTruthy();
- expect(deletedPageTagRelation).toBeTruthy();
- await revertDeletedPage(trashedPage, dummyUser1, {}, false, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/rename',
- });
- const revertedPage = await Page.findOne({ path: '/np_revert1' });
- const deltedPageBeforeRevert = await Page.findOne({
- path: '/trash/np_revert1',
- });
- const pageTagRelation = await PageTagRelation.findOne<IPageTagRelation>({
- relatedPage: revertedPage?._id,
- relatedTag: tag?._id,
- });
- expect(revertedPage).toBeTruthy();
- expect(pageTagRelation).toBeTruthy();
- expect(deltedPageBeforeRevert).toBeNull();
- // page with GRANT_RESTRICTED does not have parent
- expect(revertedPage?.parent).toBeNull();
- expect(revertedPage?.status).toBe(Page.STATUS_PUBLISHED);
- expect(revertedPage?.grant).toBe(Page.GRANT_RESTRICTED);
- expect(pageTagRelation?.isPageTrashed).toBe(false);
- });
- test('should revert single deleted page with GRANT_USER_GROUP', async () => {
- const beforeRevertPath = '/trash/np_revert2';
- const user1 = await User.findOne({ name: 'npUser1' });
- const trashedPage = await Page.findOne({
- path: beforeRevertPath,
- status: Page.STATUS_DELETED,
- grant: Page.GRANT_USER_GROUP,
- });
- const revision = await Revision.findOne({ pageId: trashedPage?._id });
- const tag = await Tag.findOne({ name: 'np_revertTag2' });
- const deletedPageTagRelation = await PageTagRelation.findOne({
- relatedPage: trashedPage?._id,
- relatedTag: tag?._id,
- isPageTrashed: true,
- });
- expect(trashedPage).toBeTruthy();
- expect(revision).toBeTruthy();
- expect(tag).toBeTruthy();
- expect(deletedPageTagRelation).toBeTruthy();
- await revertDeletedPage(trashedPage, user1, {}, false, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/revert',
- });
- const revertedPage = await Page.findOne({ path: '/np_revert2' });
- const trashedPageBR = await Page.findOne({ path: beforeRevertPath });
- const pageTagRelation = await PageTagRelation.findOne<IPageTagRelation>({
- relatedPage: revertedPage?._id,
- relatedTag: tag?._id,
- });
- expect(revertedPage).toBeTruthy();
- expect(pageTagRelation).toBeTruthy();
- expect(trashedPageBR).toBeNull();
- expect(revertedPage?.parent).toStrictEqual(rootPage._id);
- expect(revertedPage?.status).toBe(Page.STATUS_PUBLISHED);
- expect(revertedPage?.grant).toBe(Page.GRANT_USER_GROUP);
- expect(normalizeGrantedGroups(revertedPage?.grantedGroups)).toStrictEqual(
- [
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ],
- );
- expect(pageTagRelation?.isPageTrashed).toBe(false);
- });
- test(`revert multiple pages: only target page should be reverted.
- Non-existant middle page and leaf page with GRANT_RESTRICTED shoud not be reverted`, async () => {
- const beforeRevertPath1 = '/trash/np_revert3';
- const beforeRevertPath2 = '/trash/np_revert3/middle/np_revert4';
- const trashedPage1 = await Page.findOne({
- path: beforeRevertPath1,
- status: Page.STATUS_DELETED,
- grant: Page.GRANT_PUBLIC,
- });
- const trashedPage2 = await Page.findOne({
- path: beforeRevertPath2,
- status: Page.STATUS_DELETED,
- grant: Page.GRANT_RESTRICTED,
- });
- const revision1 = await Revision.findOne({ pageId: trashedPage1?._id });
- const revision2 = await Revision.findOne({ pageId: trashedPage2?._id });
- expect(trashedPage1).toBeTruthy();
- expect(trashedPage2).toBeTruthy();
- expect(revision1).toBeTruthy();
- expect(revision2).toBeTruthy();
- await revertDeletedPage(trashedPage1, npDummyUser2, {}, true, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/revert',
- });
- const revertedPage = await Page.findOne({ path: '/np_revert3' });
- const middlePage = await Page.findOne({ path: '/np_revert3/middle' });
- const notRestrictedPage = await Page.findOne({
- path: '/np_revert3/middle/np_revert4',
- });
- // AR => After Revert
- const trashedPage1AR = await Page.findOne({ path: beforeRevertPath1 });
- const trashedPage2AR = await Page.findOne({ path: beforeRevertPath2 });
- const revision1AR = await Revision.findOne({ pageId: revertedPage?._id });
- const revision2AR = await Revision.findOne({
- pageId: trashedPage2AR?._id,
- });
- expect(revertedPage).toBeTruthy();
- expect(trashedPage2AR).toBeTruthy();
- expect(revision1AR).toBeTruthy();
- expect(revision2AR).toBeTruthy();
- expect(trashedPage1AR).toBeNull();
- expect(notRestrictedPage).toBeNull();
- expect(middlePage).toBeNull();
- expect(revertedPage?.parent).toStrictEqual(rootPage._id);
- expect(revertedPage?.status).toBe(Page.STATUS_PUBLISHED);
- expect(revertedPage?.grant).toBe(Page.GRANT_PUBLIC);
- });
- test('revert multiple pages: target page, initially non-existant page and leaf page with GRANT_USER_GROUP shoud be reverted', async () => {
- const user = await User.findOne({ _id: npDummyUser3 });
- const beforeRevertPath1 = '/trash/np_revert5';
- const beforeRevertPath2 = '/trash/np_revert5/middle/np_revert6';
- const beforeRevertPath3 = '/trash/np_revert5/middle';
- const trashedPage1 = await Page.findOne({
- path: beforeRevertPath1,
- status: Page.STATUS_DELETED,
- grantedGroups: { $elemMatch: { item: groupIdA } },
- });
- const trashedPage2 = await Page.findOne({
- path: beforeRevertPath2,
- status: Page.STATUS_DELETED,
- grantedGroups: { $elemMatch: { item: groupIdB } },
- });
- const nonExistantPage3 = await Page.findOne({ path: beforeRevertPath3 }); // not exist
- const revision1 = await Revision.findOne({ pageId: trashedPage1?._id });
- const revision2 = await Revision.findOne({ pageId: trashedPage2?._id });
- expect(trashedPage1).toBeTruthy();
- expect(trashedPage2).toBeTruthy();
- expect(revision1).toBeTruthy();
- expect(revision2).toBeTruthy();
- expect(user).toBeTruthy();
- expect(nonExistantPage3).toBeNull();
- await revertDeletedPage(trashedPage1, user, {}, true, {
- ip: '::ffff:127.0.0.1',
- endpoint: '/_api/v3/pages/revert',
- });
- const revertedPage1 = await Page.findOne({ path: '/np_revert5' });
- const newlyCreatedPage = await Page.findOne({
- path: '/np_revert5/middle',
- });
- const revertedPage2 = await Page.findOne({
- path: '/np_revert5/middle/np_revert6',
- });
- // // AR => After Revert
- const trashedPage1AR = await Page.findOne({ path: beforeRevertPath1 });
- const trashedPage2AR = await Page.findOne({ path: beforeRevertPath2 });
- expect(revertedPage1).toBeTruthy();
- expect(newlyCreatedPage).toBeTruthy();
- expect(revertedPage2).toBeTruthy();
- expect(trashedPage1AR).toBeNull();
- expect(trashedPage2AR).toBeNull();
- expect(newlyCreatedPage?.isEmpty).toBe(true);
- expect(revertedPage1?.parent).toStrictEqual(rootPage._id);
- expect(revertedPage2?.parent).toStrictEqual(newlyCreatedPage?._id);
- expect(newlyCreatedPage?.parent).toStrictEqual(revertedPage1?._id);
- expect(revertedPage1?.status).toBe(Page.STATUS_PUBLISHED);
- expect(revertedPage2?.status).toBe(Page.STATUS_PUBLISHED);
- expect(newlyCreatedPage?.status).toBe(Page.STATUS_PUBLISHED);
- expect(
- normalizeGrantedGroups(revertedPage1?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdA, type: GroupType.userGroup },
- { item: externalGroupIdA, type: GroupType.externalUserGroup },
- ]);
- expect(
- normalizeGrantedGroups(revertedPage2?.grantedGroups),
- ).toStrictEqual([
- { item: groupIdB, type: GroupType.userGroup },
- { item: externalGroupIdB, type: GroupType.externalUserGroup },
- ]);
- expect(newlyCreatedPage?.grant).toBe(Page.GRANT_PUBLIC);
- });
- });
- });
|