Yuki Takei 2 месяцев назад
Родитель
Сommit
b4166f3c80

+ 107 - 58
apps/app/test/integration/service/page-grant.test.ts → apps/app/src/server/service/page/page-grant.integ.ts

@@ -1,20 +1,20 @@
 import { GroupType, type IPage, PageGrant } from '@growi/core';
 import mongoose from 'mongoose';
+import { beforeAll, describe, expect, it } from 'vitest';
 
-import { ExternalGroupProviderType } from '../../../src/features/external-user-group/interfaces/external-user-group';
+import { getInstance } from '^/test-with-vite/setup/crowi';
+
+import { ExternalGroupProviderType } from '~/features/external-user-group/interfaces/external-user-group';
 import ExternalUserGroup, {
   type ExternalUserGroupDocument,
-} 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 { UserGroupPageGrantStatus } from '../../../src/interfaces/page';
-import type Crowi from '../../../src/server/crowi';
-import type { PageDocument, PageModel } from '../../../src/server/models/page';
-import UserGroup, {
-  type UserGroupDocument,
-} from '../../../src/server/models/user-group';
-import UserGroupRelation from '../../../src/server/models/user-group-relation';
-import type { IPageGrantService } from '../../../src/server/service/page-grant';
-import { getInstance } from '../setup-crowi';
+} from '~/features/external-user-group/server/models/external-user-group';
+import ExternalUserGroupRelation from '~/features/external-user-group/server/models/external-user-group-relation';
+import { UserGroupPageGrantStatus } from '~/interfaces/page';
+import type Crowi from '~/server/crowi';
+import type { PageDocument, PageModel } from '~/server/models/page';
+import UserGroup, { type UserGroupDocument } from '~/server/models/user-group';
+import UserGroupRelation from '~/server/models/user-group-relation';
+import type { IPageGrantService } from '~/server/service/page-grant';
 
 /*
  * There are 3 grant types to test.
@@ -24,8 +24,8 @@ describe('PageGrantService', () => {
   /*
    * models
    */
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let User;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let User: any;
   let Page: PageModel;
 
   /*
@@ -34,10 +34,10 @@ describe('PageGrantService', () => {
   let crowi: Crowi;
   let pageGrantService: IPageGrantService;
 
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let user1;
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let user2;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let user1: any;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let user2: any;
 
   let groupParent: UserGroupDocument;
   let groupChild: UserGroupDocument;
@@ -88,8 +88,8 @@ describe('PageGrantService', () => {
   const pageE3User1Path = '/E3/User1';
 
   // getPageGroupGrantData test data
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let user3;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let user3: any;
   let groupGrantDataTestChildPagePath: string;
   let groupGrantDataTestParentUserGroupId: mongoose.Types.ObjectId;
   let groupGrantDataTestChildUserGroupId: mongoose.Types.ObjectId;
@@ -522,18 +522,33 @@ describe('PageGrantService', () => {
     User = mongoose.model('User');
     Page = mongoose.model<IPage, PageModel>('Page');
 
-    rootPage = (await Page.findOne({ path: '/' }))!;
+    // Ensure root page exists (required for page hierarchy)
+    rootPage = await Page.findOne({ path: '/' });
+    if (rootPage == null) {
+      const rootPageId = new mongoose.Types.ObjectId();
+      await Page.insertMany([
+        {
+          _id: rootPageId,
+          path: '/',
+          grant: Page.GRANT_PUBLIC,
+        },
+      ]);
+      rootPage = (await Page.findOne({ path: '/' }))!;
+    }
 
     await createDocumentsToTestIsGrantNormalized();
     await createDocumentsToTestGetPageGroupGrantData();
   });
 
   describe('Test isGrantNormalized method with shouldCheckDescendants false', () => {
-    test('Should return true when Ancestor: root, Target: public', async () => {
+    it('Should return true when Ancestor: root, Target: public', async () => {
       const targetPath = '/NEW';
       const grant = Page.GRANT_PUBLIC;
       const grantedUserIds = undefined;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = false;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -548,7 +563,7 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Ancestor: root, Target: GroupParent', async () => {
+    it('Should return true when Ancestor: root, Target: GroupParent', async () => {
       const targetPath = '/NEW_GroupParent';
       const grant = Page.GRANT_USER_GROUP;
       const grantedUserIds = undefined;
@@ -570,11 +585,14 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Ancestor: under-root public, Target: public', async () => {
+    it('Should return true when Ancestor: under-root public, Target: public', async () => {
       const targetPath = `${pageRootPublicPath}/NEW`;
       const grant = Page.GRANT_PUBLIC;
       const grantedUserIds = undefined;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = false;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -589,7 +607,7 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Ancestor: under-root GroupParent, Target: GroupParent', async () => {
+    it('Should return true when Ancestor: under-root GroupParent, Target: GroupParent', async () => {
       const targetPath = `${pageRootGroupParentPath}/NEW`;
       const grant = Page.GRANT_USER_GROUP;
       const grantedUserIds = undefined;
@@ -611,11 +629,14 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Ancestor: public, Target: public', async () => {
+    it('Should return true when Ancestor: public, Target: public', async () => {
       const targetPath = `${pageE1PublicPath}/NEW`;
       const grant = Page.GRANT_PUBLIC;
       const grantedUserIds = undefined;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = false;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -630,11 +651,14 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Ancestor: owned by User1, Target: owned by User1', async () => {
+    it('Should return true when Ancestor: owned by User1, Target: owned by User1', async () => {
       const targetPath = `${pageE2User1Path}/NEW`;
       const grant = Page.GRANT_OWNER;
       const grantedUserIds = [user1._id];
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = false;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -649,11 +673,14 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return false when Ancestor: owned by GroupParent, Target: public', async () => {
+    it('Should return false when Ancestor: owned by GroupParent, Target: public', async () => {
       const targetPath = `${pageE3GroupParentPath}/NEW`;
       const grant = Page.GRANT_PUBLIC;
       const grantedUserIds = undefined;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = false;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -668,7 +695,7 @@ describe('PageGrantService', () => {
       expect(result).toBe(false);
     });
 
-    test('Should return false when Ancestor: owned by GroupChild, Target: GroupParent', async () => {
+    it('Should return false when Ancestor: owned by GroupChild, Target: GroupParent', async () => {
       const targetPath = `${pageE3GroupChildPath}/NEW`;
       const grant = Page.GRANT_USER_GROUP;
       const grantedUserIds = undefined;
@@ -692,11 +719,14 @@ describe('PageGrantService', () => {
   });
 
   describe('Test isGrantNormalized method with shouldCheckDescendants true', () => {
-    test('Should return true when Target: public, Descendant: public', async () => {
+    it('Should return true when Target: public, Descendant: public', async () => {
       const targetPath = emptyPagePath1;
       const grant = Page.GRANT_PUBLIC;
       const grantedUserIds = undefined;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = true;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -711,11 +741,14 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Target: owned by User1, Descendant: User1 only', async () => {
+    it('Should return true when Target: owned by User1, Descendant: User1 only', async () => {
       const targetPath = emptyPagePath2;
       const grant = Page.GRANT_OWNER;
       const grantedUserIds = [user1._id];
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = true;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -730,7 +763,7 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return true when Target: owned by GroupParent, Descendant: GroupParent, GroupChild and User1', async () => {
+    it('Should return true when Target: owned by GroupParent, Descendant: GroupParent, GroupChild and User1', async () => {
       const targetPath = emptyPagePath3;
       const grant = Page.GRANT_USER_GROUP;
       const grantedUserIds = undefined;
@@ -752,11 +785,14 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return false when Target: owned by User1, Descendant: public', async () => {
+    it('Should return false when Target: owned by User1, Descendant: public', async () => {
       const targetPath = emptyPagePath1;
       const grant = Page.GRANT_OWNER;
       const grantedUserIds = [user1._id];
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
       const shouldCheckDescendants = true;
 
       const result = await pageGrantService.isGrantNormalized(
@@ -773,9 +809,12 @@ describe('PageGrantService', () => {
   });
 
   describe('Test validateGrantChange method', () => {
-    test('Should return true when Target: completely owned by User1 (belongs to all groups)', async () => {
+    it('Should return true when Target: completely owned by User1 (belongs to all groups)', async () => {
       const grant = Page.GRANT_PUBLIC;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
 
       const result = await pageGrantService.validateGrantChange(
         user1,
@@ -787,9 +826,12 @@ describe('PageGrantService', () => {
       expect(result).toBe(true);
     });
 
-    test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to public grant', async () => {
+    it('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to public grant', async () => {
       const grant = Page.GRANT_PUBLIC;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
 
       const result = await pageGrantService.validateGrantChange(
         user2,
@@ -801,9 +843,12 @@ describe('PageGrantService', () => {
       expect(result).toBe(false);
     });
 
-    test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to owner grant', async () => {
+    it('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to owner grant', async () => {
       const grant = Page.GRANT_OWNER;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
 
       const result = await pageGrantService.validateGrantChange(
         user2,
@@ -815,9 +860,12 @@ describe('PageGrantService', () => {
       expect(result).toBe(false);
     });
 
-    test('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to restricted grant', async () => {
+    it('Should return false when Target: partially owned by User2 (belongs to one of the groups), and change to restricted grant', async () => {
       const grant = Page.GRANT_RESTRICTED;
-      const grantedGroupIds = [];
+      const grantedGroupIds: {
+        item: mongoose.Types.ObjectId;
+        type: GroupType;
+      }[] = [];
 
       const result = await pageGrantService.validateGrantChange(
         user2,
@@ -829,7 +877,7 @@ describe('PageGrantService', () => {
       expect(result).toBe(false);
     });
 
-    test('Should return false when Target: partially owned by User2, and change to group grant without any groups of user2', async () => {
+    it('Should return false when Target: partially owned by User2, and change to group grant without any groups of user2', async () => {
       const grant = Page.GRANT_USER_GROUP;
       const grantedGroupIds = [
         { item: differentTreeGroup._id, type: GroupType.userGroup },
@@ -847,7 +895,7 @@ describe('PageGrantService', () => {
   });
 
   describe('Test for calcApplicableGrantData', () => {
-    test('Only Public is Applicable in case of top page', async () => {
+    it('Only Public is Applicable in case of top page', async () => {
       const result = await pageGrantService.calcApplicableGrantData(
         rootPage,
         user1,
@@ -859,7 +907,7 @@ describe('PageGrantService', () => {
     });
 
     // parent property of all private pages is null
-    test('Any grant is allowed if parent is null', async () => {
+    it('Any grant is allowed if parent is null', async () => {
       const userRelatedUserGroups =
         await UserGroupRelation.findAllGroupsForUser(user1);
       const userRelatedExternalUserGroups =
@@ -921,7 +969,7 @@ describe('PageGrantService', () => {
       });
     });
 
-    test('Any grant is allowed if parent is public', async () => {
+    it('Any grant is allowed if parent is public', async () => {
       const userRelatedUserGroups =
         await UserGroupRelation.findAllGroupsForUser(user1);
       const userRelatedExternalUserGroups =
@@ -983,7 +1031,7 @@ describe('PageGrantService', () => {
       });
     });
 
-    test('Only "GRANT_OWNER" is allowed if the user is the parent page\'s grantUser', async () => {
+    it('Only "GRANT_OWNER" is allowed if the user is the parent page\'s grantUser', async () => {
       // Public
       const onlyMePublicPage = await Page.findOne({
         path: pageOnlyMePublicPath,
@@ -1026,7 +1074,7 @@ describe('PageGrantService', () => {
       });
     });
 
-    test('"GRANT_OWNER" is not allowed if the user is not the parent page\'s grantUser', async () => {
+    it('"GRANT_OWNER" is not allowed if the user is not the parent page\'s grantUser', async () => {
       // Public
       const onlyMePublicPage = await Page.findOne({
         path: pageOnlyMePublicPath,
@@ -1066,7 +1114,7 @@ describe('PageGrantService', () => {
       });
     });
 
-    test('"GRANT_USER_GROUP" is allowed if the parent\'s grant is GRANT_USER_GROUP and the user is included in the group', async () => {
+    it('"GRANT_USER_GROUP" is allowed if the parent\'s grant is GRANT_USER_GROUP and the user is included in the group', async () => {
       const userGroups =
         await UserGroupRelation.findGroupsWithDescendantsByGroupAndUser(
           groupParent,
@@ -1132,8 +1180,9 @@ describe('PageGrantService', () => {
       });
     });
   });
+
   describe('Test for getPageGroupGrantData', () => {
-    test('return expected group grant data', async () => {
+    it('return expected group grant data', async () => {
       const groupGrantDataTestChildPage = await Page.findOne({
         path: groupGrantDataTestChildPagePath,
       });
@@ -1176,7 +1225,7 @@ describe('PageGrantService', () => {
       });
     });
 
-    test('return empty arrays when page is root', async () => {
+    it('return empty arrays when page is root', async () => {
       const result = await pageGrantService.getPageGroupGrantData(
         rootPage,
         user1,

+ 55 - 31
apps/app/test/integration/service/v5.page.test.ts → apps/app/src/server/service/page/v5.page.integ.ts

@@ -1,30 +1,29 @@
 import type { IPage } from '@growi/core';
 import { addSeconds } from 'date-fns/addSeconds';
 import mongoose from 'mongoose';
+import { beforeAll, describe, expect, it, vi } from 'vitest';
 
-import {
-  PageActionStage,
-  PageActionType,
-} from '../../../src/interfaces/page-operation';
-import type Crowi from '../../../src/server/crowi';
-import type { PageDocument, PageModel } from '../../../src/server/models/page';
+import { getInstance } from '^/test-with-vite/setup/crowi';
+
+import { PageActionStage, PageActionType } from '~/interfaces/page-operation';
+import type Crowi from '~/server/crowi';
+import type { PageDocument, PageModel } from '~/server/models/page';
 import type {
   IPageOperation,
   PageOperationModel,
-} from '../../../src/server/models/page-operation';
-import { getInstance } from '../setup-crowi';
+} from '~/server/models/page-operation';
 
 describe('Test page service methods', () => {
   let crowi: Crowi;
   let Page: PageModel;
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let User;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let User: any;
   let PageOperation: PageOperationModel;
 
   let rootPage: PageDocument;
 
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let dummyUser1;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let dummyUser1: any;
 
   let pageOpId1: mongoose.Types.ObjectId;
   let pageOpId2: mongoose.Types.ObjectId;
@@ -41,17 +40,32 @@ describe('Test page service methods', () => {
       'PageOperation',
     );
 
-    /*
-     * Common
-     */
-
-    // ***********************************************************************************************************
-    // * Do NOT change properties of globally used documents. Otherwise, it might cause some errors in other tests
-    // ***********************************************************************************************************
-    // users
+    // Ensure root page exists
+    rootPage = await Page.findOne({ path: '/' });
+    if (rootPage == null) {
+      const rootPageId = new mongoose.Types.ObjectId();
+      await Page.insertMany([
+        {
+          _id: rootPageId,
+          path: '/',
+          grant: Page.GRANT_PUBLIC,
+        },
+      ]);
+      rootPage = (await Page.findOne({ path: '/' }))!;
+    }
+
+    // Create dummy user for tests
+    const existingUser = await User.findOne({ username: 'v5DummyUser1' });
+    if (existingUser == null) {
+      await User.insertMany([
+        {
+          name: 'v5DummyUser1',
+          username: 'v5DummyUser1',
+          email: 'v5dummyuser1@example.com',
+        },
+      ]);
+    }
     dummyUser1 = await User.findOne({ username: 'v5DummyUser1' });
-    // page
-    rootPage = (await Page.findOne({ path: '/' }))!;
 
     /**
      * pages
@@ -460,10 +474,15 @@ describe('Test page service methods', () => {
   });
 
   describe('restart renameOperation', () => {
-    const resumeRenameSubOperation = async (renamePage, pageOp, activity?) => {
-      const mockedPathsAndDescendantCountOfAncestors = jest
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+    const resumeRenameSubOperation = async (
+      renamePage: any,
+      pageOp: any,
+      activity?: any,
+    ) => {
+      const mockedPathsAndDescendantCountOfAncestors = vi
         .spyOn(crowi.pageService, 'fixPathsAndDescendantCountOfAncestors')
-        .mockReturnValue(null);
+        .mockReturnValue(null as any);
       await crowi.pageService.resumeRenameSubOperation(
         renamePage,
         pageOp,
@@ -475,11 +494,12 @@ describe('Test page service methods', () => {
 
       mockedPathsAndDescendantCountOfAncestors.mockRestore();
       await crowi.pageService.fixPathsAndDescendantCountOfAncestors(
-        ...argsForRenameSubOperation,
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
+        ...(argsForRenameSubOperation as any),
       );
     };
 
-    test('it should successfully restart rename operation', async () => {
+    it('it should successfully restart rename operation', async () => {
       // paths before renaming
       const _path0 = '/resume_rename_0'; // out of renaming scope
       const _path1 = '/resume_rename_0/resume_rename_1'; // renamed already
@@ -551,7 +571,8 @@ describe('Test page service methods', () => {
       expect(page2?.descendantCount).toBe(1);
       expect(page3?.descendantCount).toBe(0);
     });
-    test('it should successfully restart rename operation when unprocessableExpiryDate is null', async () => {
+
+    it('it should successfully restart rename operation when unprocessableExpiryDate is null', async () => {
       // paths before renaming
       const _path0 = '/resume_rename_8'; // out of renaming scope
       const _path1 = '/resume_rename_8/resume_rename_9'; // renamed already
@@ -624,7 +645,8 @@ describe('Test page service methods', () => {
       expect(page1?.descendantCount).toBe(1);
       expect(page2?.descendantCount).toBe(0);
     });
-    test('it should fail and throw error if the current time is behind unprocessableExpiryDate', async () => {
+
+    it('it should fail and throw error if the current time is behind unprocessableExpiryDate', async () => {
       // path before renaming
       const _path0 = '/resume_rename_4'; // out of renaming scope
       const _path1 = '/resume_rename_4/resume_rename_5'; // renamed already
@@ -668,7 +690,8 @@ describe('Test page service methods', () => {
       // cleanup
       await PageOperation.findByIdAndDelete(pageOperation?._id);
     });
-    test('Missing property(toPath) for PageOperation should throw error', async () => {
+
+    it('Missing property(toPath) for PageOperation should throw error', async () => {
       // page
       const _path1 = '/resume_rename_7';
       const _page1 = await Page.findOne({ path: _path1 });
@@ -694,8 +717,9 @@ describe('Test page service methods', () => {
       await PageOperation.findByIdAndDelete(pageOperation?._id);
     });
   });
+
   describe('updateDescendantCountOfPagesWithPaths', () => {
-    test('should fix descendantCount of pages with one of the given paths', async () => {
+    it('should fix descendantCount of pages with one of the given paths', async () => {
       // path
       const _path1 = '/fix_descendantCount_1';
       const _path2 = '/fix_descendantCount_1/fix_descendantCount_2'; // empty

+ 24 - 22
apps/app/test/integration/service/user-groups.test.ts → apps/app/src/server/service/user-group.integ.ts

@@ -1,19 +1,21 @@
 import type { IGrantedGroup } from '@growi/core';
 import { GroupType, getIdForRef, type IPage, PageGrant } from '@growi/core';
 import mongoose from 'mongoose';
+import { beforeAll, describe, expect, it } from 'vitest';
 
-import { PageActionOnGroupDelete } from '../../../src/interfaces/user-group';
-import type Crowi from '../../../src/server/crowi';
-import type { PageDocument, PageModel } from '../../../src/server/models/page';
-import UserGroup from '../../../src/server/models/user-group';
-import UserGroupRelation from '../../../src/server/models/user-group-relation';
-import type { IUserGroupService } from '../../../src/server/service/user-group';
-import { getInstance } from '../setup-crowi';
+import { getInstance } from '^/test-with-vite/setup/crowi';
+
+import { PageActionOnGroupDelete } from '~/interfaces/user-group';
+import type Crowi from '~/server/crowi';
+import type { PageDocument, PageModel } from '~/server/models/page';
+import UserGroup from '~/server/models/user-group';
+import UserGroupRelation from '~/server/models/user-group-relation';
+import type { IUserGroupService } from '~/server/service/user-group';
 
 describe('UserGroupService', () => {
   let crowi: Crowi;
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let User;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let User: any;
   let Page: PageModel;
 
   let userGroupService: IUserGroupService;
@@ -35,8 +37,8 @@ describe('UserGroupService', () => {
   const groupId15 = new mongoose.Types.ObjectId();
 
   const userId1 = new mongoose.Types.ObjectId();
-  // biome-ignore lint/suspicious/noImplicitAnyLet: ignore
-  let user1;
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  let user1: any;
 
   const pageId1 = new mongoose.Types.ObjectId();
   const pageId2 = new mongoose.Types.ObjectId();
@@ -231,7 +233,7 @@ describe('UserGroupService', () => {
    * Update UserGroup
    */
   describe('updateGroup', () => {
-    test('Updated values should be reflected. (name, description, parent)', async () => {
+    it('Updated values should be reflected. (name, description, parent)', async () => {
       const userGroup2 = await UserGroup.findOne({ _id: groupId2 });
 
       const newGroupName = 'v5_group1_new';
@@ -250,7 +252,7 @@ describe('UserGroupService', () => {
       expect(updatedUserGroup.parent).toStrictEqual(newParentId);
     });
 
-    test('Should throw an error when trying to set existing group name', async () => {
+    it('Should throw an error when trying to set existing group name', async () => {
       const userGroup2 = await UserGroup.findOne({ _id: groupId2 });
 
       const result = userGroupService.updateGroup(groupId1, userGroup2?.name);
@@ -258,7 +260,7 @@ describe('UserGroupService', () => {
       await expect(result).rejects.toThrow('The group name is already taken');
     });
 
-    test('Parent should be null when parent group is released', async () => {
+    it('Parent should be null when parent group is released', async () => {
       const userGroup = await UserGroup.findOne({ _id: groupId3 });
       const updatedUserGroup = await userGroupService.updateGroup(
         userGroup?._id,
@@ -273,7 +275,7 @@ describe('UserGroupService', () => {
     /*
      * forceUpdateParents: false
      */
-    test('Should throw an error when users in child group do not exist in parent group', async () => {
+    it('Should throw an error when users in child group do not exist in parent group', async () => {
       const userGroup4 = await UserGroup.findOne({
         _id: groupId4,
         parent: null,
@@ -293,7 +295,7 @@ describe('UserGroupService', () => {
     /*
      * forceUpdateParents: true
      */
-    test('User should be included to parent group (2 groups ver)', async () => {
+    it('User should be included to parent group (2 groups ver)', async () => {
       const userGroup4 = await UserGroup.findOne({
         _id: groupId4,
         parent: null,
@@ -335,7 +337,7 @@ describe('UserGroupService', () => {
       expect(userGroupRelation5AfterUpdate).not.toBeNull();
     });
 
-    test('User should be included to parent group (3 groups ver)', async () => {
+    it('User should be included to parent group (3 groups ver)', async () => {
       const userGroup8 = await UserGroup.findOne({
         _id: groupId8,
         parent: null,
@@ -387,7 +389,7 @@ describe('UserGroupService', () => {
       expect(userGroupRelation8AfterUpdate).not.toBeNull();
     });
 
-    test('Should throw an error when trying to choose parent from descendant groups.', async () => {
+    it('Should throw an error when trying to choose parent from descendant groups.', async () => {
       const userGroup9 = await UserGroup.findOne({
         _id: groupId9,
         parent: null,
@@ -421,7 +423,7 @@ describe('UserGroupService', () => {
   });
 
   describe('removeUserByUsername', () => {
-    test('User should be deleted from child groups when the user excluded from the parent group', async () => {
+    it('User should be deleted from child groups when the user excluded from the parent group', async () => {
       const userGroup11 = await UserGroup.findOne({
         _id: groupId11,
         parent: null,
@@ -458,14 +460,14 @@ describe('UserGroupService', () => {
         relatedGroup: userGroup12?._id,
         relatedUser: userId1,
       });
-      await expect(userGroupRelation11AfterRemove).toBeNull();
-      await expect(userGroupRelation12AfterRemove).toBeNull();
+      expect(userGroupRelation11AfterRemove).toBeNull();
+      expect(userGroupRelation12AfterRemove).toBeNull();
     });
   });
 
   describe('removeCompletelyByRootGroupId', () => {
     describe('when action is public', () => {
-      test('Should remove the group and its descendants and publicize pages that are only visible to the groups to be removed', async () => {
+      it('Should remove the group and its descendants and publicize pages that are only visible to the groups to be removed', async () => {
         const userGroup13 = await UserGroup.findOne({ _id: groupId13 });
         const userGroup14 = await UserGroup.findOne({ _id: groupId14 });
         expect(userGroup13).not.toBeNull();