|
1 | 1 | import {act, fireEvent, screen} from '@testing-library/react-native'; |
2 | 2 | import {MFA_TEST_SCENARIO_NAME} from 'tests/utils/mfa/flowFixtures'; |
3 | 3 | import getWalkedPaths from 'tests/utils/mfa/flowPaths'; |
4 | | -import {getMfaControls, renderMfaUi} from 'tests/utils/mfa/realUi/harness'; |
| 4 | +import renderMfaUi from 'tests/utils/mfa/realUi/harness'; |
5 | 5 | import {pendingModalClose, resetMfaUiMocks} from 'tests/utils/mfa/realUi/mocks'; |
6 | 6 | import type * as MfaRealUiMocks from 'tests/utils/mfa/realUi/mocks'; |
7 | 7 | import getSettleableLeafStates from 'tests/utils/mfa/settleableLeafStates'; |
@@ -47,37 +47,41 @@ type MfaEventType = MfaEvent['type']; |
47 | 47 |
|
48 | 48 | type MfaEventExecutor = () => Promise<void>; |
49 | 49 |
|
| 50 | +type ExecuteScenario = ReturnType<typeof renderMfaUi>['executeScenario']; |
| 51 | + |
50 | 52 | /** |
51 | 53 | * Maps every machine event to the action that produces it in the rendered app, such as a button press |
52 | 54 | * 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. |
| 55 | + * clause makes a machine event without an executor fail compilation. The executors act on a concrete |
| 56 | + * render, so each test builds them from its own `executeScenario`. |
54 | 57 | */ |
55 | 58 | /* eslint-disable @typescript-eslint/naming-convention -- keys mirror the machine's event type union. */ |
56 | | -const mfaEventExecutors = { |
57 | | - INIT: async () => { |
58 | | - await act(async () => { |
59 | | - await getMfaControls().executeScenario(MFA_TEST_SCENARIO_NAME); |
60 | | - }); |
61 | | - await waitForBatchedUpdatesWithAct(); |
62 | | - // The initial screen's `onLayout` does not fire in jsdom, so the test calls the same handler to flush the |
63 | | - // buffered navigation. |
64 | | - act(() => handleInitialScreenLayout()); |
65 | | - await waitForBatchedUpdatesWithAct(); |
66 | | - }, |
67 | | - CLOSE_MODAL: async () => { |
68 | | - fireEvent.press(screen.getByTestId(CONFIRM_BUTTON_TEST_ID)); |
69 | | - await waitForBatchedUpdatesWithAct(); |
70 | | - }, |
71 | | - MODAL_CLOSED: async () => { |
72 | | - act(() => pendingModalClose.run()); |
73 | | - await waitForBatchedUpdatesWithAct(); |
74 | | - }, |
75 | | -} satisfies Record<MfaEventType, MfaEventExecutor>; |
| 59 | +function createMfaEventExecutors(executeScenario: ExecuteScenario) { |
| 60 | + return { |
| 61 | + INIT: async () => { |
| 62 | + await act(async () => { |
| 63 | + await executeScenario(MFA_TEST_SCENARIO_NAME); |
| 64 | + }); |
| 65 | + await waitForBatchedUpdatesWithAct(); |
| 66 | + // The initial screen's `onLayout` does not fire in jsdom, so the test calls the same handler to flush the |
| 67 | + // buffered navigation. |
| 68 | + act(() => handleInitialScreenLayout()); |
| 69 | + await waitForBatchedUpdatesWithAct(); |
| 70 | + }, |
| 71 | + CLOSE_MODAL: async () => { |
| 72 | + fireEvent.press(screen.getByTestId(CONFIRM_BUTTON_TEST_ID)); |
| 73 | + await waitForBatchedUpdatesWithAct(); |
| 74 | + }, |
| 75 | + MODAL_CLOSED: async () => { |
| 76 | + act(() => pendingModalClose.run()); |
| 77 | + await waitForBatchedUpdatesWithAct(); |
| 78 | + }, |
| 79 | + } satisfies Record<MfaEventType, MfaEventExecutor>; |
| 80 | +} |
76 | 81 | /* eslint-enable @typescript-eslint/naming-convention */ |
77 | 82 |
|
78 | 83 | // Dot-path state keys let `matchesState` target nested leaves such as `open.outcome.success`. |
79 | 84 | const testConfig = { |
80 | | - events: mfaEventExecutors, |
81 | 85 | states: { |
82 | 86 | [MFA_STATE.CLOSED]: () => { |
83 | 87 | expect(screen.queryAllByTestId(MODAL_BACKDROP_TEST_ID)).toHaveLength(0); |
@@ -131,9 +135,9 @@ describe('the real MFA modal matches the machine at every step of every generate |
131 | 135 | }); |
132 | 136 |
|
133 | 137 | it.each(walkedPathTestCases)('$title', async ({path}) => { |
134 | | - renderMfaUi(); |
| 138 | + const {executeScenario} = renderMfaUi(); |
135 | 139 | await waitForBatchedUpdatesWithAct(); |
136 | | - await path.test(testConfig); |
| 140 | + await path.test({...testConfig, events: createMfaEventExecutors(executeScenario)}); |
137 | 141 | }); |
138 | 142 | }); |
139 | 143 |
|
|
0 commit comments