1+ import * as NodeModule from "node:module" ;
12import type { NavigationState , PartialState } from "@react-navigation/native" ;
23import { expect , it , vi } from "vite-plus/test" ;
34
5+ const requireFromNative = NodeModule . createRequire (
6+ NodeModule . createRequire ( import . meta. url ) . resolve ( "@react-navigation/native/package.json" ) ,
7+ ) ;
8+ const requireFromCore = NodeModule . createRequire (
9+ requireFromNative . resolve ( "@react-navigation/core/package.json" ) ,
10+ ) ;
11+ const { getActionFromState, getStateFromPath } = requireFromNative ( "@react-navigation/core" ) as {
12+ readonly getActionFromState : typeof import ( "@react-navigation/native" ) . getActionFromState ;
13+ readonly getStateFromPath : typeof import ( "@react-navigation/native" ) . getStateFromPath ;
14+ } ;
15+ const { StackRouter } = requireFromCore ( "@react-navigation/routers" ) as {
16+ readonly StackRouter : typeof import ( "@react-navigation/native" ) . StackRouter ;
17+ } ;
18+
419const harness = vi . hoisted ( ( ) => ( {
520 pair : vi . fn ( ) ,
621 goBack : vi . fn ( ) ,
@@ -20,7 +35,12 @@ const harness = vi.hoisted(() => ({
2035 deferred : null as Array < ( ) => void > | null ,
2136} ) ) ;
2237
23- vi . mock ( "@react-navigation/native" , ( ) => ( { StackActions : { replace : vi . fn ( ) } } ) ) ;
38+ vi . mock ( "@react-navigation/native" , ( ) => ( {
39+ StackActions : { replace : vi . fn ( ) } ,
40+ CommonActions : {
41+ replaceParams : ( params : object ) => ( { type : "REPLACE_PARAMS" , payload : { params } } ) ,
42+ } ,
43+ } ) ) ;
2444vi . mock ( "../../state/use-remote-environment-registry" , ( ) => ( {
2545 pairEnvironment : harness . pair ,
2646} ) ) ;
@@ -47,6 +67,7 @@ import { appAtomRegistry } from "../../state/atom-registry";
4767import {
4868 autoConnectReport ,
4969 devAutoConnectAttemptAtom ,
70+ pairingFormLinkAction ,
5071 startDevAutoConnect ,
5172} from "./devAutoConnect" ;
5273
@@ -191,3 +212,45 @@ it("a success that waited for navigation leaves a newer link's form open", async
191212 expect ( harness . goBack ) . not . toHaveBeenCalled ( ) ;
192213 expect ( harness . dispatch ) . not . toHaveBeenCalled ( ) ;
193214} ) ;
215+
216+ it ( "a pairing link fills the pairing form already on screen instead of stacking a second one" , ( ) => {
217+ const linking = {
218+ initialRouteName : "Home" ,
219+ screens : {
220+ Home : "" ,
221+ Settings : "settings" ,
222+ SettingsEnvironmentNew : "settings/environment-new" ,
223+ ConnectionsNew : "connections/new" ,
224+ } ,
225+ } ;
226+ const router = StackRouter ( { } ) ;
227+ const options = {
228+ routeNames : Object . keys ( linking . screens ) ,
229+ routeParamList : { } ,
230+ routeGetIdList : { } ,
231+ } ;
232+ // Settings > Environments > Add environment, as the user opened it.
233+ const open = router . getRehydratedState (
234+ {
235+ index : 2 ,
236+ routes : [ { name : "Home" } , { name : "Settings" } , { name : "SettingsEnvironmentNew" } ] ,
237+ } ,
238+ options ,
239+ ) ;
240+ const link = getStateFromPath (
241+ `connections/new?pairingUrl=${ encodeURIComponent ( PAIRING_URL ) } ` ,
242+ linking ,
243+ ) ! ;
244+ const action = pairingFormLinkAction ( link , open ) ?? getActionFromState ( link , linking ) ! ;
245+ const next = router . getStateForAction ( open , { target : open . key , ...action } , options ) ;
246+
247+ expect ( next ?. routes . map ( ( route ) => route . name ) ) . toEqual ( [
248+ "Home" ,
249+ "Settings" ,
250+ "SettingsEnvironmentNew" ,
251+ ] ) ;
252+ expect ( next ?. routes . at ( - 1 ) ) . toMatchObject ( {
253+ key : open . routes [ 2 ] ! . key ,
254+ params : { pairingUrl : PAIRING_URL } ,
255+ } ) ;
256+ } ) ;
0 commit comments