@@ -7,7 +7,9 @@ import { renderHook, waitFor } from '@testing-library/react';
77import { ReactNode , createElement } from 'react' ;
88import * as Sentry from '@sentry/browser' ;
99
10- import { useCmsInfoState } from './hooks' ;
10+ import {
11+ useCmsInfoState
12+ } from './hooks' ;
1113import { AppContext } from './contexts/AppContext' ;
1214
1315// Mock all external dependencies before importing the hook
@@ -45,6 +47,10 @@ jest.mock('../lib/integrations', () => ({
4547
4648jest . mock ( '../lib/nimbus' , ( ) => ( { } ) ) ;
4749
50+ jest . mock ( '../contexts/DynamicLocalizationContext' , ( ) => ( {
51+ useDynamicLocalization : jest . fn ( ) . mockReturnValue ( { currentLocale : 'en-US' } ) ,
52+ } ) ) ;
53+
4854// Mock fetch
4955const mockFetch = jest . fn ( ) ;
5056global . fetch = mockFetch ;
@@ -93,6 +99,17 @@ describe('useCmsInfoState', () => {
9399 ok : true ,
94100 json : jest . fn ( ) . mockResolvedValue ( { customization : 'test' } ) ,
95101 } ) ;
102+
103+ // Reset navigator.language and useDynamicLocalization to English defaults
104+ Object . defineProperty ( navigator , 'language' , {
105+ writable : true ,
106+ value : 'en-US' ,
107+ } ) ;
108+ Object . defineProperty ( navigator , 'languages' , {
109+ writable : true ,
110+ value : [ 'en-US' , 'en' ] ,
111+ } ) ;
112+ require ( '../contexts/DynamicLocalizationContext' ) . useDynamicLocalization . mockReturnValue ( { currentLocale : 'en-US' } ) ;
96113 } ) ;
97114
98115 it ( 'should use default entrypoint when entrypoint is not provided in URL' , async ( ) => {
@@ -239,6 +256,9 @@ describe('useCmsInfoState', () => {
239256 value : [ 'fr-FR' , 'fr' ] ,
240257 } ) ;
241258
259+ // Mock useDynamicLocalization to return non-English locale
260+ require ( '../contexts/DynamicLocalizationContext' ) . useDynamicLocalization . mockReturnValue ( { currentLocale : 'fr-FR' } ) ;
261+
242262 mockUrlQueryData . get . mockImplementation ( ( key : string ) => {
243263 if ( key === 'client_id' ) return '1234567890abcdef' ;
244264 if ( key === 'entrypoint' ) return 'preferences' ;
@@ -249,21 +269,15 @@ describe('useCmsInfoState', () => {
249269 wrapper : MockAppProvider ,
250270 } ) ;
251271
272+ // Wait for the effect to complete
273+ await waitFor ( ( ) => {
274+ expect ( result . current . loading ) . toBe ( false ) ;
275+ } ) ;
276+
252277 // Should not fetch due to non-English locale
253278 expect ( mockFetch ) . not . toHaveBeenCalled ( ) ;
254- expect ( result . current . loading ) . toBe ( false ) ;
255279 expect ( result . current . data ) . toBeUndefined ( ) ;
256280 expect ( result . current . error ) . toBeUndefined ( ) ;
257-
258- // Reset to English for other tests
259- Object . defineProperty ( navigator , 'language' , {
260- writable : true ,
261- value : 'en-US' ,
262- } ) ;
263- Object . defineProperty ( navigator , 'languages' , {
264- writable : true ,
265- value : [ 'en-US' , 'en' ] ,
266- } ) ;
267281 } ) ;
268282
269283 it ( 'should handle fetch errors gracefully' , async ( ) => {
@@ -354,47 +368,106 @@ describe('useCmsInfoState', () => {
354368 ) ;
355369 } ) ;
356370
357- it ( 'should handle various custom entrypoint values' , async ( ) => {
358- const testCases = [
359- 'firefox-toolbar' ,
360- 'fxa_app_menu' ,
361- 'ios_settings_manage' ,
362- 'synced-tabs' ,
363- 'custom.entrypoint-123'
364- ] ;
365-
366- for ( const entrypoint of testCases ) {
367- jest . clearAllMocks ( ) ;
368-
369- mockUrlQueryData . get . mockImplementation ( ( key : string ) => {
370- if ( key === 'client_id' ) return '1234567890abcdef' ;
371- if ( key === 'entrypoint' ) return entrypoint ;
372- return null ;
373- } ) ;
374-
375- mockFetch . mockResolvedValue ( {
376- ok : true ,
377- json : jest . fn ( ) . mockResolvedValue ( { customization : `test-${ entrypoint } ` } ) ,
378- } ) ;
379-
380- const { result } = renderHook ( ( ) => useCmsInfoState ( ) , {
381- wrapper : MockAppProvider ,
382- } ) ;
383-
384- // Wait for the fetch to complete
385- await waitFor ( ( ) => {
386- expect ( result . current . loading ) . toBe ( false ) ;
387- } ) ;
388-
389- // Verify that fetch was called with the correct entrypoint
390- expect ( mockFetch ) . toHaveBeenCalledWith (
391- expect . objectContaining ( {
392- href : `http://localhost:9000/v1/cms/config?clientId=1234567890abcdef&entrypoint=${ entrypoint } ` ,
393- } ) ,
394- expect . any ( Object )
395- ) ;
396-
397- expect ( result . current . data ?. cmsInfo ) . toEqual ( { customization : `test-${ entrypoint } ` } ) ;
398- }
371+ it ( 'should fetch when l10nEnabled is true for any locale' , async ( ) => {
372+ const l10nEnabledConfig = {
373+ ...mockConfig ,
374+ cms : { enabled : true , l10nEnabled : true } ,
375+ } ;
376+
377+ const L10nEnabledProvider = ( { children } : { children : ReactNode } ) =>
378+ createElement ( AppContext . Provider , {
379+ value : { config : l10nEnabledConfig as any , account : undefined , apolloClient : undefined }
380+ } , children ) ;
381+
382+ // Mock non-English locale
383+ require ( '../contexts/DynamicLocalizationContext' ) . useDynamicLocalization . mockReturnValue ( { currentLocale : 'fr-FR' } ) ;
384+ Object . defineProperty ( navigator , 'language' , {
385+ writable : true ,
386+ value : 'fr-FR' ,
387+ } ) ;
388+
389+ mockUrlQueryData . get . mockImplementation ( ( key : string ) => {
390+ if ( key === 'client_id' ) return '1234567890abcdef' ;
391+ if ( key === 'entrypoint' ) return 'preferences' ;
392+ return null ;
393+ } ) ;
394+
395+ mockFetch . mockResolvedValue ( {
396+ ok : true ,
397+ json : jest . fn ( ) . mockResolvedValue ( { customization : 'french-test' } ) ,
398+ } ) ;
399+
400+ const { result } = renderHook ( ( ) => useCmsInfoState ( ) , {
401+ wrapper : L10nEnabledProvider ,
402+ } ) ;
403+
404+ await waitFor ( ( ) => {
405+ expect ( result . current . loading ) . toBe ( false ) ;
406+ } ) ;
407+
408+ expect ( mockFetch ) . toHaveBeenCalled ( ) ;
409+ expect ( result . current . data ?. cmsInfo ) . toEqual ( { customization : 'french-test' } ) ;
410+ } ) ;
411+
412+ it ( 'should fetch when l10nEnabled is false but browser language is English' , async ( ) => {
413+ // Mock English browser language but non-English selected locale
414+ Object . defineProperty ( navigator , 'language' , {
415+ writable : true ,
416+ value : 'en-GB' ,
417+ } ) ;
418+ require ( '../contexts/DynamicLocalizationContext' ) . useDynamicLocalization . mockReturnValue ( { currentLocale : 'fr-FR' } ) ;
419+
420+ mockUrlQueryData . get . mockImplementation ( ( key : string ) => {
421+ if ( key === 'client_id' ) return '1234567890abcdef' ;
422+ if ( key === 'entrypoint' ) return 'preferences' ;
423+ return null ;
424+ } ) ;
425+
426+ mockFetch . mockResolvedValue ( {
427+ ok : true ,
428+ json : jest . fn ( ) . mockResolvedValue ( { customization : 'english-browser-test' } ) ,
429+ } ) ;
430+
431+ const { result } = renderHook ( ( ) => useCmsInfoState ( ) , {
432+ wrapper : MockAppProvider ,
433+ } ) ;
434+
435+ await waitFor ( ( ) => {
436+ expect ( result . current . loading ) . toBe ( false ) ;
437+ } ) ;
438+
439+ expect ( mockFetch ) . toHaveBeenCalled ( ) ;
440+ expect ( result . current . data ?. cmsInfo ) . toEqual ( { customization : 'english-browser-test' } ) ;
441+ } ) ;
442+
443+ it ( 'should fetch when l10nEnabled is false but selected locale is English' , async ( ) => {
444+ // Mock non-English browser language but English selected locale
445+ Object . defineProperty ( navigator , 'language' , {
446+ writable : true ,
447+ value : 'fr-FR' ,
448+ } ) ;
449+ require ( '../contexts/DynamicLocalizationContext' ) . useDynamicLocalization . mockReturnValue ( { currentLocale : 'en-US' } ) ;
450+
451+ mockUrlQueryData . get . mockImplementation ( ( key : string ) => {
452+ if ( key === 'client_id' ) return '1234567890abcdef' ;
453+ if ( key === 'entrypoint' ) return 'preferences' ;
454+ return null ;
455+ } ) ;
456+
457+ mockFetch . mockResolvedValue ( {
458+ ok : true ,
459+ json : jest . fn ( ) . mockResolvedValue ( { customization : 'english-selected-test' } ) ,
460+ } ) ;
461+
462+ const { result } = renderHook ( ( ) => useCmsInfoState ( ) , {
463+ wrapper : MockAppProvider ,
464+ } ) ;
465+
466+ await waitFor ( ( ) => {
467+ expect ( result . current . loading ) . toBe ( false ) ;
468+ } ) ;
469+
470+ expect ( mockFetch ) . toHaveBeenCalled ( ) ;
471+ expect ( result . current . data ?. cmsInfo ) . toEqual ( { customization : 'english-selected-test' } ) ;
399472 } ) ;
400473} ) ;
0 commit comments