@@ -33,18 +33,11 @@ const mockContinueWithQuote = jest.fn();
3333const mockUseContinueWithQuoteOptions = jest . fn ( ) ;
3434let mockIsFocused = true ;
3535
36- // Holds the most recent 'beforeRemove' listener registered against the
37- // mocked navigation object. Tests fire it directly to exercise the
38- // production beforeRemove path without spinning up a real navigator.
39- // The listener now reads `e.data.action.type` so it can ignore RESET
40- // stack-rebuilds; tests pass an event arg accordingly.
4136interface BeforeRemoveEvent {
4237 data : { action : { type : string } } ;
4338}
4439let registeredBeforeRemoveListener : ( ( e ?: BeforeRemoveEvent ) => void ) | null =
4540 null ;
46- // Default event passed when a test wants to simulate a user back/swipe — any
47- // non-RESET action type triggers the close path.
4841const DEFAULT_GO_BACK_EVENT : BeforeRemoveEvent = {
4942 data : { action : { type : 'GO_BACK' } } ,
5043} ;
@@ -214,8 +207,6 @@ describe('HeadlessHost', () => {
214207 } ) ;
215208
216209 it ( 'renders only a transparent container — no header, spinner, or buttons after Phase 9.5' , ( ) => {
217- // The Phase 9.5 contract: the consumer (TPC / MMPay) renders all
218- // user-visible loading UI. The Host is a stack base only.
219210 const session = seedSession ( buildAggregatorQuote ( ) ) ;
220211 renderHost ( { headlessSessionId : session . id } ) ;
221212 expect (
@@ -225,7 +216,6 @@ describe('HeadlessHost', () => {
225216 'pointerEvents' ,
226217 'none' ,
227218 ) ;
228- // No legacy chrome should be present.
229219 expect ( screen . queryByText ( / C a n c e l / i) ) . not . toBeOnTheScreen ( ) ;
230220 expect ( screen . queryByText ( / P r e p a r i n g / i) ) . not . toBeOnTheScreen ( ) ;
231221 expect ( screen . queryByText ( / n o l o n g e r a c t i v e / i) ) . not . toBeOnTheScreen ( ) ;
@@ -238,8 +228,6 @@ describe('HeadlessHost', () => {
238228 } ) ;
239229
240230 it ( 'renders the transparent container even with no session — no UI affordances surface to the user' , ( ) => {
241- // Pre-Phase 9.5 this rendered a "no session" message; the consumer
242- // now owns that surface.
243231 renderHost ( { headlessSessionId : 'headless-buy-not-real' } ) ;
244232 expect (
245233 screen . getByTestId ( HEADLESS_HOST_CONTAINER_TEST_ID ) ,
@@ -342,12 +330,8 @@ describe('HeadlessHost', () => {
342330 it ( 'skips orchestration when the session has already been cancelled' , async ( ) => {
343331 const quote = buildAggregatorQuote ( ) ;
344332 const session = seedSession ( quote ) ;
345- // Mark the session terminal *before* the screen mounts: the focus
346- // effect must respect that and avoid a stale re-trigger.
347333 closeSession ( session . id , { reason : 'consumer_cancelled' } ) ;
348334 renderHost ( { headlessSessionId : session . id } ) ;
349- // No session left → orchestration short-circuits. The consumer
350- // already received onClose from the closeSession call above.
351335 expect ( mockContinueWithQuote ) . not . toHaveBeenCalled ( ) ;
352336 } ) ;
353337 } ) ;
@@ -421,13 +405,6 @@ describe('HeadlessHost', () => {
421405 expect ( mockContinueWithQuote ) . toHaveBeenCalledTimes ( 1 ) ,
422406 ) ;
423407 unmount ( ) ;
424- // Phase 8: unmount fires the dismissal close because the session
425- // had not reached a terminal status. After unmount the session is
426- // gone from the registry, so the .catch's live-session re-read
427- // short-circuits and does not produce a second onClose or an
428- // onError. (The .catch's `cancelled` flag is independent React
429- // unmount-state protection; this test does not exercise it
430- // directly.)
431408 expect ( callbacks . onClose ) . toHaveBeenCalledTimes ( 1 ) ;
432409 expect ( callbacks . onClose ) . toHaveBeenCalledWith ( {
433410 reason : 'user_dismissed' ,
@@ -454,8 +431,6 @@ describe('HeadlessHost', () => {
454431 } ) ;
455432 expect ( callbacks . onClose ) . toHaveBeenCalledWith ( { reason : 'unknown' } ) ;
456433 expect ( getSession ( session . id ) ) . toBeUndefined ( ) ;
457- // The auth-error path also short-circuits the continue-on-focus effect
458- // — we never want to push EnterEmail again on top of the error message.
459434 expect ( mockContinueWithQuote ) . not . toHaveBeenCalled ( ) ;
460435 } ) ;
461436
@@ -477,17 +452,12 @@ describe('HeadlessHost', () => {
477452 } ,
478453 ) ;
479454 renderHost ( { headlessSessionId : session . id } ) ;
480- // Even though onError throws, the close path still runs and the
481- // session is gone from the registry.
482455 await waitFor ( ( ) => expect ( getSession ( session . id ) ) . toBeUndefined ( ) ) ;
483456 } ) ;
484457 } ) ;
485458
486459 describe ( 'Dismissal (Phase 8 + 9.5)' , ( ) => {
487460 it ( 'registers a beforeRemove listener that synchronously closes the session with user_dismissed' , ( ) => {
488- // Phase 9.5 replaces the old visible Cancel/Back buttons with a
489- // navigation listener so the synchronous close still fires when the
490- // user backs out — even with no chrome to render.
491461 const quote = buildAggregatorQuote ( ) ;
492462 const session = seedSession ( quote ) ;
493463 const callbacks = session . callbacks ;
@@ -498,7 +468,6 @@ describe('HeadlessHost', () => {
498468 ) ;
499469 expect ( typeof registeredBeforeRemoveListener ) . toBe ( 'function' ) ;
500470
501- // Fire the listener like React Navigation would on a back gesture.
502471 registeredBeforeRemoveListener ?.( DEFAULT_GO_BACK_EVENT ) ;
503472
504473 expect ( callbacks . onClose ) . toHaveBeenCalledTimes ( 1 ) ;
@@ -509,12 +478,6 @@ describe('HeadlessHost', () => {
509478 } ) ;
510479
511480 it ( 'does NOT close the session when beforeRemove fires for a RESET action (stack rebuild guard)' , ( ) => {
512- // Cursor Bugbot — useTransakRouting calls navigation.reset() to
513- // re-pin HEADLESS_HOST at the base when moving to VerifyIdentity /
514- // BasicInfo / Checkout / KycWebview. The reset fires beforeRemove on
515- // the OLD instance, but the session is still in flight; closing it
516- // here would prematurely fire onClose({ reason: 'user_dismissed' })
517- // and break the flow.
518481 const quote = buildAggregatorQuote ( ) ;
519482 const session = seedSession ( quote ) ;
520483 const callbacks = session . callbacks ;
@@ -526,9 +489,6 @@ describe('HeadlessHost', () => {
526489 } ) ;
527490
528491 expect ( callbacks . onClose ) . not . toHaveBeenCalled ( ) ;
529- // The session is still live so useTransakRouting's reset can complete
530- // and re-pin the new HEADLESS_HOST without losing the consumer's
531- // callbacks.
532492 expect ( getSession ( session . id ) ) . toBeDefined ( ) ;
533493 } ) ;
534494
@@ -565,15 +525,10 @@ describe('HeadlessHost', () => {
565525 expect ( mockContinueWithQuote ) . toHaveBeenCalledTimes ( 1 ) ,
566526 ) ;
567527
568- // Simulate Phase 6: useTransakRouting / Checkout fires
569- // closeSession({ reason: 'completed' }) after onOrderCreated.
570528 closeSession ( session . id , { reason : 'completed' } ) ;
571529 expect ( callbacks . onClose ) . toHaveBeenCalledTimes ( 1 ) ;
572530 expect ( callbacks . onClose ) . toHaveBeenCalledWith ( { reason : 'completed' } ) ;
573531
574- // beforeRemove fires too (React Navigation always fires it on screen
575- // removal), then unmount cleanup runs. Both find the session gone and
576- // no-op.
577532 registeredBeforeRemoveListener ?.( DEFAULT_GO_BACK_EVENT ) ;
578533 unmount ( ) ;
579534
@@ -589,24 +544,19 @@ describe('HeadlessHost', () => {
589544 nativeFlowError : 'OTP rejected' ,
590545 } ) ;
591546
592- // Phase 7: nativeFlowError handler funnels through failSession →
593- // closeSession({ reason: 'unknown' }, { terminalStatus: 'failed' }).
594547 expect ( callbacks . onClose ) . toHaveBeenCalledTimes ( 1 ) ;
595548 expect ( callbacks . onClose ) . toHaveBeenCalledWith ( { reason : 'unknown' } ) ;
596549
597550 registeredBeforeRemoveListener ?.( DEFAULT_GO_BACK_EVENT ) ;
598551 unmount ( ) ;
599552
600- // Both follow-up paths re-read, see nothing, no-op.
601553 expect ( callbacks . onClose ) . toHaveBeenCalledTimes ( 1 ) ;
602554 } ) ;
603555
604556 it ( 'no-ops on unmount when the host mounted against an already-terminated session' , ( ) => {
605557 const quote = buildAggregatorQuote ( ) ;
606558 const session = seedSession ( quote ) ;
607559 const callbacks = session . callbacks ;
608- // Cancel before the screen mounts; the Phase 8 dismissal cleanup must
609- // not produce a spurious second onClose.
610560 closeSession ( session . id , { reason : 'consumer_cancelled' } ) ;
611561 expect ( callbacks . onClose ) . toHaveBeenCalledTimes ( 1 ) ;
612562 expect ( callbacks . onClose ) . toHaveBeenCalledWith ( {
0 commit comments