@@ -345,6 +345,7 @@ describe('Admin Controls', () => {
345345 // Should still start polling
346346 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
347347 strictModeDisabled : true ,
348+ adminControlsApplicable : true ,
348349 } ) ;
349350 await vi . advanceTimersByTimeAsync ( 5 * 60 * 1000 ) ;
350351
@@ -363,7 +364,10 @@ describe('Admin Controls', () => {
363364 } ) ;
364365
365366 it ( 'should fetch from server if no cachedSettings provided' , async ( ) => {
366- const serverResponse = { strictModeDisabled : false } ;
367+ const serverResponse = {
368+ strictModeDisabled : false ,
369+ adminControlsApplicable : true ,
370+ } ;
367371 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( serverResponse ) ;
368372
369373 const result = await fetchAdminControls (
@@ -386,31 +390,24 @@ describe('Admin Controls', () => {
386390 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ;
387391 } ) ;
388392
389- it ( 'should return empty object on fetch error and still start polling' , async ( ) => {
390- ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue (
391- new Error ( 'Network error' ) ,
392- ) ;
393- const result = await fetchAdminControls (
394- mockServer ,
395- undefined ,
396- true ,
397- mockOnSettingsChanged ,
398- ) ;
393+ it ( 'should throw error on fetch error and NOT start polling' , async ( ) => {
394+ const error = new Error ( 'Network error' ) ;
395+ ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue ( error ) ;
399396
400- expect ( result ) . toEqual ( { } ) ;
397+ await expect (
398+ fetchAdminControls ( mockServer , undefined , true , mockOnSettingsChanged ) ,
399+ ) . rejects . toThrow ( error ) ;
401400
402- // Polling should have been started and should retry
403- ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
404- strictModeDisabled : false ,
405- } ) ;
401+ // Polling should NOT have been started
402+ // Advance timers just to be absolutely sure
406403 await vi . advanceTimersByTimeAsync ( 5 * 60 * 1000 ) ;
407- expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 2 ) ; // Initial + poll
404+ expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ; // Only initial fetch
408405 } ) ;
409406
410- it ( 'should return empty object on 403 fetch error and STOP polling' , async ( ) => {
411- const error403 = new Error ( 'Forbidden' ) ;
412- Object . assign ( error403 , { status : 403 } ) ;
413- ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue ( error403 ) ;
407+ it ( 'should return empty object on adminControlsApplicable false and STOP polling' , async ( ) => {
408+ ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
409+ adminControlsApplicable : false ,
410+ } ) ;
414411
415412 const result = await fetchAdminControls (
416413 mockServer ,
@@ -421,7 +418,7 @@ describe('Admin Controls', () => {
421418
422419 expect ( result ) . toEqual ( { } ) ;
423420
424- // Advance time - should NOT poll because of 403
421+ // Advance time - should NOT poll because of adminControlsApplicable: false
425422 await vi . advanceTimersByTimeAsync ( 5 * 60 * 1000 ) ;
426423 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ; // Only the initial call
427424 } ) ;
@@ -430,6 +427,7 @@ describe('Admin Controls', () => {
430427 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
431428 strictModeDisabled : false ,
432429 unknownField : 'bad' ,
430+ adminControlsApplicable : true ,
433431 } ) ;
434432
435433 const result = await fetchAdminControls (
@@ -455,7 +453,9 @@ describe('Admin Controls', () => {
455453 } ) ;
456454
457455 it ( 'should reset polling interval if called again' , async ( ) => {
458- ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( { } ) ;
456+ ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
457+ adminControlsApplicable : true ,
458+ } ) ;
459459
460460 // First call
461461 await fetchAdminControls (
@@ -514,6 +514,7 @@ describe('Admin Controls', () => {
514514 const serverResponse = {
515515 strictModeDisabled : true ,
516516 unknownField : 'should be removed' ,
517+ adminControlsApplicable : true ,
517518 } ;
518519 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( serverResponse ) ;
519520
@@ -532,30 +533,32 @@ describe('Admin Controls', () => {
532533 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ;
533534 } ) ;
534535
535- it ( 'should return empty object on 403 fetch error ' , async ( ) => {
536- const error403 = new Error ( 'Forbidden' ) ;
537- Object . assign ( error403 , { status : 403 } ) ;
538- ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue ( error403 ) ;
536+ it ( 'should return empty object on adminControlsApplicable false ' , async ( ) => {
537+ ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
538+ adminControlsApplicable : false ,
539+ } ) ;
539540
540541 const result = await fetchAdminControlsOnce ( mockServer , true ) ;
541542 expect ( result ) . toEqual ( { } ) ;
542543 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ;
543544 } ) ;
544545
545- it ( 'should return empty object on any other fetch error' , async ( ) => {
546- ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue (
547- new Error ( 'Network error' ) ,
546+ it ( 'should throw error on any other fetch error' , async ( ) => {
547+ const error = new Error ( 'Network error' ) ;
548+ ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue ( error ) ;
549+ await expect ( fetchAdminControlsOnce ( mockServer , true ) ) . rejects . toThrow (
550+ error ,
548551 ) ;
549- const result = await fetchAdminControlsOnce ( mockServer , true ) ;
550- expect ( result ) . toEqual ( { } ) ;
551552 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ;
552553 } ) ;
553554
554555 it ( 'should not start or stop any polling timers' , async ( ) => {
555556 const setIntervalSpy = vi . spyOn ( global , 'setInterval' ) ;
556557 const clearIntervalSpy = vi . spyOn ( global , 'clearInterval' ) ;
557558
558- ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( { } ) ;
559+ ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
560+ adminControlsApplicable : true ,
561+ } ) ;
559562 await fetchAdminControlsOnce ( mockServer , true ) ;
560563
561564 expect ( setIntervalSpy ) . not . toHaveBeenCalled ( ) ;
@@ -568,6 +571,7 @@ describe('Admin Controls', () => {
568571 // Initial fetch
569572 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
570573 strictModeDisabled : true ,
574+ adminControlsApplicable : true ,
571575 } ) ;
572576 await fetchAdminControls (
573577 mockServer ,
@@ -579,6 +583,7 @@ describe('Admin Controls', () => {
579583 // Update for next poll
580584 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
581585 strictModeDisabled : false ,
586+ adminControlsApplicable : true ,
582587 } ) ;
583588
584589 // Fast forward
@@ -598,7 +603,10 @@ describe('Admin Controls', () => {
598603 } ) ;
599604
600605 it ( 'should NOT emit if settings are deeply equal but not the same instance' , async ( ) => {
601- const settings = { strictModeDisabled : false } ;
606+ const settings = {
607+ strictModeDisabled : false ,
608+ adminControlsApplicable : true ,
609+ } ;
602610 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( settings ) ;
603611
604612 await fetchAdminControls (
@@ -613,6 +621,7 @@ describe('Admin Controls', () => {
613621 // Next poll returns a different object with the same values
614622 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
615623 strictModeDisabled : false ,
624+ adminControlsApplicable : true ,
616625 } ) ;
617626 await vi . advanceTimersByTimeAsync ( 5 * 60 * 1000 ) ;
618627
@@ -623,6 +632,7 @@ describe('Admin Controls', () => {
623632 // Initial fetch is successful
624633 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
625634 strictModeDisabled : true ,
635+ adminControlsApplicable : true ,
626636 } ) ;
627637 await fetchAdminControls (
628638 mockServer ,
@@ -643,6 +653,7 @@ describe('Admin Controls', () => {
643653 // Subsequent poll succeeds with new data
644654 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
645655 strictModeDisabled : false ,
656+ adminControlsApplicable : true ,
646657 } ) ;
647658 await vi . advanceTimersByTimeAsync ( 5 * 60 * 1000 ) ;
648659 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 3 ) ;
@@ -659,10 +670,11 @@ describe('Admin Controls', () => {
659670 } ) ;
660671 } ) ;
661672
662- it ( 'should STOP polling if server returns 403 ' , async ( ) => {
673+ it ( 'should STOP polling if server returns adminControlsApplicable false ' , async ( ) => {
663674 // Initial fetch is successful
664675 ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
665676 strictModeDisabled : true ,
677+ adminControlsApplicable : true ,
666678 } ) ;
667679 await fetchAdminControls (
668680 mockServer ,
@@ -672,10 +684,10 @@ describe('Admin Controls', () => {
672684 ) ;
673685 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 1 ) ;
674686
675- // Next poll returns 403
676- const error403 = new Error ( 'Forbidden' ) ;
677- Object . assign ( error403 , { status : 403 } ) ;
678- ( mockServer . fetchAdminControls as Mock ) . mockRejectedValue ( error403 ) ;
687+ // Next poll returns adminControlsApplicable: false
688+ ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
689+ adminControlsApplicable : false ,
690+ } ) ;
679691
680692 await vi . advanceTimersByTimeAsync ( 5 * 60 * 1000 ) ;
681693 expect ( mockServer . fetchAdminControls ) . toHaveBeenCalledTimes ( 2 ) ;
@@ -688,7 +700,9 @@ describe('Admin Controls', () => {
688700
689701 describe ( 'stopAdminControlsPolling' , ( ) => {
690702 it ( 'should stop polling after it has started' , async ( ) => {
691- ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( { } ) ;
703+ ( mockServer . fetchAdminControls as Mock ) . mockResolvedValue ( {
704+ adminControlsApplicable : true ,
705+ } ) ;
692706
693707 // Start polling
694708 await fetchAdminControls (
0 commit comments