481e2fe825
以后端 @Valid 注解为唯一真相源,建立 VALIDATION 常量映射, 统一前后端验证规则,消除 roleSort 类不一致问题。
78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { VALIDATION, getRules, getInitialValue, type ValidationField } from '@/constants/validation-rules'
|
|
|
|
describe('validation-rules', () => {
|
|
describe('VALIDATION', () => {
|
|
const requiredFields: ValidationField[] = [
|
|
'username', 'password', 'email', 'phone',
|
|
'roleName', 'roleKey', 'roleSort',
|
|
'menuName', 'dictName', 'dictType', 'dictLabel', 'dictValue',
|
|
'configName', 'configKey', 'configValue',
|
|
'noticeTitle', 'noticeContent',
|
|
'deptName',
|
|
]
|
|
|
|
it.each(requiredFields)('%s should have at least one rule', (field) => {
|
|
expect(VALIDATION[field].rules.length).toBeGreaterThan(0)
|
|
})
|
|
|
|
it('username should require 3-50 alphanumeric/underscore/dash', () => {
|
|
const rules = VALIDATION.username.rules
|
|
expect(rules.some((r) => 'required' in r && r.required)).toBe(true)
|
|
expect(rules.some((r) => 'min' in r && r.min === 3)).toBe(true)
|
|
expect(rules.some((r) => 'max' in r && r.max === 50)).toBe(true)
|
|
expect(rules.some((r) => 'pattern' in r)).toBe(true)
|
|
})
|
|
|
|
it('password should require 8-20 with uppercase, lowercase, digit', () => {
|
|
const rules = VALIDATION.password.rules
|
|
expect(rules.some((r) => 'required' in r && r.required)).toBe(true)
|
|
expect(rules.some((r) => 'min' in r && r.min === 8)).toBe(true)
|
|
expect(rules.some((r) => 'max' in r && r.max === 20)).toBe(true)
|
|
expect(rules.some((r) => 'pattern' in r)).toBe(true)
|
|
})
|
|
|
|
it('roleSort should have initialValue 1 and min 1', () => {
|
|
expect(VALIDATION.roleSort.initialValue).toBe(1)
|
|
const rules = VALIDATION.roleSort.rules
|
|
expect(rules.some((r) => 'type' in r && r.type === 'number' && 'min' in r && r.min === 1)).toBe(true)
|
|
})
|
|
|
|
it('menuSort should have initialValue 0 and min 0', () => {
|
|
expect(VALIDATION.menuSort.initialValue).toBe(0)
|
|
})
|
|
|
|
it('deptName should require 1-100 chars', () => {
|
|
const rules = VALIDATION.deptName.rules
|
|
expect(rules.some((r) => 'required' in r && r.required)).toBe(true)
|
|
expect(rules.some((r) => 'min' in r && r.min === 1)).toBe(true)
|
|
expect(rules.some((r) => 'max' in r && r.max === 100)).toBe(true)
|
|
})
|
|
|
|
it('deptSort should have initialValue 0', () => {
|
|
expect(VALIDATION.deptSort.initialValue).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('getRules', () => {
|
|
it('should return a copy of rules array', () => {
|
|
const rules1 = getRules('username')
|
|
const rules2 = getRules('username')
|
|
expect(rules1).not.toBe(rules2)
|
|
expect(rules1).toEqual(rules2)
|
|
})
|
|
})
|
|
|
|
describe('getInitialValue', () => {
|
|
it('should return initialValue for fields that have it', () => {
|
|
expect(getInitialValue('roleSort')).toBe(1)
|
|
expect(getInitialValue('menuSort')).toBe(0)
|
|
expect(getInitialValue('deptSort')).toBe(0)
|
|
})
|
|
|
|
it('should return undefined for fields without initialValue', () => {
|
|
expect(getInitialValue('username')).toBeUndefined()
|
|
})
|
|
})
|
|
})
|