test-infra: re-enable 16 disabled server suites (jest DI + lib0 ESM) (#56)

16 suites were disabled via testPathIgnorePatterns due to two root causes: lib0
ESM not transformed (the @hocuspocus/server -> lib0/decoding.js chain) and stock
'should be defined' specs built via Test.createTestingModule without providers.
Add lib0 to transformIgnorePatterns; convert the 14 DI placeholders to direct
new X(...) instantiation with stub deps (keeping a real construct smoke test);
re-enable the suites. Also updates the public-share limiter test to assert the
fail-closed behavior from #62 (surfaced now that the suite runs). Full server
suite: 67 passed, 689 tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
claude code agent 227
2026-06-21 03:40:40 +03:00
parent 8016b1c540
commit c486750b2a
16 changed files with 174 additions and 130 deletions

View File

@@ -477,11 +477,10 @@ describe('PublicShareWorkspaceLimiter (cluster-wide sliding-window per-workspace
expect(await limiter.tryConsume('ws-1')).toBe(true);
});
it('FAILS OPEN (returns true) when the Redis eval rejects', async () => {
// The per-workspace cap is a COST backstop, not an access boundary: the
// funnel access gates and the per-IP throttle still apply. A transient
// Redis failure must therefore ADMIT the call (true) rather than 500/429,
// so a Redis blip cannot take the public-share assistant fully offline.
it('FAILS CLOSED (returns false) when the Redis eval rejects', async () => {
// FAIL CLOSED (#62): if Redis is down we cannot prove the workspace is under
// its cap, so DENY (the controller 429s) rather than admit an unmetered,
// billable anonymous call. The feature is optional, so denial is harmless.
const failingRedis = {
eval: () => Promise.reject(new Error('redis down')),
} as unknown as import('ioredis').Redis;
@@ -495,7 +494,7 @@ describe('PublicShareWorkspaceLimiter (cluster-wide sliding-window per-workspace
const errSpy = jest
.spyOn(Logger.prototype, 'error')
.mockImplementation(() => undefined);
expect(await limiter.tryConsume('ws-1')).toBe(true);
expect(await limiter.tryConsume('ws-1')).toBe(false);
expect(errSpy).toHaveBeenCalled(); // the failure MUST be logged, not swallowed
errSpy.mockRestore();
});

View File

@@ -1,15 +1,19 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthController } from './auth.controller';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the injected dependency tokens (e.g. AUDIT_SERVICE) at compile(),
// and this smoke test only needs the controller to construct.
describe('AuthController', () => {
let controller: AuthController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [AuthController],
}).compile();
controller = module.get<AuthController>(AuthController);
beforeEach(() => {
controller = new AuthController(
{} as any, // authService
{} as any, // sessionService
{} as any, // environmentService
{} as any, // moduleRef
{} as any, // auditService
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,25 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from './auth.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the @InjectKysely() connection token (and AUDIT_SERVICE) at
// compile(); this smoke test only needs the service to construct.
describe('AuthService', () => {
let service: AuthService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [AuthService],
}).compile();
service = module.get<AuthService>(AuthService);
beforeEach(() => {
service = new AuthService(
{} as any, // signupService
{} as any, // tokenService
{} as any, // sessionService
{} as any, // userSessionRepo
{} as any, // userRepo
{} as any, // userTokenRepo
{} as any, // mailService
{} as any, // domainService
{} as any, // environmentService
{} as any, // db
{} as any, // auditService
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { TokenService } from './token.service';
// Direct instantiation with stub deps, mirroring the rest of these unit specs.
describe('TokenService', () => {
let service: TokenService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [TokenService],
}).compile();
service = module.get<TokenService>(TokenService);
beforeEach(() => {
service = new TokenService(
{} as any, // jwtService
{} as any, // environmentService
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,20 @@
import { Test, TestingModule } from '@nestjs/testing';
import { CommentService } from './comment.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the @InjectQueue() tokens at compile(), and this smoke test only
// needs the service to construct.
describe('CommentService', () => {
let service: CommentService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [CommentService],
}).compile();
service = module.get<CommentService>(CommentService);
beforeEach(() => {
service = new CommentService(
{} as any, // commentRepo
{} as any, // pageRepo
{} as any, // wsService
{} as any, // collaborationGateway
{} as any, // generalQueue
{} as any, // notificationQueue
);
});
it('should be defined', () => {

View File

@@ -1,17 +1,15 @@
import { Test, TestingModule } from '@nestjs/testing';
import { GroupController } from './group.controller';
import { GroupService } from './services/group.service';
// Direct instantiation with stub deps, mirroring the rest of these unit specs.
describe('GroupController', () => {
let controller: GroupController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [GroupController],
providers: [GroupService],
}).compile();
controller = module.get<GroupController>(GroupController);
beforeEach(() => {
controller = new GroupController(
{} as any, // groupService
{} as any, // groupUserService
{} as any, // workspaceAbility
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { GroupService } from './group.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the @InjectKysely() connection token (and AUDIT_SERVICE) at
// compile(); this smoke test only needs the service to construct.
describe('GroupService', () => {
let service: GroupService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [GroupService],
}).compile();
service = module.get<GroupService>(GroupService);
beforeEach(() => {
service = new GroupService(
{} as any, // groupRepo
{} as any, // groupUserRepo
{} as any, // spaceMemberRepo
{} as any, // groupUserService
{} as any, // watcherRepo
{} as any, // favoriteRepo
{} as any, // db
{} as any, // auditService
);
});
it('should be defined', () => {

View File

@@ -1,17 +1,23 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PageController } from './page.controller';
import { PageService } from './services/page.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve PageService's injected tokens at compile(), and this smoke test only
// needs the controller to construct.
describe('PageController', () => {
let controller: PageController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [PageController],
providers: [PageService],
}).compile();
controller = module.get<PageController>(PageController);
beforeEach(() => {
controller = new PageController(
{} as any, // pageService
{} as any, // pageRepo
{} as any, // workspaceRepo
{} as any, // pageHistoryService
{} as any, // spaceAbility
{} as any, // pageAccessService
{} as any, // backlinkService
{} as any, // labelService
{} as any, // auditService
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,27 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PageService } from './page.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the @InjectKysely()/@InjectQueue() tokens at compile(), and this
// smoke test only needs the service to construct.
describe('PageService', () => {
let service: PageService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [PageService],
}).compile();
service = module.get<PageService>(PageService);
beforeEach(() => {
service = new PageService(
{} as any, // pageRepo
{} as any, // pagePermissionRepo
{} as any, // attachmentRepo
{} as any, // db
{} as any, // storageService
{} as any, // attachmentQueue
{} as any, // aiQueue
{} as any, // generalQueue
{} as any, // eventEmitter
{} as any, // collaborationGateway
{} as any, // watcherService
{} as any, // transclusionService
{} as any, // workspaceRepo
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SpaceService } from './space.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the @InjectKysely()/@InjectQueue()/AUDIT_SERVICE tokens at compile();
// this smoke test only needs the service to construct.
describe('SpaceService', () => {
let service: SpaceService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [SpaceService],
}).compile();
service = module.get<SpaceService>(SpaceService);
beforeEach(() => {
service = new SpaceService(
{} as any, // spaceRepo
{} as any, // spaceMemberService
{} as any, // shareRepo
{} as any, // workspaceRepo
{} as any, // licenseCheckService
{} as any, // db
{} as any, // attachmentQueue
{} as any, // auditService
);
});
it('should be defined', () => {

View File

@@ -1,17 +1,17 @@
import { Test, TestingModule } from '@nestjs/testing';
import { SpaceController } from './space.controller';
import { SpaceService } from './services/space.service';
// Direct instantiation with stub deps, mirroring the rest of these unit specs.
describe('SpaceController', () => {
let controller: SpaceController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [SpaceController],
providers: [SpaceService],
}).compile();
controller = module.get<SpaceController>(SpaceController);
beforeEach(() => {
controller = new SpaceController(
{} as any, // spaceService
{} as any, // spaceMemberService
{} as any, // spaceMemberRepo
{} as any, // spaceAbility
{} as any, // workspaceAbility
);
});
it('should be defined', () => {

View File

@@ -1,17 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserController } from './user.controller';
import { UserService } from './user.service';
// Direct instantiation with stub deps, mirroring the rest of these unit specs.
describe('UserController', () => {
let controller: UserController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
providers: [UserService],
}).compile();
controller = module.get<UserController>(UserController);
beforeEach(() => {
controller = new UserController(
{} as any, // userService
{} as any, // workspaceRepo
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,32 @@
import { Test, TestingModule } from '@nestjs/testing';
import { WorkspaceService } from './workspace.service';
// Direct instantiation with stub deps. The Test.createTestingModule form failed
// to resolve the @InjectKysely()/@InjectQueue()/AUDIT_SERVICE tokens at compile();
// this smoke test only needs the service to construct.
describe('WorkspaceService', () => {
let service: WorkspaceService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [WorkspaceService],
}).compile();
service = module.get<WorkspaceService>(WorkspaceService);
beforeEach(() => {
service = new WorkspaceService(
{} as any, // workspaceRepo
{} as any, // spaceService
{} as any, // spaceMemberService
{} as any, // groupRepo
{} as any, // groupUserRepo
{} as any, // userRepo
{} as any, // environmentService
{} as any, // domainService
{} as any, // licenseCheckService
{} as any, // shareRepo
{} as any, // watcherRepo
{} as any, // favoriteRepo
{} as any, // db
{} as any, // attachmentQueue
{} as any, // billingQueue
{} as any, // aiQueue
{} as any, // auditService
{} as any, // userSessionRepo
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,14 @@
import { Test, TestingModule } from '@nestjs/testing';
import { EnvironmentService } from './environment.service';
// Direct instantiation with a stub ConfigService, mirroring the rest of these
// unit specs.
describe('EnvironmentService', () => {
let service: EnvironmentService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [EnvironmentService],
}).compile();
service = module.get<EnvironmentService>(EnvironmentService);
beforeEach(() => {
service = new EnvironmentService(
{} as any, // configService
);
});
it('should be defined', () => {

View File

@@ -1,15 +1,15 @@
import { Test, TestingModule } from '@nestjs/testing';
import { StorageService } from './storage.service';
// Direct instantiation with a stub driver. The Test.createTestingModule form
// failed to resolve the STORAGE_DRIVER_TOKEN at compile(); this smoke test only
// needs the service to construct.
describe('StorageService', () => {
let service: StorageService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [StorageService],
}).compile();
service = module.get<StorageService>(StorageService);
beforeEach(() => {
service = new StorageService(
{} as any, // storageDriver
);
});
it('should be defined', () => {