60 lines
4.2 KiB
TypeScript
60 lines
4.2 KiB
TypeScript
import { fireEvent, render, screen, waitFor } from '@testing-library/react'
|
|
import DetailJobRecovery from './DetailJobRecovery'
|
|
import type { DetailJob } from '@/lib/detail-generator/types'
|
|
|
|
const requestId = 'a1111111-1111-4111-8111-111111111111'
|
|
const fixture = (recovery = { canQuery: true, canContinue: false, needsRequestId: false }): DetailJob => ({ id: 'job-1', projectId: 'project-1', ownerId: 'owner-1', kind: 'analyze', status: 'unknown', checkpoint: {}, payload: {}, requestId, error: '原结果待核查', progress: 40, createdAt: '', updatedAt: '', recovery })
|
|
beforeEach(() => { global.fetch = jest.fn(async () => ({ ok: true, json: async () => ({ job: fixture() }) })) as any })
|
|
|
|
test('querying the original result sends one recovery action and never requests a new analysis', async () => {
|
|
const updated = jest.fn().mockResolvedValue(undefined)
|
|
render(<DetailJobRecovery job={fixture()} onUpdated={updated} />)
|
|
const button = screen.getByRole('button', { name: '取回原结果' })
|
|
fireEvent.click(button); fireEvent.click(button)
|
|
await waitFor(() => expect(updated).toHaveBeenCalledTimes(1))
|
|
expect(global.fetch).toHaveBeenCalledTimes(1)
|
|
expect((global.fetch as jest.Mock).mock.calls[0][0]).toBe('/api/detail-generator/jobs/job-1/recover')
|
|
expect(JSON.parse((global.fetch as jest.Mock).mock.calls[0][1].body)).toEqual({ action: 'query' })
|
|
expect(screen.getByText(/未留存仍需核查/)).toBeVisible()
|
|
})
|
|
|
|
test('recovered analysis requires an explicit continuation and does not resend the original request ID', async () => {
|
|
render(<DetailJobRecovery job={fixture({ canQuery: false, canContinue: true, needsRequestId: false })} onUpdated={jest.fn().mockResolvedValue(undefined)} />)
|
|
expect(global.fetch).not.toHaveBeenCalled()
|
|
expect(screen.getByText(/将调用文案模型,不重复分析/)).toBeVisible()
|
|
fireEvent.click(screen.getByRole('button', { name: '继续文案' }))
|
|
await waitFor(() => expect(global.fetch).toHaveBeenCalledTimes(1))
|
|
expect(JSON.parse((global.fetch as jest.Mock).mock.calls[0][1].body)).toEqual({ action: 'continue' })
|
|
expect(screen.queryByRole('button', { name: '取回原结果' })).not.toBeInTheDocument()
|
|
})
|
|
|
|
test('a missing request ID is requested explicitly and only a valid original UUID is accepted', async () => {
|
|
render(<DetailJobRecovery job={{ ...fixture({ canQuery: true, canContinue: false, needsRequestId: true }), requestId: null }} onUpdated={jest.fn().mockResolvedValue(undefined)} />)
|
|
const field = screen.getByRole('textbox', { name: '原客户请求编号' })
|
|
expect(screen.getByRole('button', { name: '取回原结果' })).toBeDisabled()
|
|
fireEvent.change(field, { target: { value: requestId } })
|
|
fireEvent.click(screen.getByRole('button', { name: '取回原结果' }))
|
|
await waitFor(() => expect(global.fetch).toHaveBeenCalledTimes(1))
|
|
expect(JSON.parse((global.fetch as jest.Mock).mock.calls[0][1].body)).toEqual({ action: 'query', requestId })
|
|
})
|
|
|
|
test('recovery failure preserves the input; refreshing state makes no second recovery submission', async () => {
|
|
const updated = jest.fn().mockResolvedValue(undefined)
|
|
;(global.fetch as jest.Mock).mockResolvedValue({ ok: false, status: 503, json: async () => ({ error: '查询暂时中断,原请求仍待核查' }) })
|
|
render(<DetailJobRecovery job={{ ...fixture({ canQuery: true, canContinue: false, needsRequestId: true }), requestId: null }} onUpdated={updated} />)
|
|
fireEvent.change(screen.getByRole('textbox'), { target: { value: requestId } })
|
|
fireEvent.click(screen.getByRole('button', { name: '取回原结果' }))
|
|
expect(await screen.findByRole('alert')).toHaveTextContent('仍待核查')
|
|
expect(screen.getByRole('textbox')).toHaveValue(requestId)
|
|
fireEvent.click(screen.getByRole('button', { name: '刷新状态' }))
|
|
expect(updated).toHaveBeenCalledTimes(1)
|
|
expect(global.fetch).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
test('unsaved edits disable recovery rather than replacing the current draft', () => {
|
|
render(<DetailJobRecovery job={fixture()} dirty onUpdated={jest.fn()} />)
|
|
expect(screen.getByRole('button', { name: '取回原结果' })).toBeDisabled()
|
|
expect(screen.getByText(/撤销未保存修改/)).toBeVisible()
|
|
expect(global.fetch).not.toHaveBeenCalled()
|
|
})
|