Skip to content

Commit 4fbad10

Browse files
committed
test(mfa): pin the INIT executor to the single test scenario
Recovering the scenario from the step event existed for the era of two INIT fixtures, which ended when the unobserved payload variant was dropped. With one fixture the recovery added a type guard, an impossible throw, and a step-typed executor signature without carrying any information, so the executor now starts MFA_TEST_SCENARIO_NAME directly and every executor is a plain thunk.
1 parent 5a0988f commit 4fbad10

2 files changed

Lines changed: 8 additions & 25 deletions

File tree

tests/unit/components/MultifactorAuthentication/machine/graphTraversal/viewMatchesMachine.test.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {act, fireEvent, screen} from '@testing-library/react-native';
2-
import {isTestScenarioInitEvent} from 'tests/utils/mfa/flowFixtures';
2+
import {MFA_TEST_SCENARIO_NAME} from 'tests/utils/mfa/flowFixtures';
33
import getWalkedPaths from 'tests/utils/mfa/flowPaths';
44
import {getMfaControls, renderMfaUi} from 'tests/utils/mfa/realUi/harness';
55
import {pendingModalClose, resetMfaUiMocks} from 'tests/utils/mfa/realUi/mocks';
@@ -45,25 +45,18 @@ const MFA_STATE = CONST.MULTIFACTOR_AUTHENTICATION.MFA_STATE;
4545

4646
type MfaEventType = MfaEvent['type'];
4747

48-
/**
49-
* The event carries only its `type` here because `xstate/graph` erases the remaining fields from the
50-
* executor's step type. The INIT executor recovers them through `isTestScenarioInitEvent`.
51-
*/
52-
type MfaEventExecutor = (step: {event: {type: MfaEventType}}) => Promise<void>;
48+
type MfaEventExecutor = () => Promise<void>;
5349

5450
/**
55-
* `INIT` starts a flow through the public API, using the scenario from the step's own event.
56-
* `MODAL_CLOSED` runs the navigator's teardown callback. `satisfies Record<MfaEventType, ...>`
57-
* requires an explicit executor for every machine event.
51+
* Maps every machine event to the action that produces it in the rendered app, such as a button press
52+
* or a navigator callback. The walk drives each path step through this table, and the `satisfies`
53+
* clause makes a machine event without an executor fail compilation.
5854
*/
5955
/* eslint-disable @typescript-eslint/naming-convention -- keys mirror the machine's event type union. */
6056
const mfaEventExecutors = {
61-
INIT: async ({event}) => {
62-
if (!isTestScenarioInitEvent(event)) {
63-
throw new Error(`The INIT executor received an event outside the test-scenario fixtures: ${JSON.stringify(event)}`);
64-
}
57+
INIT: async () => {
6558
await act(async () => {
66-
await getMfaControls().executeScenario(event.scenarioName);
59+
await getMfaControls().executeScenario(MFA_TEST_SCENARIO_NAME);
6760
});
6861
await waitForBatchedUpdatesWithAct();
6962
// The initial screen's `onLayout` does not fire in jsdom, so the test calls the same handler to flush the

tests/utils/mfa/flowFixtures.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,5 @@ function createInitEvent(): MultifactorAuthenticationInitEvent<typeof MFA_TEST_S
1616
};
1717
}
1818

19-
/**
20-
* Narrows a traversal event to the test-scenario INIT fixture shape. The scenario-name check is enough,
21-
* because {@link createInitEvent} is the only place that builds INIT events for the traversal. The
22-
* parameter accepts any typed event, because `xstate/graph` erases everything but `type` from the
23-
* event an executor receives.
24-
*/
25-
function isTestScenarioInitEvent(event: {type: string}): event is MultifactorAuthenticationInitEvent<typeof MFA_TEST_SCENARIO_NAME> {
26-
return event.type === 'INIT' && 'scenarioName' in event && event.scenarioName === MFA_TEST_SCENARIO_NAME;
27-
}
28-
2919
export default createInitEvent;
30-
export {isTestScenarioInitEvent, MFA_TEST_SCENARIO_NAME};
20+
export {MFA_TEST_SCENARIO_NAME};

0 commit comments

Comments
 (0)