@@ -27,6 +27,16 @@ import {
2727import { $isConsentBannerVisible } from '@components/scripts/store/consentBanner'
2828import * as errorHandlerModule from '@components/scripts/errors/handler'
2929
30+ const consentCreateMock = vi . hoisted ( ( ) => vi . fn ( ) )
31+
32+ vi . mock ( 'astro:actions' , ( ) => ( {
33+ actions : {
34+ gdpr : {
35+ consentCreate : consentCreateMock ,
36+ } ,
37+ } ,
38+ } ) )
39+
3040// Mock js-cookie
3141vi . mock ( 'js-cookie' , ( ) => ( {
3242 default : {
@@ -81,6 +91,7 @@ describe('Cookie Consent Management', () => {
8191
8292 // Clear mocks
8393 vi . clearAllMocks ( )
94+ consentCreateMock . mockReset ( )
8495
8596 // Clear localStorage
8697 localStorage . clear ( )
@@ -320,8 +331,7 @@ describe('Consent side effects', () => {
320331 } )
321332
322333 it ( 'logs consent updates via the GDPR API when preferences change' , async ( ) => {
323- const fetchSpy = vi . fn ( ) . mockResolvedValue ( { ok : true } )
324- vi . stubGlobal ( 'fetch' , fetchSpy )
334+ consentCreateMock . mockResolvedValue ( { data : { success : true , record : { id : 'consent-1' } } } )
325335
326336 let consentListener :
327337 | ( ( _state : ConsentState , _oldState ?: ConsentState ) => Promise < void > | void )
@@ -353,16 +363,13 @@ describe('Consent side effects', () => {
353363 await consentListener ?.( newState , oldState )
354364
355365 await vi . waitFor ( ( ) => {
356- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 )
366+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 1 )
357367 } )
358- const firstFetchCall = fetchSpy . mock . calls . at ( 0 )
359- if ( ! firstFetchCall ) {
360- throw new TestError ( 'Expected consent logging fetch to be called once' )
368+ const firstConsentCall = consentCreateMock . mock . calls . at ( 0 )
369+ if ( ! firstConsentCall ) {
370+ throw new TestError ( 'Expected consent logging action to be called once' )
361371 }
362- const [ url , options ] = firstFetchCall
363- expect ( url ) . toBe ( '/_actions/gdpr.consentCreate' )
364- expect ( options ?. method ) . toBe ( 'POST' )
365- const payload = JSON . parse ( options ?. body as string )
372+ const [ payload ] = firstConsentCall
366373 expect ( payload ) . toMatchObject ( {
367374 DataSubjectId : validDataSubjectId ,
368375 purposes : [ 'analytics' ] ,
@@ -372,13 +379,12 @@ describe('Consent side effects', () => {
372379
373380 await consentListener ?.( newState , undefined )
374381 await vi . waitFor ( ( ) => {
375- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 )
382+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 1 )
376383 } )
377384 } )
378385
379386 it ( 'regenerates a DataSubjectId before logging when state value is missing or invalid' , async ( ) => {
380- const fetchSpy = vi . fn ( ) . mockResolvedValue ( { ok : true } )
381- vi . stubGlobal ( 'fetch' , fetchSpy )
387+ consentCreateMock . mockResolvedValue ( { data : { success : true , record : { id : 'consent-1' } } } )
382388
383389 const regeneratedId = 'regenerated-data-subject-id'
384390 vi . mocked ( getOrCreateDataSubjectId ) . mockReturnValue ( regeneratedId )
@@ -412,25 +418,23 @@ describe('Consent side effects', () => {
412418 await consentListener ?.( newState , oldState )
413419
414420 await vi . waitFor ( ( ) => {
415- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 )
421+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 1 )
416422 } )
417423
418424 expect ( getOrCreateDataSubjectId ) . toHaveBeenCalledTimes ( 1 )
419425
420- const firstFetchCall = fetchSpy . mock . calls . at ( 0 )
421- if ( ! firstFetchCall ) {
422- throw new TestError ( 'Expected consent logging fetch to be called once' )
426+ const firstConsentCall = consentCreateMock . mock . calls . at ( 0 )
427+ if ( ! firstConsentCall ) {
428+ throw new TestError ( 'Expected consent logging action to be called once' )
423429 }
424- const [ , options ] = firstFetchCall
425- const payload = JSON . parse ( options ?. body as string )
430+ const [ payload ] = firstConsentCall
426431 expect ( payload . DataSubjectId ) . toBe ( regeneratedId )
427432
428433 expect ( $consent . get ( ) . DataSubjectId ) . toBe ( regeneratedId )
429434 } )
430435
431436 it ( 'queues consent logging when offline and retries after reconnecting' , async ( ) => {
432- const fetchSpy = vi . fn ( ) . mockResolvedValue ( { ok : true } )
433- vi . stubGlobal ( 'fetch' , fetchSpy )
437+ consentCreateMock . mockResolvedValue ( { data : { success : true , record : { id : 'consent-1' } } } )
434438
435439 const onlineGetter = vi . spyOn ( window . navigator , 'onLine' , 'get' )
436440 onlineGetter . mockReturnValue ( false )
@@ -463,13 +467,13 @@ describe('Consent side effects', () => {
463467
464468 await consentListener ?.( newState , oldState )
465469
466- expect ( fetchSpy ) . not . toHaveBeenCalled ( )
470+ expect ( consentCreateMock ) . not . toHaveBeenCalled ( )
467471
468472 onlineGetter . mockReturnValue ( true )
469473 window . dispatchEvent ( new Event ( 'online' ) )
470474
471475 await vi . waitFor ( ( ) => {
472- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 )
476+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 1 )
473477 } )
474478
475479 onlineGetter . mockRestore ( )
@@ -478,8 +482,7 @@ describe('Consent side effects', () => {
478482 it ( 'coalesces burst consent updates into the latest payload before sending' , async ( ) => {
479483 vi . useFakeTimers ( )
480484
481- const fetchSpy = vi . fn ( ) . mockResolvedValue ( { ok : true } )
482- vi . stubGlobal ( 'fetch' , fetchSpy )
485+ consentCreateMock . mockResolvedValue ( { data : { success : true , record : { id : 'consent-1' } } } )
483486
484487 let consentListener :
485488 | ( ( _state : ConsentState , _oldState ?: ConsentState ) => Promise < void > | void )
@@ -524,38 +527,34 @@ describe('Consent side effects', () => {
524527 await consentListener ?.( state2 , state1 )
525528 await consentListener ?.( state3 , state2 )
526529
527- expect ( fetchSpy ) . not . toHaveBeenCalled ( )
530+ expect ( consentCreateMock ) . not . toHaveBeenCalled ( )
528531
529532 await vi . advanceTimersByTimeAsync ( 250 )
530533
531534 await vi . waitFor ( ( ) => {
532- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 )
535+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 1 )
533536 } )
534537
535- const firstFetchCall = fetchSpy . mock . calls . at ( 0 )
536- if ( ! firstFetchCall ) {
537- throw new TestError ( 'Expected coalesced consent logging fetch to be called once' )
538+ const firstConsentCall = consentCreateMock . mock . calls . at ( 0 )
539+ if ( ! firstConsentCall ) {
540+ throw new TestError ( 'Expected coalesced consent logging action to be called once' )
538541 }
539542
540- const [ , options ] = firstFetchCall
541- const payload = JSON . parse ( options ?. body as string )
543+ const [ payload ] = firstConsentCall
542544 expect ( payload . purposes ) . toEqual ( [ 'analytics' , 'marketing' , 'functional' ] )
543545 } )
544546
545547 it ( 'retries consent logging after a 429 without reporting a script error' , async ( ) => {
546548 vi . useFakeTimers ( )
547549
548- const fetchSpy = vi
549- . fn ( )
550+ consentCreateMock
550551 . mockResolvedValueOnce ( {
551- ok : false ,
552- status : 429 ,
553- statusText : 'Too Many Requests' ,
554- headers : { get : vi . fn ( ( ) => '1' ) } ,
555- json : vi . fn ( ) . mockResolvedValue ( { error : { message : 'Try again in 1s' } } ) ,
552+ error : {
553+ code : 'TOO_MANY_REQUESTS' ,
554+ message : 'Try again in 1s' ,
555+ } ,
556556 } )
557- . mockResolvedValueOnce ( { ok : true } )
558- vi . stubGlobal ( 'fetch' , fetchSpy )
557+ . mockResolvedValueOnce ( { data : { success : true , record : { id : 'consent-1' } } } )
559558
560559 const handleScriptErrorSpy = vi . spyOn ( errorHandlerModule , 'handleScriptError' )
561560
@@ -590,15 +589,15 @@ describe('Consent side effects', () => {
590589 await vi . advanceTimersByTimeAsync ( 250 )
591590
592591 await vi . waitFor ( ( ) => {
593- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 )
592+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 1 )
594593 } )
595594
596595 expect ( handleScriptErrorSpy ) . not . toHaveBeenCalled ( )
597596
598597 await vi . advanceTimersByTimeAsync ( 1_000 )
599598
600599 await vi . waitFor ( ( ) => {
601- expect ( fetchSpy ) . toHaveBeenCalledTimes ( 2 )
600+ expect ( consentCreateMock ) . toHaveBeenCalledTimes ( 2 )
602601 } )
603602
604603 expect ( handleScriptErrorSpy ) . not . toHaveBeenCalled ( )
0 commit comments