website refactor
This commit is contained in:
@@ -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');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
});
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user