eletrotupi / tcc/ api/tests/errors/validation-error.unit.test.tsc901c35af9c84b6a29e5185545ced1129f33b8f4
1.5 KB | 43 lines Raw
1
import { describe, it, expect } from 'vitest'
2
import { z } from 'zod'
3
import { formatValidationError } from '@app/lib/errors/validationError'
4

5
describe('formatValidationError', () => {
6
  it('keys a single field by its name', () => {
7
    const schema = z.object({ email: z.string().email() })
8
    const parsed = schema.safeParse({ email: 'nope' })
9

10
    if (parsed.success) throw new Error('expected validation to fail')
11

12
    const { error, fields } = formatValidationError(parsed.error)
13

14
    expect(Object.keys(fields)).toEqual(['email'])
15
    expect(typeof fields.email).toBe('string')
16
    expect(fields.email.length).toBeGreaterThan(0)
17
    expect(error).toContain(fields.email)
18
  })
19

20
  it('joins the segments of a nested path with dots', () => {
21
    const schema = z.object({ profile: z.object({ age: z.number() }) })
22
    const parsed = schema.safeParse({ profile: { age: 'x' } })
23

24
    if (parsed.success) throw new Error('expected validation to fail')
25

26
    const { fields } = formatValidationError(parsed.error)
27

28
    expect(Object.keys(fields)).toEqual(['profile.age'])
29
  })
30

31
  it('keeps only the first message for a field', () => {
32
    const schema = z.object({ code: z.string().min(5).regex(/^a/) })
33
    const parsed = schema.safeParse({ code: 'b' })
34

35
    if (parsed.success) throw new Error('expected validation to fail')
36

37
    const { fields } = formatValidationError(parsed.error)
38

39
    expect(parsed.error.issues.length).toBeGreaterThan(1)
40
    expect(fields.code).toBe(parsed.error.issues[0].message)
41
    expect(fields.code).not.toBe(parsed.error.issues[1].message)
42
  })
43
})