🧹 cleanup additional question

This commit is contained in:
Chowdhury Foysal Ahamed
2026-07-16 18:37:33 +02:00
parent 68b62607b7
commit d8d87052da
3 changed files with 34 additions and 114 deletions
@@ -793,10 +793,10 @@ function OptionCard({
} }
/** /**
* Qualifying questions shown when the NCII reason is selected. US residents * Qualifying question shown when the NCII reason is selected. The depicted
* reporting imagery of themselves (or on behalf of the person depicted) are * person (or their authorized representative) is directed to the external
* directed to the external NCII report form; everyone else continues * NCII report form; everyone else continues with the normal in-app
* with the normal in-app submission. * submission.
*/ */
function NciiQualification({ function NciiQualification({
ncii, ncii,
@@ -811,31 +811,17 @@ function NciiQualification({
return ( return (
<View style={[a.gap_md]}> <View style={[a.gap_md]}>
<YesNoQuestion <YesNoQuestion
testID="report:ncii:residesInUS" testID="report:ncii:isDepicted"
question={l`Do you reside in the United States?`} question={l`Are you the person depicted, or an authorized representative acting on behalf of the person depicted?`}
value={ncii.residesInUS} value={ncii.isDepicted}
onAnswer={answer => { onAnswer={answer => {
dispatch({ dispatch({
type: 'answerNciiQuestion', type: 'answerNciiQuestion',
question: 'residesInUS', question: 'isDepicted',
answer, answer,
}) })
}} }}
/> />
{ncii.residesInUS === true && (
<YesNoQuestion
testID="report:ncii:isDepicted"
question={l`Are you the person depicted, or an authorized representative acting on behalf of the person depicted?`}
value={ncii.isDepicted}
onAnswer={answer => {
dispatch({
type: 'answerNciiQuestion',
question: 'isDepicted',
answer,
})
}}
/>
)}
{outcome === 'externalForm' && ( {outcome === 'externalForm' && (
<Link <Link
to={NCII_FORM} to={NCII_FORM}
@@ -29,22 +29,16 @@ describe('getNciiQualificationOutcome', () => {
expect(getNciiQualificationOutcome(undefined)).toBeUndefined() expect(getNciiQualificationOutcome(undefined)).toBeUndefined()
}) })
it('is pending until questions are answered', () => { it('is pending until the question is answered', () => {
expect(getNciiQualificationOutcome({})).toBe('pending') expect(getNciiQualificationOutcome({})).toBe('pending')
expect(getNciiQualificationOutcome({residesInUS: true})).toBe('pending')
}) })
it('directs US residents depicted in the imagery to the external form', () => { it('directs the depicted person to the external form', () => {
expect( expect(getNciiQualificationOutcome({isDepicted: true})).toBe('externalForm')
getNciiQualificationOutcome({residesInUS: true, isDepicted: true}),
).toBe('externalForm')
}) })
it('directs everyone else to in-app submission', () => { it('directs everyone else to in-app submission', () => {
expect(getNciiQualificationOutcome({residesInUS: false})).toBe('inApp') expect(getNciiQualificationOutcome({isDepicted: false})).toBe('inApp')
expect(
getNciiQualificationOutcome({residesInUS: true, isDepicted: false}),
).toBe('inApp')
}) })
}) })
@@ -64,33 +58,8 @@ describe('reducer NCII qualification', () => {
expect(state.ncii).toBeUndefined() expect(state.ncii).toBeUndefined()
}) })
it('advances to step 3 for non-US residents', () => { it('holds at step 2 for the depicted person (external form)', () => {
let state = selectNciiOption() let state = selectNciiOption()
state = reducer(state, {
type: 'answerNciiQuestion',
question: 'residesInUS',
answer: false,
})
expect(state.activeStepIndex1).toBe(3)
})
it('holds at step 2 for US residents until the second answer', () => {
let state = selectNciiOption()
state = reducer(state, {
type: 'answerNciiQuestion',
question: 'residesInUS',
answer: true,
})
expect(state.activeStepIndex1).toBe(2)
})
it('holds at step 2 for depicted US residents (external form)', () => {
let state = selectNciiOption()
state = reducer(state, {
type: 'answerNciiQuestion',
question: 'residesInUS',
answer: true,
})
state = reducer(state, { state = reducer(state, {
type: 'answerNciiQuestion', type: 'answerNciiQuestion',
question: 'isDepicted', question: 'isDepicted',
@@ -100,13 +69,8 @@ describe('reducer NCII qualification', () => {
expect(state.activeStepIndex1).toBe(2) expect(state.activeStepIndex1).toBe(2)
}) })
it('advances to step 3 for non-depicted US residents', () => { it('advances to step 3 when not the depicted person', () => {
let state = selectNciiOption() let state = selectNciiOption()
state = reducer(state, {
type: 'answerNciiQuestion',
question: 'residesInUS',
answer: true,
})
state = reducer(state, { state = reducer(state, {
type: 'answerNciiQuestion', type: 'answerNciiQuestion',
question: 'isDepicted', question: 'isDepicted',
@@ -115,52 +79,31 @@ describe('reducer NCII qualification', () => {
expect(state.activeStepIndex1).toBe(3) expect(state.activeStepIndex1).toBe(3)
}) })
it('resets the second answer when the first changes', () => { it('does not advance past a pending question when a labeler is auto-selected', () => {
let state = selectNciiOption() let state = selectNciiOption()
state = reducer(state, { state = reducer(state, {
type: 'answerNciiQuestion', type: 'selectLabeler',
question: 'residesInUS', labeler: {} as AppBskyLabelerDefs.LabelerViewDetailed,
answer: true, })
expect(state.activeStepIndex1).toBe(2)
})
it('skips to step 4 when the answer resolves after labeler auto-selection', () => {
let state = selectNciiOption()
state = reducer(state, {
type: 'selectLabeler',
labeler: {} as AppBskyLabelerDefs.LabelerViewDetailed,
}) })
state = reducer(state, { state = reducer(state, {
type: 'answerNciiQuestion', type: 'answerNciiQuestion',
question: 'isDepicted', question: 'isDepicted',
answer: true,
})
state = reducer(state, {
type: 'answerNciiQuestion',
question: 'residesInUS',
answer: true,
})
expect(state.ncii?.isDepicted).toBeUndefined()
expect(state.activeStepIndex1).toBe(2)
})
it('does not advance past pending questions when a labeler is auto-selected', () => {
let state = selectNciiOption()
state = reducer(state, {
type: 'selectLabeler',
labeler: {} as AppBskyLabelerDefs.LabelerViewDetailed,
})
expect(state.activeStepIndex1).toBe(2)
})
it('skips to step 4 when answers resolve after labeler auto-selection', () => {
let state = selectNciiOption()
state = reducer(state, {
type: 'selectLabeler',
labeler: {} as AppBskyLabelerDefs.LabelerViewDetailed,
})
state = reducer(state, {
type: 'answerNciiQuestion',
question: 'residesInUS',
answer: false, answer: false,
}) })
expect(state.activeStepIndex1).toBe(4) expect(state.activeStepIndex1).toBe(4)
}) })
it('clears NCII state when the reason or category is cleared', () => { it('clears NCII state when the reason or category is cleared', () => {
let state = selectNciiOption() const state = selectNciiOption()
expect(reducer(state, {type: 'clearOption'}).ncii).toBeUndefined() expect(reducer(state, {type: 'clearOption'}).ncii).toBeUndefined()
expect(reducer(state, {type: 'clearCategory'}).ncii).toBeUndefined() expect(reducer(state, {type: 'clearCategory'}).ncii).toBeUndefined()
}) })
@@ -10,7 +10,6 @@ import {
} from '#/components/moderation/ReportDialog/utils/useReportOptions' } from '#/components/moderation/ReportDialog/utils/useReportOptions'
export type NciiQualification = { export type NciiQualification = {
residesInUS?: boolean
isDepicted?: boolean isDepicted?: boolean
} }
@@ -23,28 +22,24 @@ export type ReportState = {
activeStepIndex1: number activeStepIndex1: number
error?: string error?: string
/** /**
* Present while the selected reason is NCII. Tracks answers to the * Present while the selected reason is NCII. Tracks the answer to the
* qualifying questions that determine whether the report should go through * qualifying question that determines whether the report should go through
* the external NCII report form instead of in-app submission. * the external NCII report form instead of in-app submission.
*/ */
ncii?: NciiQualification ncii?: NciiQualification
} }
/** /**
* Resolves the NCII qualifying questions into an outcome. US residents who * Resolves the NCII qualifying question into an outcome. The depicted person
* are the depicted person (or their authorized representative) are directed * (or their authorized representative) is directed to the external NCII
* to the external NCII report form; everyone else proceeds with the * report form; everyone else proceeds with the normal in-app submission.
* normal in-app submission.
*/ */
export function getNciiQualificationOutcome( export function getNciiQualificationOutcome(
ncii?: NciiQualification, ncii?: NciiQualification,
): 'pending' | 'externalForm' | 'inApp' | undefined { ): 'pending' | 'externalForm' | 'inApp' | undefined {
if (!ncii) return undefined if (!ncii) return undefined
if (ncii.residesInUS === false) return 'inApp' if (ncii.isDepicted === true) return 'externalForm'
if (ncii.residesInUS === true) { if (ncii.isDepicted === false) return 'inApp'
if (ncii.isDepicted === true) return 'externalForm'
if (ncii.isDepicted === false) return 'inApp'
}
return 'pending' return 'pending'
} }
@@ -142,10 +137,6 @@ export function reducer(state: ReportState, action: ReportAction): ReportState {
} }
case 'answerNciiQuestion': { case 'answerNciiQuestion': {
const ncii = {...state.ncii, [action.question]: action.answer} const ncii = {...state.ncii, [action.question]: action.answer}
// the second question only applies to US residents
if (action.question === 'residesInUS') {
ncii.isDepicted = undefined
}
return { return {
...state, ...state,
ncii, ncii,