85 lines
4.2 KiB
TypeScript
85 lines
4.2 KiB
TypeScript
|
|
import { describe, expect, it } from 'vitest'
|
||
|
|
import { validateFieldValues, type FieldDefLike } from '../app/utils/fieldValidation'
|
||
|
|
|
||
|
|
/** ชุดนิยามครบทุก type ที่ระบบรองรับ (ตาม TemplateField: text/number/date) */
|
||
|
|
const defs: FieldDefLike[] = [
|
||
|
|
{ key: 'employee_name', label: 'ชื่อพนักงาน', type: 'text', isRequired: true },
|
||
|
|
{ key: 'position', label: 'ตำแหน่ง', type: 'text', isRequired: false },
|
||
|
|
{ key: 'salary', label: 'เงินเดือน', type: 'number', isRequired: false },
|
||
|
|
{ key: 'start_date', label: 'วันเริ่มงาน', type: 'date', isRequired: false },
|
||
|
|
]
|
||
|
|
|
||
|
|
describe('validateFieldValues — dynamic form ของหน้าสร้างเอกสาร (FR-10)', () => {
|
||
|
|
it('ค่าครบและถูก type ทุก field → ไม่มี issue', () => {
|
||
|
|
const issues = validateFieldValues(defs, {
|
||
|
|
employee_name: 'สมหญิง รักงาน',
|
||
|
|
position: 'วิศวกรซอฟต์แวร์',
|
||
|
|
salary: '75000',
|
||
|
|
start_date: '2026-08-01',
|
||
|
|
})
|
||
|
|
expect(issues).toEqual([])
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('required', () => {
|
||
|
|
it('required ขาด (ไม่มี key) → issue ชี้ field นั้น', () => {
|
||
|
|
const issues = validateFieldValues(defs, { salary: '1' })
|
||
|
|
expect(issues).toHaveLength(1)
|
||
|
|
expect(issues[0].key).toBe('employee_name')
|
||
|
|
expect(issues[0].message).toContain('ชื่อพนักงาน')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('required ว่างเปล่า / มีแต่วรรค → issue (ค่าที่เป็นช่องว่างนับเป็นว่าง)', () => {
|
||
|
|
expect(validateFieldValues(defs, { employee_name: '' })[0].key).toBe('employee_name')
|
||
|
|
expect(validateFieldValues(defs, { employee_name: ' ' })[0].key).toBe('employee_name')
|
||
|
|
})
|
||
|
|
|
||
|
|
it('ไม่ required และว่าง → ผ่าน (ไม่บังคับ type ด้วย)', () => {
|
||
|
|
const issues = validateFieldValues(defs, {
|
||
|
|
employee_name: 'มีชื่อ',
|
||
|
|
position: '',
|
||
|
|
salary: '',
|
||
|
|
start_date: '',
|
||
|
|
})
|
||
|
|
expect(issues).toEqual([])
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('type = number (ตรง NumberStyles.Number ของ backend)', () => {
|
||
|
|
it.each(['1', '-5', '+3.14', '1,234.56', '0'])('ค่า %s ผ่าน', (value) => {
|
||
|
|
expect(validateFieldValues(defs, { employee_name: 'x', salary: value })).toEqual([])
|
||
|
|
})
|
||
|
|
|
||
|
|
it.each(['abc', '1.2.3', '12.', '.5', '1e5', '--2'])('ค่า %s เป็น issue', (value) => {
|
||
|
|
const issues = validateFieldValues(defs, { employee_name: 'x', salary: value })
|
||
|
|
expect(issues).toHaveLength(1)
|
||
|
|
expect(issues[0].message).toContain('ตัวเลข')
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
describe('type = date', () => {
|
||
|
|
it.each(['2026-08-01', '2026-08-01T09:00:00Z', '2026-12-31'])('ค่า %s ผ่าน', (value) => {
|
||
|
|
expect(validateFieldValues(defs, { employee_name: 'x', start_date: value })).toEqual([])
|
||
|
|
})
|
||
|
|
|
||
|
|
it.each(['not-a-date', '31/02/2026 ผิดรูป', 'สิงหาคม'])('ค่า %s เป็น issue', (value) => {
|
||
|
|
const issues = validateFieldValues(defs, { employee_name: 'x', start_date: value })
|
||
|
|
expect(issues).toHaveLength(1)
|
||
|
|
expect(issues[0].message).toContain('วันที่')
|
||
|
|
})
|
||
|
|
})
|
||
|
|
|
||
|
|
it('ผิดหลาย field พร้อมกัน → issue เรียงตามลำดับ defs และ issue ละ field เดียว', () => {
|
||
|
|
const issues = validateFieldValues(defs, {
|
||
|
|
employee_name: 'มีชื่อแล้ว', // required ผ่าน เหลือดูเฉพาะ type ของ salary/start_date
|
||
|
|
salary: 'abc',
|
||
|
|
start_date: 'วันนี้',
|
||
|
|
})
|
||
|
|
expect(issues.map((i) => i.key)).toEqual(['salary', 'start_date'])
|
||
|
|
})
|
||
|
|
|
||
|
|
it('type อื่นที่ไม่รู้จัก (เช่น จาก backend อนาคต) → ไม่ validate เพิ่ม', () => {
|
||
|
|
const futureDefs: FieldDefLike[] = [{ key: 'x', label: 'อะไรใหม่', type: 'email', isRequired: false }]
|
||
|
|
expect(validateFieldValues(futureDefs, { x: 'ไม่ใช่ email' })).toEqual([])
|
||
|
|
})
|
||
|
|
})
|