d3ro-voice/apps/mobile-rn/__tests__/content-report-sheet.test.tsx
2026-08-29 18:33:45 +09:00

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()
})
})