website refactor

This commit is contained in:
2026-01-16 12:55:48 +01:00
parent 0208334c59
commit 20a42c52fd
83 changed files with 1610 additions and 1238 deletions

View File

@@ -8,7 +8,7 @@ async function withRequestContext<T>(req: Record<string, unknown>, fn: () => Pro
const res = {};
return await new Promise<T>((resolve, reject) => {
requestContextMiddleware(req as any, res as any, () => {
requestContextMiddleware(req as never, res as never, () => {
fn().then(resolve, reject);
});
});
@@ -16,12 +16,12 @@ async function withRequestContext<T>(req: Record<string, unknown>, fn: () => Pro
describe('ActorFromSession', () => {
it('derives actor from authenticated session (request.user), not request payload', async () => {
const req: any = {
const req: unknown = {
user: { userId: 'driver-from-session' },
body: { driverId: 'driver-from-body' },
};
await withRequestContext(req, async () => {
await withRequestContext(req as Record<string, unknown>, async () => {
const actor = getActorFromRequestContext();
expect(actor).toEqual({ userId: 'driver-from-session', driverId: 'driver-from-session' });
});
@@ -32,14 +32,14 @@ describe('ActorFromSession', () => {
execute: vi.fn(async () => Result.ok(undefined)),
};
const req: any = {
const req: unknown = {
user: { userId: 'driver-from-session' },
body: { performerDriverId: 'driver-from-body' },
};
await withRequestContext(req, async () => {
await withRequestContext(req as Record<string, unknown>, async () => {
await expect(
requireLeagueAdminOrOwner('league-1', getLeagueAdminPermissionsUseCase as any),
requireLeagueAdminOrOwner('league-1', getLeagueAdminPermissionsUseCase as never),
).resolves.toBeUndefined();
});
@@ -52,15 +52,15 @@ describe('ActorFromSession', () => {
it('permission helper rejects when league admin check fails', async () => {
const getLeagueAdminPermissionsUseCase = {
execute: vi.fn(async () =>
Result.err({ code: 'USER_NOT_MEMBER', details: { message: 'nope' } } as any),
Result.err({ code: 'USER_NOT_MEMBER', details: { message: 'nope' } } as never),
),
};
const req: any = { user: { userId: 'driver-from-session' } };
const req: unknown = { user: { userId: 'driver-from-session' } };
await withRequestContext(req, async () => {
await withRequestContext(req as Record<string, unknown>, async () => {
await expect(
requireLeagueAdminOrOwner('league-1', getLeagueAdminPermissionsUseCase as any),
requireLeagueAdminOrOwner('league-1', getLeagueAdminPermissionsUseCase as never),
).rejects.toThrow('Forbidden');
});
});

View File

@@ -118,7 +118,7 @@ describe('AuthController', () => {
};
(service.getCurrentSession as Mock).mockResolvedValue(session);
const res = { json: vi.fn() } as any;
const res = { json: vi.fn() } as unknown as import('express').Response;
await controller.getSession(res);
@@ -129,7 +129,7 @@ describe('AuthController', () => {
it('should write JSON null when no session', async () => {
(service.getCurrentSession as Mock).mockResolvedValue(null);
const res = { json: vi.fn() } as any;
const res = { json: vi.fn() } as unknown as import('express').Response;
await controller.getSession(res);
@@ -151,7 +151,7 @@ describe('AuthController', () => {
});
describe('auth guards (HTTP)', () => {
let app: any;
let app: import("@nestjs/common").INestApplication;
const sessionPort: { getCurrentSession: () => Promise<null | { token: string; user: { id: string } }> } = {
getCurrentSession: vi.fn(async () => null),
@@ -201,9 +201,9 @@ describe('AuthController', () => {
const reflector = new Reflector();
app.useGlobalGuards(
new AuthenticationGuard(sessionPort as any),
new AuthorizationGuard(reflector, authorizationService as any),
new FeatureAvailabilityGuard(reflector, policyService as any),
new AuthenticationGuard(sessionPort as never),
new AuthorizationGuard(reflector, authorizationService as never),
new FeatureAvailabilityGuard(reflector, policyService as never),
);
await app.init();

View File

@@ -45,7 +45,7 @@ type SessionPort = {
};
describe('Auth guards (HTTP)', () => {
let app: any;
let app: import("@nestjs/common").INestApplication;
const sessionPort: SessionPort = {
getCurrentSession: vi.fn(async () => null),
@@ -75,9 +75,9 @@ describe('Auth guards (HTTP)', () => {
const reflector = new Reflector();
app.useGlobalGuards(
new AuthenticationGuard(sessionPort as any),
new AuthorizationGuard(reflector, authorizationService as any),
new FeatureAvailabilityGuard(reflector, policyService as any),
new AuthenticationGuard(sessionPort as never),
new AuthorizationGuard(reflector, authorizationService as never),
new FeatureAvailabilityGuard(reflector, policyService as never),
);
await app.init();

View File

@@ -3,11 +3,11 @@ import { Result } from '@core/shared/application/Result';
import { AuthService } from './AuthService';
class FakeAuthSessionPresenter {
private model: any = null;
private model: unknown = null;
reset() {
this.model = null;
}
present(model: any) {
present(model: unknown) {
this.model = model;
}
get responseModel() {
@@ -17,11 +17,11 @@ class FakeAuthSessionPresenter {
}
class FakeCommandResultPresenter {
private model: any = null;
private model: unknown = null;
reset() {
this.model = null;
}
present(model: any) {
present(model: unknown) {
this.model = model;
}
get responseModel() {
@@ -33,18 +33,18 @@ class FakeCommandResultPresenter {
describe('AuthService', () => {
it('getCurrentSession returns null when no session', async () => {
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ getCurrentSession: vi.fn(async () => null), createSession: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{ getCurrentSession: vi.fn(async () => null), createSession: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.getCurrentSession()).resolves.toBeNull();
@@ -52,24 +52,24 @@ describe('AuthService', () => {
it('getCurrentSession maps core session to DTO', async () => {
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{
getCurrentSession: vi.fn(async () => ({
token: 't1',
user: { id: 'u1', email: null, displayName: 'John' },
})),
createSession: vi.fn(),
} as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
} as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.getCurrentSession()).resolves.toEqual({
@@ -92,25 +92,25 @@ describe('AuthService', () => {
};
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
identitySessionPort as any,
{ execute: vi.fn() } as any,
signupUseCase as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
authSessionPresenter as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
identitySessionPort as never,
{ execute: vi.fn() } as never,
signupUseCase as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
authSessionPresenter as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
const session = await service.signupWithEmail({
email: 'e2',
password: 'p2',
displayName: 'Jane Smith',
} as any);
} as never);
expect(signupUseCase.execute).toHaveBeenCalledWith({
email: 'e2',
@@ -127,22 +127,22 @@ describe('AuthService', () => {
it('signupWithEmail throws with fallback when no details.message', async () => {
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' } as any)) } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' } as never)) } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(
service.signupWithEmail({ email: 'e2', password: 'p2', displayName: 'Jane Smith' } as any),
service.signupWithEmail({ email: 'e2', password: 'p2', displayName: 'Jane Smith' } as never),
).rejects.toThrow('Signup failed');
});
@@ -160,21 +160,21 @@ describe('AuthService', () => {
};
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
identitySessionPort as any,
loginUseCase as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
authSessionPresenter as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
identitySessionPort as never,
loginUseCase as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
authSessionPresenter as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.loginWithEmail({ email: 'e3', password: 'p3' } as any)).resolves.toEqual({
await expect(service.loginWithEmail({ email: 'e3', password: 'p3' } as never)).resolves.toEqual({
token: 't3',
user: { userId: 'u3', email: 'e3', displayName: 'Bob Wilson' },
});
@@ -192,40 +192,40 @@ describe('AuthService', () => {
it('loginWithEmail throws on use case error and prefers details.message', async () => {
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as any,
{ execute: vi.fn(async () => Result.err({ code: 'INVALID_CREDENTIALS', details: { message: 'Bad login' } })) } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as never,
{ execute: vi.fn(async () => Result.err({ code: 'INVALID_CREDENTIALS', details: { message: 'Bad login' } })) } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.loginWithEmail({ email: 'e', password: 'p' } as any)).rejects.toThrow('Bad login');
await expect(service.loginWithEmail({ email: 'e', password: 'p' } as never)).rejects.toThrow('Bad login');
});
it('loginWithEmail throws with fallback when no details.message', async () => {
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as any,
{ execute: vi.fn(async () => Result.err({ code: 'INVALID_CREDENTIALS' } as any)) } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as never,
{ execute: vi.fn(async () => Result.err({ code: 'INVALID_CREDENTIALS' } as never)) } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.loginWithEmail({ email: 'e', password: 'p' } as any)).rejects.toThrow('Login failed');
await expect(service.loginWithEmail({ email: 'e', password: 'p' } as never)).rejects.toThrow('Login failed');
});
it('logout returns command result on success', async () => {
@@ -237,18 +237,18 @@ describe('AuthService', () => {
};
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
logoutUseCase as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
commandResultPresenter as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
logoutUseCase as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
commandResultPresenter as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.logout()).resolves.toEqual({ success: true });
@@ -256,18 +256,18 @@ describe('AuthService', () => {
it('logout throws with fallback when no details.message', async () => {
const service = new AuthService(
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as any,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' } as any)) } as any,
{ execute: vi.fn() } as any,
{ execute: vi.fn() } as any,
new FakeAuthSessionPresenter() as any,
new FakeCommandResultPresenter() as any,
new FakeAuthSessionPresenter() as any,
new FakeAuthSessionPresenter() as any,
{ debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() } as never,
{ getCurrentSession: vi.fn(), createSession: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn(async () => Result.err({ code: 'REPOSITORY_ERROR' } as never)) } as never,
{ execute: vi.fn() } as never,
{ execute: vi.fn() } as never,
new FakeAuthSessionPresenter() as never,
new FakeCommandResultPresenter() as never,
new FakeAuthSessionPresenter() as never,
new FakeAuthSessionPresenter() as never,
);
await expect(service.logout()).rejects.toThrow('Logout failed');

View File

@@ -9,7 +9,7 @@ import { requestContextMiddleware } from '@adapters/http/RequestContext';
import { AuthModule } from './AuthModule';
describe('Auth session (HTTP, inmemory)', () => {
let app: any;
let app: import("@nestjs/common").INestApplication;
beforeEach(async () => {
const module = await Test.createTestingModule({

View File

@@ -11,44 +11,44 @@ function createExecutionContext(request: Record<string, unknown>) {
describe('AuthenticationGuard', () => {
it('attaches request.user.userId from session when missing', async () => {
const request: any = {};
const request: unknown = {};
const sessionPort = {
getCurrentSession: vi.fn(async () => ({ token: 't', user: { id: 'user-1' } })),
};
const guard = new AuthenticationGuard(sessionPort as any);
const guard = new AuthenticationGuard(sessionPort as never);
await expect(guard.canActivate(createExecutionContext(request) as any)).resolves.toBe(true);
await expect(guard.canActivate(createExecutionContext(request as Record<string, unknown>) as never)).resolves.toBe(true);
expect(sessionPort.getCurrentSession).toHaveBeenCalledTimes(1);
expect(request.user).toEqual({ userId: 'user-1' });
expect((request as { user?: unknown }).user).toEqual({ userId: 'user-1' });
});
it('does not override request.user.userId if already present', async () => {
const request: any = { user: { userId: 'already-set' } };
const request: unknown = { user: { userId: 'already-set' } };
const sessionPort = {
getCurrentSession: vi.fn(async () => ({ token: 't', user: { id: 'user-1' } })),
};
const guard = new AuthenticationGuard(sessionPort as any);
const guard = new AuthenticationGuard(sessionPort as never);
await expect(guard.canActivate(createExecutionContext(request) as any)).resolves.toBe(true);
await expect(guard.canActivate(createExecutionContext(request as Record<string, unknown>) as never)).resolves.toBe(true);
expect(sessionPort.getCurrentSession).not.toHaveBeenCalled();
expect(request.user).toEqual({ userId: 'already-set' });
expect((request as { user?: unknown }).user).toEqual({ userId: 'already-set' });
});
it('leaves request.user undefined when no session exists', async () => {
const request: any = {};
const request: unknown = {};
const sessionPort = {
getCurrentSession: vi.fn(async () => null),
};
const guard = new AuthenticationGuard(sessionPort as any);
const guard = new AuthenticationGuard(sessionPort as never);
await expect(guard.canActivate(createExecutionContext(request) as any)).resolves.toBe(true);
await expect(guard.canActivate(createExecutionContext(request as Record<string, unknown>) as never)).resolves.toBe(true);
expect(sessionPort.getCurrentSession).toHaveBeenCalledTimes(1);
expect(request.user).toBeUndefined();
expect((request as { user?: unknown }).user).toBeUndefined();
});
});

View File

@@ -30,60 +30,60 @@ function createExecutionContext(options: { handler: Function; userId?: string })
describe('AuthorizationGuard', () => {
it('allows public routes without a user session', async () => {
const authorizationService = { getRolesForUser: vi.fn() };
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
const guard = new AuthorizationGuard(new Reflector(), authorizationService as never);
const ctx = createExecutionContext({
handler: DummyController.prototype.publicHandler,
});
await expect(guard.canActivate(ctx as any)).resolves.toBe(true);
await expect(guard.canActivate(ctx as never)).resolves.toBe(true);
expect(authorizationService.getRolesForUser).not.toHaveBeenCalled();
});
it('denies non-public routes by default when not authenticated', async () => {
const authorizationService = { getRolesForUser: vi.fn() };
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
const guard = new AuthorizationGuard(new Reflector(), authorizationService as never);
const ctx = createExecutionContext({
handler: DummyController.prototype.protectedHandler,
});
await expect(guard.canActivate(ctx as any)).rejects.toThrow(UnauthorizedException);
await expect(guard.canActivate(ctx as never)).rejects.toThrow(UnauthorizedException);
});
it('allows non-public routes when authenticated', async () => {
const authorizationService = { getRolesForUser: vi.fn().mockReturnValue([]) };
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
const guard = new AuthorizationGuard(new Reflector(), authorizationService as never);
const ctx = createExecutionContext({
handler: DummyController.prototype.protectedHandler,
userId: 'user-1',
});
await expect(guard.canActivate(ctx as any)).resolves.toBe(true);
await expect(guard.canActivate(ctx as never)).resolves.toBe(true);
});
it('denies routes requiring roles when user does not have any required role', async () => {
const authorizationService = { getRolesForUser: vi.fn().mockReturnValue(['user']) };
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
const guard = new AuthorizationGuard(new Reflector(), authorizationService as never);
const ctx = createExecutionContext({
handler: DummyController.prototype.adminHandler,
userId: 'user-1',
});
await expect(guard.canActivate(ctx as any)).rejects.toThrow(ForbiddenException);
await expect(guard.canActivate(ctx as never)).rejects.toThrow(ForbiddenException);
});
it('allows routes requiring roles when user has a required role', async () => {
const authorizationService = { getRolesForUser: vi.fn().mockReturnValue(['admin']) };
const guard = new AuthorizationGuard(new Reflector(), authorizationService as any);
const guard = new AuthorizationGuard(new Reflector(), authorizationService as never);
const ctx = createExecutionContext({
handler: DummyController.prototype.adminHandler,
userId: 'user-1',
});
await expect(guard.canActivate(ctx as any)).resolves.toBe(true);
await expect(guard.canActivate(ctx as never)).resolves.toBe(true);
});
});