1+ import { loadClerkJSScript , loadClerkUIScript } from '@clerk/shared/loadClerkJsScript' ;
12import type { Resources , UnsubscribeCallback } from '@clerk/shared/types' ;
2- import { afterAll , beforeAll , describe , expect , it , vi } from 'vitest' ;
3+ import { afterAll , afterEach , beforeAll , beforeEach , describe , expect , it , vi } from 'vitest' ;
34
45import { IsomorphicClerk } from '../isomorphicClerk' ;
56
@@ -12,7 +13,9 @@ vi.mock('@clerk/shared/loadClerkJsScript', () => ({
1213describe ( 'isomorphicClerk' , ( ) => {
1314 beforeAll ( ( ) => {
1415 vi . useFakeTimers ( ) ;
16+ } ) ;
1517
18+ beforeEach ( ( ) => {
1619 // Set up minimal global Clerk objects to prevent errors during initialization
1720 ( global as any ) . Clerk = {
1821 load : vi . fn ( ) . mockResolvedValue ( undefined ) ,
@@ -21,13 +24,18 @@ describe('isomorphicClerk', () => {
2124 ( global as any ) . __internal_ClerkUICtor = vi . fn ( ) ;
2225 } ) ;
2326
24- afterAll ( ( ) => {
25- vi . useRealTimers ( ) ;
27+ afterEach ( ( ) => {
28+ vi . mocked ( loadClerkJSScript ) . mockClear ( ) ;
29+ vi . mocked ( loadClerkUIScript ) . mockClear ( ) ;
2630 // Clean up globals
2731 delete ( global as any ) . Clerk ;
2832 delete ( global as any ) . __internal_ClerkUICtor ;
2933 } ) ;
3034
35+ afterAll ( ( ) => {
36+ vi . useRealTimers ( ) ;
37+ } ) ;
38+
3139 it ( 'instantiates a IsomorphicClerk instance' , ( ) => {
3240 expect ( ( ) => {
3341 new IsomorphicClerk ( { publishableKey : 'pk_test_XXX' } ) ;
@@ -117,4 +125,79 @@ describe('isomorphicClerk', () => {
117125 expect ( listenerCallHistory ) . toEqual ( [ ] ) ;
118126 expect ( listenerCallHistory . length ) . toBe ( 0 ) ;
119127 } ) ;
128+
129+ describe ( '__internal_* URL precedence' , ( ) => {
130+ it ( '__internal_clerkJSUrl causes script loading even when Clerk prop is provided' , async ( ) => {
131+ const mockClerkCtor = vi . fn ( ) . mockImplementation ( ( ) => ( {
132+ load : vi . fn ( ) . mockResolvedValue ( undefined ) ,
133+ loaded : false ,
134+ } ) ) ;
135+ // Make the mock pass the isConstructor check
136+ mockClerkCtor . prototype = { } ;
137+
138+ const clerk = new IsomorphicClerk ( {
139+ publishableKey : 'pk_test_XXX' ,
140+ Clerk : mockClerkCtor as any ,
141+ __internal_clerkJSUrl : 'https://staging.clerk.com/clerk.js' ,
142+ } ) ;
143+
144+ // Trigger loading by accessing the private method
145+ await ( clerk as any ) . getClerkJsEntryChunk ( ) ;
146+
147+ // Should load from URL, not use the bundled constructor
148+ expect ( loadClerkJSScript ) . toHaveBeenCalled ( ) ;
149+ expect ( mockClerkCtor ) . not . toHaveBeenCalled ( ) ;
150+ } ) ;
151+
152+ it ( '__internal_clerkUIUrl causes script loading even when ui.ClerkUI prop is provided' , async ( ) => {
153+ const mockClerkUI = vi . fn ( ) ;
154+
155+ const clerk = new IsomorphicClerk ( {
156+ publishableKey : 'pk_test_XXX' ,
157+ ui : { ClerkUI : mockClerkUI } as any ,
158+ __internal_clerkUIUrl : 'https://staging.clerk.com/clerk-ui.js' ,
159+ } ) ;
160+
161+ const result = await ( clerk as any ) . getClerkUIEntryChunk ( ) ;
162+
163+ // Should load from URL, not return the bundled ClerkUI
164+ expect ( loadClerkUIScript ) . toHaveBeenCalled ( ) ;
165+ expect ( result ) . not . toBe ( mockClerkUI ) ;
166+ } ) ;
167+
168+ it ( 'Clerk prop is used when no __internal_clerkJSUrl is set' , async ( ) => {
169+ const mockInstance = {
170+ load : vi . fn ( ) . mockResolvedValue ( undefined ) ,
171+ loaded : false ,
172+ } ;
173+ const mockClerkCtor = vi . fn ( ) . mockImplementation ( ( ) => mockInstance ) ;
174+ mockClerkCtor . prototype = { } ;
175+
176+ const clerk = new IsomorphicClerk ( {
177+ publishableKey : 'pk_test_XXX' ,
178+ Clerk : mockClerkCtor as any ,
179+ } ) ;
180+
181+ await ( clerk as any ) . getClerkJsEntryChunk ( ) ;
182+
183+ // Should use the bundled constructor, not load from URL
184+ expect ( loadClerkJSScript ) . not . toHaveBeenCalled ( ) ;
185+ expect ( mockClerkCtor ) . toHaveBeenCalled ( ) ;
186+ } ) ;
187+
188+ it ( 'ui.ClerkUI is used when no __internal_clerkUIUrl is set' , async ( ) => {
189+ const mockClerkUI = vi . fn ( ) ;
190+
191+ const clerk = new IsomorphicClerk ( {
192+ publishableKey : 'pk_test_XXX' ,
193+ ui : { ClerkUI : mockClerkUI } as any ,
194+ } ) ;
195+
196+ const result = await ( clerk as any ) . getClerkUIEntryChunk ( ) ;
197+
198+ // Should return the bundled ClerkUI, not load from URL
199+ expect ( loadClerkUIScript ) . not . toHaveBeenCalled ( ) ;
200+ expect ( result ) . toBe ( mockClerkUI ) ;
201+ } ) ;
202+ } ) ;
120203} ) ;
0 commit comments