96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
import React from 'react'
|
|
import { act, create, type ReactTestRenderer } from 'react-test-renderer'
|
|
|
|
const mockSubmitAiContentReport = jest.fn()
|
|
const mockClose = jest.fn()
|
|
|
|
jest.mock('@d3ro/i18n', () => ({
|
|
useI18n: () => ({ t: (key: string, params?: Record<string, string>) => (
|
|
params?.id === undefined ? key : `${key}:${params.id}`
|
|
) }),
|
|
}))
|
|
jest.mock('../src/lib/preferences-context', () => ({
|
|
useMobilePreferences: () => ({
|
|
palette: {
|
|
bg: { app: '#000', card: '#181818', inset: '#202020', sidebar: '#111', cardHover: '#222' },
|
|
text: { primary: '#fff', secondary: '#ddd', muted: '#999', onAccent: '#000' },
|
|
border: { subtle: '#333', default: '#444', strong: '#666' },
|
|
accent: { main: '#fc0', dim: '#332b00', pressed: '#db0' },
|
|
tag: { red: '#f66', green: '#5d8' },
|
|
shadow: '#000',
|
|
},
|
|
}),
|
|
}))
|
|
jest.mock('../src/lib/random-id', () => ({
|
|
createUuidV4: () => '22222222-2222-4222-8222-222222222222',
|
|
}))
|
|
jest.mock('../src/features/reporting/content-report-service', () => {
|
|
const actual = jest.requireActual('../src/features/reporting/content-report-service')
|
|
return {
|
|
...actual,
|
|
submitAiContentReport: (...args: unknown[]) => mockSubmitAiContentReport(...args),
|
|
}
|
|
})
|
|
|
|
import ContentReportSheet from '../src/components/ContentReportSheet'
|
|
|
|
async function renderSheet(): Promise<ReactTestRenderer> {
|
|
let renderer: ReactTestRenderer
|
|
await act(async () => {
|
|
renderer = create(
|
|
<ContentReportSheet
|
|
visible
|
|
accessToken="access-token"
|
|
target={{
|
|
sourceType: 'talk_response',
|
|
generationId: '11111111-1111-4111-8111-111111111111',
|
|
snapshot: 'unsafe AI output',
|
|
}}
|
|
onRequestClose={mockClose}
|
|
/>,
|
|
)
|
|
await Promise.resolve()
|
|
})
|
|
return renderer!
|
|
}
|
|
|
|
describe('ContentReportSheet', () => {
|
|
beforeEach(() => {
|
|
mockClose.mockReset()
|
|
mockSubmitAiContentReport.mockReset().mockResolvedValue({
|
|
reportId: '33333333-3333-4333-8333-333333333333',
|
|
status: 'submitted',
|
|
idempotent: false,
|
|
createdAt: '2026-08-24T08:00:00.000Z',
|
|
})
|
|
})
|
|
|
|
it('requires a reason, submits only the selected output, and shows an in-app receipt', async () => {
|
|
const renderer = await renderSheet()
|
|
const submitBeforeReason = renderer.root.findByProps({ testID: 'content-report-submit' })
|
|
expect(submitBeforeReason.props.disabled).toBe(true)
|
|
|
|
await act(async () => {
|
|
renderer.root.findByProps({ testID: 'content-report-reason-privacy' }).props.onPress()
|
|
renderer.root.findByProps({ testID: 'content-report-comment' }).props.onChangeText('name exposed')
|
|
})
|
|
await act(async () => {
|
|
renderer.root.findByProps({ testID: 'content-report-submit' }).props.onPress()
|
|
await Promise.resolve()
|
|
await Promise.resolve()
|
|
})
|
|
|
|
expect(mockSubmitAiContentReport).toHaveBeenCalledWith({
|
|
accessToken: 'access-token',
|
|
idempotencyKey: '22222222-2222-4222-8222-222222222222',
|
|
generationId: '11111111-1111-4111-8111-111111111111',
|
|
sourceType: 'talk_response',
|
|
reason: 'privacy',
|
|
comment: 'name exposed',
|
|
snapshot: 'unsafe AI output',
|
|
})
|
|
expect(renderer.root.findByProps({ testID: 'content-report-success' })).toBeTruthy()
|
|
expect(renderer.root.findByProps({ testID: 'content-report-receipt' })).toBeTruthy()
|
|
expect(mockClose).not.toHaveBeenCalled()
|
|
})
|
|
})
|