wraith/backend/src/auth/ws-auth.guard.spec.ts
Vantz Stockwell 63315f94c4 test: backend test suite — 8 spec files covering vault encryption, credentials, SSH keys, auth service, controller, guards
63 tests across 8 spec files, all passing. Removes 2 stale stub files from
backend/test/ that were incompatible with the current async EncryptionService
and 3-argument AuthService constructor. New suite lives in src/ co-located
with source files per NestJS convention.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 19:10:12 -04:00

57 lines
2.0 KiB
TypeScript

// backend/src/auth/ws-auth.guard.spec.ts
import { WsAuthGuard } from './ws-auth.guard';
import { AuthController } from './auth.controller';
describe('WsAuthGuard', () => {
let guard: WsAuthGuard;
let jwt: any;
beforeEach(() => {
jwt = {
verify: jest.fn().mockReturnValue({ sub: 1, email: 'test@test.com' }),
};
guard = new WsAuthGuard(jwt as any);
});
it('should authenticate via httpOnly cookie', () => {
const req = { headers: { cookie: 'wraith_token=valid-jwt; other=stuff' }, url: '/ws' };
const result = guard.validateClient({}, req);
expect(jwt.verify).toHaveBeenCalledWith('valid-jwt');
expect(result).toEqual({ sub: 1, email: 'test@test.com' });
});
it('should authenticate via single-use WS ticket', () => {
const originalConsume = AuthController.consumeWsTicket;
AuthController.consumeWsTicket = jest.fn().mockReturnValue({
sub: 42,
email: 'ticket@test.com',
role: 'user',
});
const req = { url: '/api/ws/terminal?ticket=abc123', headers: {} };
const result = guard.validateClient({}, req);
expect(AuthController.consumeWsTicket).toHaveBeenCalledWith('abc123');
expect(result).toEqual({ sub: 42, email: 'ticket@test.com' });
// Restore
AuthController.consumeWsTicket = originalConsume;
});
it('should fall back to legacy URL token when no cookie or ticket', () => {
const req = { url: '/api/ws/terminal?token=legacy-jwt', headers: {} };
guard.validateClient({}, req);
expect(jwt.verify).toHaveBeenCalledWith('legacy-jwt');
});
it('should return null when no credentials are present', () => {
const req = { url: '/api/ws/terminal', headers: {} };
const result = guard.validateClient({}, req);
expect(result).toBeNull();
});
it('should return null when JWT verification fails', () => {
jwt.verify.mockImplementation(() => { throw new Error('invalid signature'); });
const req = { headers: { cookie: 'wraith_token=bad-jwt' }, url: '/ws' };
const result = guard.validateClient({}, req);
expect(result).toBeNull();
});
});