veza/apps/web/src/schemas/apiRequestSchemas.test.ts
senke 441cb02233 fix(a11y): fix heading hierarchy h1→h3 gaps on 8 pages
Changed h3 section titles to h2 on pages where they directly follow the page h1:
- Library: empty state heading
- Queue: "Now Playing" + "Up Next"
- Search: discovery sections + results sections
- Profile: "About" + "Links"
- Sessions: card title
- Notifications: date group headers

Also: add 'api' binary to .gitignore

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:14:18 +01:00

228 lines
6.3 KiB
TypeScript

/**
* Tests for API Request Schemas
* FE-TYPE-003: Test Zod schema validation for API requests
*/
import { describe, it, expect } from 'vitest';
import {
loginRequestSchema,
registerRequestSchema,
sendMessageRequestSchema,
createConversationRequestSchema,
updateProfileRequestSchema,
validateApiRequest,
safeValidateApiRequest,
} from './apiRequestSchemas';
describe('apiRequestSchemas', () => {
describe('loginRequestSchema', () => {
it('should validate valid login request', () => {
const validRequest = {
email: 'test@example.com',
password: 'password123',
};
const result = loginRequestSchema.safeParse(validRequest);
expect(result.success).toBe(true);
});
it('should reject invalid email', () => {
const invalidRequest = {
email: 'not-an-email',
password: 'password123',
};
const result = loginRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
it('should reject empty password', () => {
const invalidRequest = {
email: 'test@example.com',
password: '',
};
const result = loginRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
});
describe('registerRequestSchema', () => {
it('should validate valid register request', () => {
const validRequest = {
username: 'testuser',
email: 'test@example.com',
password: 'SecurePass123!',
};
const result = registerRequestSchema.safeParse(validRequest);
expect(result.success).toBe(true);
});
it('should reject short password', () => {
const invalidRequest = {
username: 'testuser',
email: 'test@example.com',
password: 'short',
};
const result = registerRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
it('should reject invalid username', () => {
const invalidRequest = {
username: 'ab', // Too short
email: 'test@example.com',
password: 'SecurePass123!',
};
const result = registerRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
});
describe('sendMessageRequestSchema', () => {
it('should validate valid message request', () => {
const validRequest = {
conversation_id: '123e4567-e89b-12d3-a456-426614174000',
content: 'Hello, world!',
};
const result = sendMessageRequestSchema.safeParse(validRequest);
expect(result.success).toBe(true);
});
it('should reject invalid UUID', () => {
const invalidRequest = {
conversation_id: 'not-a-uuid',
content: 'Hello, world!',
};
const result = sendMessageRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
it('should reject empty content', () => {
const invalidRequest = {
conversation_id: '123e4567-e89b-12d3-a456-426614174000',
content: '',
};
const result = sendMessageRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
});
describe('createConversationRequestSchema', () => {
it('should validate valid conversation request', () => {
const validRequest = {
name: 'Test Conversation',
type: 'group',
participant_ids: ['123e4567-e89b-12d3-a456-426614174000'],
};
const result = createConversationRequestSchema.safeParse(validRequest);
expect(result.success).toBe(true);
});
it('should reject empty participant list', () => {
const invalidRequest = {
name: 'Test Conversation',
type: 'group',
participant_ids: [],
};
const result = createConversationRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
it('should reject empty name', () => {
const invalidRequest = {
name: '',
type: 'group',
participant_ids: ['123e4567-e89b-12d3-a456-426614174000'],
};
const result = createConversationRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
});
describe('updateProfileRequestSchema', () => {
it('should validate valid profile update', () => {
const validRequest = {
first_name: 'John',
last_name: 'Doe',
bio: 'Test bio',
};
const result = updateProfileRequestSchema.safeParse(validRequest);
expect(result.success).toBe(true);
});
it('should validate empty request (all optional)', () => {
const validRequest = {};
const result = updateProfileRequestSchema.safeParse(validRequest);
expect(result.success).toBe(true);
});
it('should reject invalid date format', () => {
const invalidRequest = {
birthdate: '2024/01/01', // Wrong format
};
const result = updateProfileRequestSchema.safeParse(invalidRequest);
expect(result.success).toBe(false);
});
});
describe('validateApiRequest', () => {
it('should validate and return data', () => {
const validRequest = {
email: 'test@example.com',
password: 'password123',
};
const result = validateApiRequest(loginRequestSchema, validRequest);
expect(result.email).toBe(validRequest.email);
expect(result.password).toBe(validRequest.password);
});
it('should throw on invalid data', () => {
const invalidRequest = {
email: 'not-an-email',
password: 'password123',
};
expect(() =>
validateApiRequest(loginRequestSchema, invalidRequest),
).toThrow();
});
});
describe('safeValidateApiRequest', () => {
it('should return success for valid data', () => {
const validRequest = {
email: 'test@example.com',
password: 'password123',
};
const result = safeValidateApiRequest(loginRequestSchema, validRequest);
expect(result.success).toBe(true);
expect(result.data).toBeDefined();
});
it('should return error for invalid data', () => {
const invalidRequest = {
email: 'not-an-email',
password: 'password123',
};
const result = safeValidateApiRequest(loginRequestSchema, invalidRequest);
expect(result.success).toBe(false);
expect(result.error).toBeDefined();
});
});
});