import { describe, expect, it } from 'vitest' import { BRAZILIAN_PHONE_DUPLICATE_MESSAGE } from '@/lib/phone' import { contactCitySchema, contactCreateSchema, contactFieldUpdateSchema, contactStateSchema, } from '@/lib/schemas/contact' describe('contactCreateSchema (C139)', () => { it('accepts a full valid ficha', () => { const result = contactCreateSchema.safeParse({ name: 'Maria Silva', email: 'maria@example.com', phones: ['71999990000'], gender: 'feminino', state: 'BA', city: 'Salvador', postalCode: '40000000', }) expect(result.success).toBe(true) }) it('accepts the minimal ficha (name + state)', () => { const result = contactCreateSchema.safeParse({ name: 'Ana Souza', state: 'BA' }) expect(result.success).toBe(true) }) it('rejects a missing state', () => { const result = contactCreateSchema.safeParse({ name: 'Ana Souza' }) expect(result.success).toBe(false) if (!result.success) expect(result.error.issues.some((issue) => issue.path[0] === 'state')).toBe(true) }) it('rejects an unknown gender', () => { expect( contactCreateSchema.safeParse({ name: 'Ana Souza', state: 'BA', gender: 'x' }).success, ).toBe(false) }) it('rejects a single-word name', () => { expect(contactCreateSchema.safeParse({ name: 'Ana', state: 'BA' }).success).toBe(false) }) it('rejects duplicated phones within the same ficha (C112)', () => { const result = contactCreateSchema.safeParse({ name: 'Ana Souza', state: 'BA', phones: ['71999990000', '71999990000'], }) expect(result.success).toBe(false) if (!result.success) { expect( result.error.issues.some((issue) => issue.message === BRAZILIAN_PHONE_DUPLICATE_MESSAGE), ).toBe(true) } }) it('accepts an empty phone list', () => { expect( contactCreateSchema.safeParse({ name: 'Ana Souza', state: 'BA', phones: [] }).success, ).toBe(true) }) }) describe('contactFieldUpdateSchema — C139 variants', () => { it('accepts the city variant', () => { expect( contactFieldUpdateSchema.safeParse({ id: 5, field: 'city', city: 'Camaçari' }).success, ).toBe(true) expect(contactFieldUpdateSchema.safeParse({ id: 5, field: 'city', city: 'C' }).success).toBe( false, ) }) it('transforms an empty postalCode to undefined (clear semantics)', () => { const result = contactFieldUpdateSchema.safeParse({ id: 5, field: 'postalCode', postalCode: '', }) expect(result.success).toBe(true) if (result.success) { const data = result.data as { field: string; postalCode?: string } expect(data.postalCode).toBeUndefined() } }) it('accepts an 8-digit postalCode and rejects a malformed one', () => { expect( contactFieldUpdateSchema.safeParse({ id: 5, field: 'postalCode', postalCode: '42800000' }) .success, ).toBe(true) expect( contactFieldUpdateSchema.safeParse({ id: 5, field: 'postalCode', postalCode: 'abc' }).success, ).toBe(false) }) it('keeps the legacy variants working', () => { expect( contactFieldUpdateSchema.safeParse({ id: 5, field: 'name', name: 'Ana Souza' }).success, ).toBe(true) expect( contactFieldUpdateSchema.safeParse({ id: 5, field: 'phones', phones: ['71999990000'] }) .success, ).toBe(true) }) it('collapses an empty city to undefined in the create ficha (C139 DRY)', () => { const result = contactCreateSchema.safeParse({ name: 'Ana Souza', state: 'BA', city: '' }) expect(result.success).toBe(true) if (result.success) { expect((result.data as { city?: string }).city).toBeUndefined() } }) it('reports the long-city message on the field-update city variant', () => { const result = contactFieldUpdateSchema.safeParse({ id: 5, field: 'city', city: 'a'.repeat(101), }) expect(result.success).toBe(false) if (!result.success) { expect(result.error.issues.some((issue) => issue.message === 'Cidade muito longa')).toBe(true) } }) }) describe('contactStateSchema / contactCitySchema (S9+ DRY consolidation)', () => { it('contactStateSchema accepts a known UF and rejects an unknown one', () => { expect(contactStateSchema.safeParse('BA').success).toBe(true) expect(contactStateSchema.safeParse('XX').success).toBe(false) }) it('contactCitySchema reports the long-city message at the max boundary', () => { expect(contactCitySchema.safeParse('Camaçari').success).toBe(true) const result = contactCitySchema.safeParse('a'.repeat(101)) expect(result.success).toBe(false) if (!result.success) { expect(result.error.issues.some((issue) => issue.message === 'Cidade muito longa')).toBe(true) } }) })