import { describe, it, expect } from 'vitest'; import { registerSchema, loginSchema, forgotPasswordSchema, resetPasswordSchema, sessionFilterSchema, companySettingsSchema, userUpdateSchema, metricsQuerySchema, validateInput, } from '../../lib/validation'; describe('Validation Schemas', () => { // Helper for password validation const validPassword = 'Password123!'; const invalidPasswordShort = 'Pass1!'; const invalidPasswordNoLower = 'PASSWORD123!'; const invalidPasswordNoUpper = 'password123!'; const invalidPasswordNoNumber = 'Password!!'; const invalidPasswordNoSpecial = 'Password123'; // Helper for email validation const validEmail = 'test@example.com'; const invalidEmailFormat = 'test@example'; const invalidEmailTooLong = 'a'.repeat(250) + '@example.com'; // 250 + 11 = 261 chars // Helper for company name validation const validCompanyName = 'My Company Inc.'; const invalidCompanyNameEmpty = ''; const invalidCompanyNameTooLong = 'A'.repeat(101); const invalidCompanyNameChars = 'My Company #$%'; describe('registerSchema', () => { it('should validate a valid registration object', () => { const data = { email: validEmail, password: validPassword, company: validCompanyName, }; expect(registerSchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid email', () => { const data = { email: invalidEmailFormat, password: validPassword, company: validCompanyName, }; expect(registerSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid password', () => { const data = { email: validEmail, password: invalidPasswordShort, company: validCompanyName, }; expect(registerSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid company name', () => { const data = { email: validEmail, password: validPassword, company: invalidCompanyNameEmpty, }; expect(registerSchema.safeParse(data).success).toBe(false); }); }); describe('loginSchema', () => { it('should validate a valid login object', () => { const data = { email: validEmail, password: validPassword, }; expect(loginSchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid email', () => { const data = { email: invalidEmailFormat, password: validPassword, }; expect(loginSchema.safeParse(data).success).toBe(false); }); it('should invalidate an empty password', () => { const data = { email: validEmail, password: '', }; expect(loginSchema.safeParse(data).success).toBe(false); }); }); describe('forgotPasswordSchema', () => { it('should validate a valid email', () => { const data = { email: validEmail }; expect(forgotPasswordSchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid email', () => { const data = { email: invalidEmailFormat }; expect(forgotPasswordSchema.safeParse(data).success).toBe(false); }); }); describe('resetPasswordSchema', () => { it('should validate a valid reset password object', () => { const data = { token: 'some-valid-token', password: validPassword, }; expect(resetPasswordSchema.safeParse(data).success).toBe(true); }); it('should invalidate an empty token', () => { const data = { token: '', password: validPassword, }; expect(resetPasswordSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid password', () => { const data = { token: 'some-valid-token', password: invalidPasswordShort, }; expect(resetPasswordSchema.safeParse(data).success).toBe(false); }); }); describe('sessionFilterSchema', () => { it('should validate a valid session filter object', () => { const data = { search: 'query', sentiment: 'POSITIVE', category: 'SCHEDULE_HOURS', startDate: '2023-01-01T00:00:00Z', endDate: '2023-01-31T23:59:59Z', page: 1, limit: 20, }; expect(sessionFilterSchema.safeParse(data).success).toBe(true); }); it('should validate with only optional fields', () => { const data = {}; expect(sessionFilterSchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid sentiment', () => { const data = { sentiment: 'INVALID' }; expect(sessionFilterSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid category', () => { const data = { category: 'INVALID_CATEGORY' }; expect(sessionFilterSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid date format', () => { const data = { startDate: '2023-01-01' }; // Missing time expect(sessionFilterSchema.safeParse(data).success).toBe(false); }); it('should invalidate page less than 1', () => { const data = { page: 0 }; expect(sessionFilterSchema.safeParse(data).success).toBe(false); }); it('should invalidate limit greater than 100', () => { const data = { limit: 101 }; expect(sessionFilterSchema.safeParse(data).success).toBe(false); }); }); describe('companySettingsSchema', () => { it('should validate a valid company settings object', () => { const data = { name: validCompanyName, csvUrl: 'http://example.com/data.csv', csvUsername: 'user', csvPassword: 'password', sentimentAlert: 0.5, dashboardOpts: { theme: 'dark' }, }; expect(companySettingsSchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid CSV URL', () => { const data = { name: validCompanyName, csvUrl: 'invalid-url', }; expect(companySettingsSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid company name', () => { const data = { name: invalidCompanyNameEmpty, csvUrl: 'http://example.com/data.csv', }; expect(companySettingsSchema.safeParse(data).success).toBe(false); }); it('should invalidate sentimentAlert out of range', () => { const data = { name: validCompanyName, csvUrl: 'http://example.com/data.csv', sentimentAlert: 1.1, }; expect(companySettingsSchema.safeParse(data).success).toBe(false); }); }); describe('userUpdateSchema', () => { it('should validate a valid user update object with all fields', () => { const data = { email: validEmail, role: 'ADMIN', password: validPassword, }; expect(userUpdateSchema.safeParse(data).success).toBe(true); }); it('should validate a valid user update object with only email', () => { const data = { email: validEmail }; expect(userUpdateSchema.safeParse(data).success).toBe(true); }); it('should validate a valid user update object with only role', () => { const data = { role: 'USER' }; expect(userUpdateSchema.safeParse(data).success).toBe(true); }); it('should validate a valid user update object with only password', () => { const data = { password: validPassword }; expect(userUpdateSchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid email', () => { const data = { email: invalidEmailFormat }; expect(userUpdateSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid role', () => { const data = { role: 'SUPERUSER' }; expect(userUpdateSchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid password', () => { const data = { password: invalidPasswordShort }; expect(userUpdateSchema.safeParse(data).success).toBe(false); }); }); describe('metricsQuerySchema', () => { it('should validate a valid metrics query object', () => { const data = { startDate: '2023-01-01T00:00:00Z', endDate: '2023-01-31T23:59:59Z', companyId: 'a1b2c3d4-e5f6-7890-1234-567890abcdef', }; expect(metricsQuerySchema.safeParse(data).success).toBe(true); }); it('should validate with only optional fields', () => { const data = {}; expect(metricsQuerySchema.safeParse(data).success).toBe(true); }); it('should invalidate an invalid date format', () => { const data = { startDate: '2023-01-01' }; expect(metricsQuerySchema.safeParse(data).success).toBe(false); }); it('should invalidate an invalid companyId format', () => { const data = { companyId: 'invalid-uuid' }; expect(metricsQuerySchema.safeParse(data).success).toBe(false); }); }); describe('validateInput', () => { const testSchema = registerSchema; // Using registerSchema for validateInput tests it('should return success true and data for valid input', () => { const data = { email: validEmail, password: validPassword, company: validCompanyName, }; const result = validateInput(testSchema, data); expect(result.success).toBe(true); expect((result as any).data).toEqual(data); }); it('should return success false and errors for invalid input', () => { const data = { email: invalidEmailFormat, password: invalidPasswordShort, company: invalidCompanyNameEmpty, }; const result = validateInput(testSchema, data); expect(result.success).toBe(false); expect((result as any).errors).toEqual(expect.arrayContaining([ 'email: Invalid email format', 'password: Password must be at least 12 characters long', 'company: Company name is required', ])); }); it('should handle non-ZodError errors gracefully', () => { const mockSchema = { parse: () => { throw new Error('Some unexpected error'); } } as any; const result = validateInput(mockSchema, {}); expect(result.success).toBe(false); expect((result as any).errors).toEqual(['Invalid input']); }); }); });