1- import { configure , screen , within } from '@testing-library/react' ;
2- import { beforeAll , describe , expect , it , onTestFinished } from 'vitest' ;
1+ import { Clerk } from '@clerk/clerk-js' ;
2+ import { ClerkContextProvider } from '@clerk/shared/react' ;
3+ import { act , configure , render , screen , within } from '@testing-library/react' ;
4+ import React from 'react' ;
5+ import { beforeAll , describe , expect , it , onTestFinished , vi } from 'vitest' ;
36import { page } from 'vitest/browser' ;
47
5- import { serveFapi } from '../../../__tests__/feature/fake-fapi' ;
8+ import { publishableKey , serveFapi } from '../../../__tests__/feature/fake-fapi' ;
69import { fapiClient , fapiEnvironment , fapiSession , fapiUser } from '../../../__tests__/feature/fapi' ;
710import { renderWithClerk } from '../../../__tests__/feature/render' ;
11+ import { MosaicProvider } from '../../../mosaic-provider' ;
812
913beforeAll ( async ( ) => {
1014 await import ( '../user-profile.modal-content' ) ;
@@ -30,6 +34,26 @@ function strictMode() {
3034 onTestFinished ( ( ) => configure ( { reactStrictMode : false } ) ) ;
3135}
3236
37+ function PatchesHistoryOnMount ( {
38+ onReplaceState,
39+ children,
40+ } : {
41+ onReplaceState : ( url : string ) => void ;
42+ children : React . ReactNode ;
43+ } ) {
44+ React . useEffect ( ( ) => {
45+ const original = window . history . replaceState . bind ( window . history ) ;
46+ window . history . replaceState = ( state , unused , url ) => {
47+ onReplaceState ( String ( url ) ) ;
48+ original ( state , unused , url ) ;
49+ } ;
50+ return ( ) => {
51+ window . history . replaceState = original ;
52+ } ;
53+ } , [ onReplaceState ] ) ;
54+ return children ;
55+ }
56+
3357describe ( 'UserProfile modal return' , ( ) => {
3458 it . each ( [
3559 { name : 'renders normally' , strict : false } ,
@@ -73,6 +97,59 @@ describe('UserProfile modal return', () => {
7397 expect ( window . history . state ) . toEqual ( { router : 'state' } ) ;
7498 } ) ;
7599
100+ it ( 'clears the param through a history patch that a parent installs while mounting' , async ( ) => {
101+ serve ( ) ;
102+ visit ( '?__clerk_mosaic_modal=user-profile%2Faccount' ) ;
103+ const onReplaceState = vi . fn ( ) ;
104+ const clerk = new Clerk ( publishableKey ( ) ) ;
105+
106+ const tree = ( ) => (
107+ < PatchesHistoryOnMount onReplaceState = { onReplaceState } >
108+ < ClerkContextProvider
109+ clerk = { clerk }
110+ clerkStatus = { clerk . status }
111+ >
112+ < MosaicProvider >
113+ < p > Page</ p >
114+ </ MosaicProvider >
115+ </ ClerkContextProvider >
116+ </ PatchesHistoryOnMount >
117+ ) ;
118+ const view = render ( tree ( ) ) ;
119+ await act ( ( ) => clerk . load ( ) ) ;
120+ view . rerender ( tree ( ) ) ;
121+
122+ await screen . findByRole ( 'dialog' ) ;
123+ expect ( window . location . search ) . toBe ( '' ) ;
124+ expect ( onReplaceState ) . toHaveBeenCalledTimes ( 1 ) ;
125+ } ) ;
126+
127+ it ( 'keeps history state that is not a plain object when it clears the param' , async ( ) => {
128+ serve ( ) ;
129+ visit ( '?__clerk_mosaic_modal=user-profile%2Faccount' ) ;
130+ window . history . replaceState ( [ 'router' , 'state' ] , '' ) ;
131+
132+ await renderWithClerk ( < p > Page</ p > ) ;
133+
134+ await screen . findByRole ( 'dialog' ) ;
135+ expect ( window . location . search ) . toBe ( '' ) ;
136+ expect ( window . history . state ) . toEqual ( [ 'router' , 'state' ] ) ;
137+ } ) ;
138+
139+ it ( 'keeps an array as an array when it drops the Next.js marker' , async ( ) => {
140+ serve ( ) ;
141+ visit ( '?__clerk_mosaic_modal=user-profile%2Faccount' ) ;
142+ window . history . replaceState ( Object . assign ( [ 'router' , 'state' ] , { __NA : true } ) , '' ) ;
143+
144+ await renderWithClerk ( < p > Page</ p > ) ;
145+
146+ await screen . findByRole ( 'dialog' ) ;
147+ expect ( window . location . search ) . toBe ( '' ) ;
148+ expect ( Array . isArray ( window . history . state ) ) . toBe ( true ) ;
149+ expect ( window . history . state ) . toEqual ( [ 'router' , 'state' ] ) ;
150+ expect ( window . history . state ) . not . toHaveProperty ( '__NA' ) ;
151+ } ) ;
152+
76153 it ( 'ignores an unknown value' , async ( ) => {
77154 serve ( ) ;
78155 visit ( '?__clerk_mosaic_modal=organization-profile%2Fgeneral&tab=connections' ) ;
0 commit comments