d3ro-voice/apps/mobile-rn/__tests__/content-report-sheet.test.tsx
Yun Chan 5ca3709b32
Some checks failed
ci / 정본·보안·린트·타입·테스트 (push) Failing after 50s
ci / 워크스페이스 빌드 검증 (push) Has been skipped
ci / Supabase Edge Functions + Cloudflare Worker (push) Successful in 20s
ci / .NET API 서버 테스트 (push) Successful in 12s
deploy-site / deploy (push) Successful in 39s
ci / 모바일 린트·타입·Jest (push) Failing after 3h10m31s
feat: add mobile shell and unified search
2026-09-28 23:23:36 +09:00

90 lines
3.1 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', () => {
const { d3roNativeDarkPalette } = jest.requireActual('@d3ro/ui-native') as typeof import('@d3ro/ui-native')
return {
useMobilePreferences: () => ({ palette: d3roNativeDarkPalette }),
}
})
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()
})
})