feat(family): 表单校验抽纯函数并补单测
This commit is contained in:
parent
9d1ea0abbc
commit
95a67ae412
|
|
@ -6,6 +6,7 @@ import { addCared, type EmergencyContact } from '@/api/family'
|
|||
import { MAX_EMERGENCY_CONTACTS, MAX_FAMILY_NAME_LEN } from '@/constants/family'
|
||||
import { navigateBack } from '@/utils/navigation'
|
||||
import { showToast } from '@/utils/toast'
|
||||
import { validateContactForm } from './validate'
|
||||
import styles from './add.module.scss'
|
||||
|
||||
const emptyContact = (): EmergencyContact => ({
|
||||
|
|
@ -35,14 +36,9 @@ export default function ContactAdd() {
|
|||
|
||||
const submit = async () => {
|
||||
if (submitting) return
|
||||
if (!name.trim() || !idNumber.trim() || !address.trim()) {
|
||||
showToast('请填写完整')
|
||||
return
|
||||
}
|
||||
// 跳过完全未填的联系人卡,只提交有内容的
|
||||
const filled = contacts.filter((c) => c.name.trim() || c.phone.trim())
|
||||
if (filled.some((c) => !c.name.trim() || !c.phone.trim())) {
|
||||
showToast('请完整填写联系人')
|
||||
const result = validateContactForm({ name, idNumber, address, contacts })
|
||||
if (!result.ok) {
|
||||
showToast(result.error)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -53,7 +49,7 @@ export default function ContactAdd() {
|
|||
name: name.trim(),
|
||||
idNumber: idNumber.trim(),
|
||||
address: address.trim(),
|
||||
contacts: filled
|
||||
contacts: result.contacts
|
||||
})
|
||||
showToast('添加成功')
|
||||
setTimeout(() => navigateBack(), 500)
|
||||
|
|
@ -74,7 +70,7 @@ export default function ContactAdd() {
|
|||
<Input
|
||||
className={styles.input}
|
||||
placeholder="请输入最多 10 个字"
|
||||
maxLength={MAX_FAMILY_NAME_LEN}
|
||||
maxlength={MAX_FAMILY_NAME_LEN}
|
||||
value={name}
|
||||
onInput={(e) => setName(e.detail.value)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import type { EmergencyContact } from '@/api/family'
|
||||
|
||||
export interface ContactFormInput {
|
||||
name: string
|
||||
idNumber: string
|
||||
address: string
|
||||
contacts: EmergencyContact[]
|
||||
}
|
||||
|
||||
export type ValidateResult =
|
||||
| { ok: true; contacts: EmergencyContact[] }
|
||||
| { ok: false; error: string }
|
||||
|
||||
// 必填项齐全且联系人卡要么空白(忽略)要么填全,才允许提交
|
||||
export function validateContactForm(input: ContactFormInput): ValidateResult {
|
||||
if (!input.name.trim() || !input.idNumber.trim() || !input.address.trim()) {
|
||||
return { ok: false, error: '请填写完整' }
|
||||
}
|
||||
|
||||
const filled = input.contacts.filter((c) => c.name.trim() || c.phone.trim())
|
||||
if (filled.some((c) => !c.name.trim() || !c.phone.trim())) {
|
||||
return { ok: false, error: '请完整填写联系人' }
|
||||
}
|
||||
|
||||
return { ok: true, contacts: filled }
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
import { describe, it, expect } from 'vitest'
|
||||
import { validateContactForm, type ContactFormInput } from '@/pages/family/contact/validate'
|
||||
import type { EmergencyContact } from '@/api/family'
|
||||
|
||||
const contact = (over: Partial<EmergencyContact> = {}): EmergencyContact => ({
|
||||
id: 'c1',
|
||||
name: '',
|
||||
phone: '',
|
||||
relation: '',
|
||||
...over
|
||||
})
|
||||
|
||||
const form = (over: Partial<ContactFormInput> = {}): ContactFormInput => ({
|
||||
name: '王奶奶',
|
||||
idNumber: '440301194001010000',
|
||||
address: '深圳市南山区',
|
||||
contacts: [],
|
||||
...over
|
||||
})
|
||||
|
||||
describe('添加关爱对象表单校验', () => {
|
||||
it('必填齐全返回 ok', () => {
|
||||
const result = validateContactForm(form())
|
||||
expect(result.ok).toBe(true)
|
||||
if (result.ok) expect(result.contacts).toEqual([])
|
||||
})
|
||||
|
||||
it('任一必填缺失/空白报 请填写完整', () => {
|
||||
const r1 = validateContactForm(form({ name: '' }))
|
||||
const r2 = validateContactForm(form({ idNumber: ' ' }))
|
||||
const r3 = validateContactForm(form({ address: '' }))
|
||||
expect(!r1.ok && r1.error).toBe('请填写完整')
|
||||
expect(!r2.ok && r2.error).toBe('请填写完整')
|
||||
expect(!r3.ok && r3.error).toBe('请填写完整')
|
||||
})
|
||||
|
||||
it('空白联系人卡被过滤,不阻断提交', () => {
|
||||
const result = validateContactForm(form({ contacts: [contact()] }))
|
||||
expect(result.ok).toBe(true)
|
||||
if (result.ok) expect(result.contacts).toEqual([])
|
||||
})
|
||||
|
||||
it('联系人只填了姓名或电话时报 请完整填写联系人', () => {
|
||||
const r1 = validateContactForm(form({ contacts: [contact({ name: '张女士' })] }))
|
||||
const r2 = validateContactForm(form({ contacts: [contact({ phone: '13800138000' })] }))
|
||||
expect(!r1.ok && r1.error).toBe('请完整填写联系人')
|
||||
expect(!r2.ok && r2.error).toBe('请完整填写联系人')
|
||||
})
|
||||
|
||||
it('姓名电话齐全的联系人保留在结果中', () => {
|
||||
const c = contact({ id: 'c9', name: '张女士', phone: '13800138000', relation: '配偶' })
|
||||
const result = validateContactForm(form({ contacts: [c] }))
|
||||
expect(result.ok).toBe(true)
|
||||
if (result.ok) expect(result.contacts).toEqual([c])
|
||||
})
|
||||
})
|
||||
Loading…
Reference in New Issue