Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
85 lines
2.2 KiB
TypeScript
85 lines
2.2 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import { showFormValidationToast } from '@/lib/formValidationToast'
|
|
import { addToast } from '@/lib/toast'
|
|
import { texts } from '@/texts'
|
|
|
|
vi.mock('@/lib/toast', () => ({
|
|
addToast: vi.fn(),
|
|
}))
|
|
|
|
describe('showFormValidationToast', () => {
|
|
beforeEach(() => {
|
|
vi.mocked(addToast).mockClear()
|
|
})
|
|
|
|
it('shows the first nested field message', () => {
|
|
showFormValidationToast({
|
|
profile: {
|
|
mobile: { type: 'pattern', message: 'شماره موبایل معتبر نیست' },
|
|
},
|
|
})
|
|
|
|
expect(addToast).toHaveBeenCalledWith({
|
|
title: texts.common.formIncomplete,
|
|
description: 'شماره موبایل معتبر نیست',
|
|
color: 'danger',
|
|
})
|
|
})
|
|
|
|
it('does not recurse into FieldError.ref circular graphs', () => {
|
|
const parent: { child?: object } = {}
|
|
const input = { tagName: 'INPUT', parentNode: parent }
|
|
|
|
parent.child = input
|
|
|
|
expect(() => {
|
|
showFormValidationToast({
|
|
mobile: {
|
|
type: 'pattern',
|
|
message: '',
|
|
ref: input as never,
|
|
},
|
|
code: { type: 'required', message: 'کد را وارد کنید' },
|
|
})
|
|
}).not.toThrow()
|
|
|
|
expect(addToast).toHaveBeenCalledWith({
|
|
title: texts.common.formIncomplete,
|
|
description: 'کد را وارد کنید',
|
|
color: 'danger',
|
|
})
|
|
})
|
|
|
|
it('tolerates self-referential error trees without throwing', () => {
|
|
const errors: Record<string, unknown> = {}
|
|
|
|
errors.root = errors
|
|
errors.mobile = { type: 'required', message: 'شماره موبایل را وارد کنید' }
|
|
|
|
expect(() => {
|
|
showFormValidationToast(errors as never)
|
|
}).not.toThrow()
|
|
|
|
expect(addToast).toHaveBeenCalledWith({
|
|
title: texts.common.formIncomplete,
|
|
description: 'شماره موبایل را وارد کنید',
|
|
color: 'danger',
|
|
})
|
|
})
|
|
|
|
it('falls back when no message can be read safely', () => {
|
|
const cyclic: Record<string, unknown> = {}
|
|
|
|
cyclic.self = cyclic
|
|
|
|
showFormValidationToast(cyclic as never)
|
|
|
|
expect(addToast).toHaveBeenCalledWith({
|
|
title: texts.common.formIncomplete,
|
|
description: texts.common.formValidationDefault,
|
|
color: 'danger',
|
|
})
|
|
})
|
|
})
|