81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { readFileSync } from 'node:fs';
|
|
import { resolve } from 'node:path';
|
|
import { validateSync } from 'class-validator';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { SendMessageDto } from '../../conversations/conversations.dto.js';
|
|
import { ChatRequestDto } from '../chat.dto.js';
|
|
import { validateSocketSession } from '../chat.gateway-auth.js';
|
|
|
|
describe('Chat controller source hardening', () => {
|
|
it('applies AuthGuard and reads the current user', () => {
|
|
const source = readFileSync(resolve('src/chat/chat.controller.ts'), 'utf8');
|
|
|
|
expect(source).toContain('@UseGuards(AuthGuard)');
|
|
expect(source).toContain('@CurrentUser() user: { id: string }');
|
|
});
|
|
});
|
|
|
|
describe('WebSocket session authentication', () => {
|
|
it('returns null when the handshake does not resolve to a session', async () => {
|
|
const result = await validateSocketSession(
|
|
{},
|
|
{
|
|
api: {
|
|
getSession: vi.fn().mockResolvedValue(null),
|
|
},
|
|
},
|
|
);
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it('returns the resolved session when Better Auth accepts the headers', async () => {
|
|
const session = { user: { id: 'user-1' }, session: { id: 'session-1' } };
|
|
|
|
const result = await validateSocketSession(
|
|
{ cookie: 'session=abc' },
|
|
{
|
|
api: {
|
|
getSession: vi.fn().mockResolvedValue(session),
|
|
},
|
|
},
|
|
);
|
|
|
|
expect(result).toBe(session);
|
|
});
|
|
});
|
|
|
|
describe('Chat DTO validation', () => {
|
|
it('rejects unsupported message roles and system messages', () => {
|
|
const dto = Object.assign(new SendMessageDto(), {
|
|
content: 'hello',
|
|
role: 'system',
|
|
});
|
|
|
|
const errors = validateSync(dto);
|
|
|
|
expect(errors.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('rejects oversized conversation message content above 32000 characters', () => {
|
|
const dto = Object.assign(new SendMessageDto(), {
|
|
content: 'x'.repeat(32_001),
|
|
role: 'user',
|
|
});
|
|
|
|
const errors = validateSync(dto);
|
|
|
|
expect(errors.length).toBeGreaterThan(0);
|
|
});
|
|
|
|
it('rejects oversized chat content above 10000 characters', () => {
|
|
const dto = Object.assign(new ChatRequestDto(), {
|
|
content: 'x'.repeat(10_001),
|
|
});
|
|
|
|
const errors = validateSync(dto);
|
|
|
|
expect(errors.length).toBeGreaterThan(0);
|
|
});
|
|
});
|