66 lines
2.8 KiB
TypeScript
66 lines
2.8 KiB
TypeScript
import { CurrentUserGuard } from '../../src/modules/identity/presentation/guards/current-user.guard';
|
|
import { SyncIdentityHandler } from '../../src/modules/identity/application/handlers/user/sync-identity.handler';
|
|
import { IUser } from '../../src/modules/identity/domain/repositories/user.interface';
|
|
import { IdentityData } from '../../src/core/auth/interfaces/identity-data';
|
|
import { UnauthorizedException } from '@nestjs/common';
|
|
|
|
describe('CurrentUserGuard', () => {
|
|
let guard: CurrentUserGuard;
|
|
let mockSync: Partial<SyncIdentityHandler>;
|
|
let mockUserRepo: Partial<IUser>;
|
|
|
|
beforeEach(() => {
|
|
mockSync = { execute: jest.fn() };
|
|
mockUserRepo = { getById: jest.fn() };
|
|
guard = new CurrentUserGuard(mockSync as any, mockUserRepo as any);
|
|
});
|
|
|
|
function makeContext(req: any): any {
|
|
return { switchToHttp: () => ({ getRequest: () => req }) } as any;
|
|
}
|
|
|
|
test('raylabContext fast path sets currentUser and returns true', async () => {
|
|
const user = { id: 'u1' } as any;
|
|
const req: any = { raylabContext: { user } };
|
|
const res = await guard.canActivate(makeContext(req));
|
|
expect(res).toBe(true);
|
|
expect(req.currentUser).toBe(user);
|
|
});
|
|
|
|
test('missing identity throws UnauthorizedException', async () => {
|
|
const req: any = {};
|
|
await expect(guard.canActivate(makeContext(req))).rejects.toThrow(UnauthorizedException);
|
|
});
|
|
|
|
test('internal identity resolves by getById and does not call sync', async () => {
|
|
const identity = new IdentityData('uid', 'u', 'e');
|
|
const req: any = { identity, identitySource: 'internal' };
|
|
(mockUserRepo.getById as jest.Mock).mockResolvedValue({ id: 'uid', roles: [], permissions: [] });
|
|
|
|
const res = await guard.canActivate(makeContext(req));
|
|
expect(res).toBe(true);
|
|
expect(req.currentUser).toBeDefined();
|
|
expect((mockSync.execute as jest.Mock)).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('internal identity with missing user throws UnauthorizedException', async () => {
|
|
const identity = new IdentityData('missing', 'u', 'e');
|
|
const req: any = { identity, identitySource: 'internal' };
|
|
(mockUserRepo.getById as jest.Mock).mockRejectedValue(new Error('User tidak ditemukan.'));
|
|
|
|
await expect(guard.canActivate(makeContext(req))).rejects.toThrow(UnauthorizedException);
|
|
expect((mockSync.execute as jest.Mock)).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test('external identity calls syncIdentityHandler', async () => {
|
|
const identity = new IdentityData('extsub', 'u', 'e');
|
|
const req: any = { identity, identitySource: 'external' };
|
|
(mockSync.execute as jest.Mock).mockResolvedValue({ id: 'user-ext' });
|
|
|
|
const res = await guard.canActivate(makeContext(req));
|
|
expect(res).toBe(true);
|
|
expect(req.currentUser).toBeDefined();
|
|
expect((mockUserRepo.getById as jest.Mock)).not.toHaveBeenCalled();
|
|
});
|
|
});
|