eCourt-Doc-Edit/web/test/fieldEditor.spec.ts
Suphonchai Phoonsawat 9bb4a48c00 Phase 10: field editor (FR-14)
เพิ่ม editor ต่อ template field — ผู้ดูแลเลือกรูปแบบช่องกรอกในฟอร์มสร้างเอกสารได้:
text → textbox/textarea, number/date → control ตาม type (presentation metadata
ล้วน — validation ยังยึด Type, ค่า field เป็น string ทั้ง flow, ไม่แตะ generate/sync/add-in)

- Backend: TemplateField.Editor (nullable, null = default ของ type) +
  migration AddTemplateFieldEditor + validate ตาม type ใน PUT templates
  (ค่าไม่รู้จัก/ไม่เข้ากับ type → 400, normalize-on-write, API คืน resolved เสมอ)
- Web: util fieldEditor.ts + editor select หน้าแก้ template (desktop+mobile,
  ซ่อนเมื่อ type มีทางเดียว) + ฟอร์มสร้างเอกสาร render ตาม editor +
  แก้ prefill re-generate ของ field date จาก ISO timestamp เต็ม (input[type=date]
  รับเฉพาะ yyyy-MM-dd เดิมแสดงว่าง)
- Docs: spec v6 (FR-14/AC-17) + plan Phase 10 + sub-plan field-editor.md +
  acceptance-review AC-17 + README/CLAUDE.md
- Tests: backend 60/60 (FieldEditorTests ใหม่ 8 กรณี) · web 46/46 + build ผ่าน

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-22 09:17:15 +07:00

62 lines
3.1 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { dateInputValue, defaultEditor, editorOptions, resolveEditor } from '../app/utils/fieldEditor'
describe('fieldEditor — editor ต่อ field (FR-14)', () => {
describe('defaultEditor', () => {
it('ทุก type มี default ตาม allow-list ของ backend', () => {
expect(defaultEditor('text')).toBe('textbox')
expect(defaultEditor('number')).toBe('number')
expect(defaultEditor('date')).toBe('date')
})
it('type ที่ไม่รู้จัก → textbox (degrade อ่อนโยน)', () => {
expect(defaultEditor('unknown')).toBe('textbox')
})
})
describe('editorOptions', () => {
it('text เลือกได้ 2 แบบ — number/date มีทางเดียว (ซ่อน select)', () => {
expect(editorOptions('text')).toEqual(['textbox', 'textarea'])
expect(editorOptions('number')).toEqual(['number'])
expect(editorOptions('date')).toEqual(['date'])
})
})
describe('resolveEditor — ใช้ตอน render ฟอร์มสร้างเอกสาร', () => {
it('editor ที่เข้ากับ type → ใช้ค่านั้น (text + textarea = ข้อความยาว)', () => {
expect(resolveEditor({ type: 'text', editor: 'textarea' })).toBe('textarea')
expect(resolveEditor({ type: 'text', editor: 'textbox' })).toBe('textbox')
})
it('ไม่มี editor / null → default ของ type (backend เก่าหรือค่า default ที่เก็บ null)', () => {
expect(resolveEditor({ type: 'text' })).toBe('textbox')
expect(resolveEditor({ type: 'text', editor: null })).toBe('textbox')
expect(resolveEditor({ type: 'date', editor: undefined })).toBe('date')
})
it('editor ไม่เข้ากับ type → default ของ type ไม่ throw (กันค่าหลุดจาก API)', () => {
expect(resolveEditor({ type: 'number', editor: 'textarea' })).toBe('number')
expect(resolveEditor({ type: 'text', editor: 'date' })).toBe('textbox')
})
it('type ที่ไม่รู้จัก → textbox', () => {
expect(resolveEditor({ type: 'other', editor: 'whatever' })).toBe('textbox')
})
})
describe('dateInputValue — prefill re-generate ของ field วันที่', () => {
it('ISO timestamp เต็ม (ค่าจาก field sync ของ Word) → เหลือ yyyy-MM-dd ให้ input[type=date] แสดงได้', () => {
expect(dateInputValue('2026-08-20T09:00:00Z')).toBe('2026-08-20')
expect(dateInputValue('2026-08-20T09:00:00+07:00')).toBe('2026-08-20')
})
it('yyyy-MM-dd อยู่แล้ว → คงเดิม', () => {
expect(dateInputValue('2026-08-20')).toBe('2026-08-20')
})
it('ค่าอื่น → คงเดิมให้ validation ของฟอร์มจัดการ', () => {
expect(dateInputValue('20 ส.ค. 2569')).toBe('20 ส.ค. 2569')
expect(dateInputValue('')).toBe('')
})
})
})