65 lines
4.0 KiB
TypeScript
65 lines
4.0 KiB
TypeScript
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
||
import CertificateReportUploader from './CertificateReportUploader'
|
||
import { chunkUpload } from '@/lib/chunk-upload'
|
||
import { DEFAULT_CERTIFICATE_REPORT_USAGE_RULES } from '@/lib/certificate-report'
|
||
|
||
jest.mock('@/lib/chunk-upload', () => ({ chunkUpload: jest.fn() }))
|
||
|
||
test('成品只填写 SPU 时不能上传,须先填写报告名称', () => {
|
||
const originalFetch = global.fetch
|
||
global.fetch = jest.fn()
|
||
try {
|
||
render(<CertificateReportUploader onSuccess={jest.fn()} onCancel={jest.fn()} productCategories={[]} />)
|
||
fireEvent.change(screen.getByLabelText('SPU'), { target: { value: 'SPU-001' } })
|
||
fireEvent.click(screen.getByRole('button', { name: '创建分享素材' }))
|
||
expect(screen.getByText('请填写报告名称 / 检测对象')).toBeInTheDocument()
|
||
expect(global.fetch).not.toHaveBeenCalled()
|
||
} finally {
|
||
global.fetch = originalFetch
|
||
}
|
||
})
|
||
|
||
test.each([['成品', true], ['成品', false], ['原材料', true], ['原材料', false]] as const)('%s上传说明与日期:手动到期时间 %s', async (kind, manualExpiry) => {
|
||
const originalFetch = global.fetch
|
||
jest.useFakeTimers().setSystemTime(new Date('2026-09-27T12:00:00'))
|
||
const { container } = render(<CertificateReportUploader onSuccess={jest.fn()} onCancel={jest.fn()} productCategories={[{ id: '1', name: '板材' }]} />)
|
||
try {
|
||
expect(screen.getByLabelText('成品')).toBeChecked()
|
||
fireEvent.click(screen.getByLabelText(kind))
|
||
const reportTitleInput = screen.getByLabelText('报告名称 / 检测对象 *')
|
||
expect(reportTitleInput).toBeRequired()
|
||
if (kind === '成品') {
|
||
expect(reportTitleInput.compareDocumentPosition(screen.getByLabelText('SPU')) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
|
||
}
|
||
expect(screen.getByText('上传后将作为素材名称显示')).toBeInTheDocument()
|
||
fireEvent.change(screen.getByLabelText(/报告名称 \/ 检测对象/), { target: { value: '板材检测报告' } })
|
||
fireEvent.change(screen.getByLabelText('品类 *'), { target: { value: '板材' } })
|
||
fireEvent.change(screen.getByLabelText('证书编号 *'), { target: { value: 'CMA-001' } })
|
||
fireEvent.click(screen.getByRole('button', { name: /证书检测日期/ }))
|
||
fireEvent.click(screen.getByRole('button', { name: '2026年9月23日' }))
|
||
expect(screen.getByLabelText('证书到期时间(选填)')).toHaveTextContent('默认 2027-09-23')
|
||
if (manualExpiry) {
|
||
fireEvent.click(screen.getByRole('button', { name: /证书到期时间/ }))
|
||
fireEvent.click(screen.getByRole('button', { name: '2027年9月24日' }))
|
||
}
|
||
expect(screen.queryByLabelText('证书使用说明 *')).not.toBeInTheDocument()
|
||
expect(screen.getAllByRole('textbox').filter((input) => input.tagName === 'TEXTAREA')).toHaveLength(1)
|
||
expect(screen.getByLabelText('检测报告使用规则说明 *')).toHaveValue(DEFAULT_CERTIFICATE_REPORT_USAGE_RULES)
|
||
const pdf = new File(['%PDF-1.4'], '报告.pdf', { type: 'application/pdf' })
|
||
fireEvent.change(container.querySelector('input[type="file"]')!, { target: { files: [pdf] } })
|
||
jest.useRealTimers()
|
||
global.fetch = jest.fn().mockResolvedValue({ ok: true, json: async () => ({ materialId: 'report-1' }) })
|
||
;(chunkUpload as jest.Mock).mockResolvedValue({ uploadId: 'file-1' })
|
||
fireEvent.click(screen.getByRole('button', { name: '创建分享素材' }))
|
||
await waitFor(() => expect(global.fetch).toHaveBeenCalledTimes(2))
|
||
const [url, init] = (global.fetch as jest.Mock).mock.calls[0]
|
||
expect(url).toBe('/api/materials/upload/certificate-report/init')
|
||
const payload = JSON.parse(init.body)
|
||
expect(payload).toMatchObject({ reportKind: kind, certificateTestedOn: '2026-09-23', certificateExpiresOn: manualExpiry ? '2027-09-24' : '', reportUsageRules: DEFAULT_CERTIFICATE_REPORT_USAGE_RULES })
|
||
expect(payload).not.toHaveProperty('certificateUsageInstructions')
|
||
} finally {
|
||
jest.useRealTimers()
|
||
global.fetch = originalFetch
|
||
}
|
||
})
|