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:
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
Reference in New Issue
Block a user