@@ -14,65 +14,15 @@ import {
1414 ASSET_FETCH_GA_INFO_HEADER ,
1515 INTERNAL_ASSET_FETCH_GA_INFO_VALUE ,
1616} from '../lib/ga4-asset-fetch.ts' ;
17+ import {
18+ assertAssetFetchGa4Event ,
19+ createWaitUntilSpy ,
20+ firstAssetFetchEvent ,
21+ setupGa4CapturingFetchMock ,
22+ setupNetlifyEnv ,
23+ } from '../lib/test-helpers.ts' ;
1724import assetTracking , { shouldTrackAssetFetch } from './index.ts' ;
1825
19- function setupNetlifyEnv ( t : { after : ( fn : ( ) => void ) => void } ) {
20- const g = globalThis as Record < string , unknown > ;
21- const originalNetlify = g . Netlify ;
22- t . after ( ( ) => {
23- g . Netlify = originalNetlify ;
24- } ) ;
25-
26- g . Netlify = {
27- env : {
28- get : ( name : string ) => {
29- if ( name === 'HUGO_SERVICES_GOOGLEANALYTICS_ID' ) return 'G-TEST' ;
30- if ( name === 'GA4_API_SECRET' ) return 'secret' ;
31- return undefined ;
32- } ,
33- } ,
34- } ;
35- }
36-
37- function setupFetchMock ( t : { after : ( fn : ( ) => void ) => void } ) {
38- const originalFetch = globalThis . fetch ;
39- t . after ( ( ) => {
40- globalThis . fetch = originalFetch ;
41- } ) ;
42-
43- const ga4Bodies : Record < string , unknown > [ ] = [ ] ;
44-
45- globalThis . fetch = ( async ( input : RequestInfo | URL , init ?: RequestInit ) => {
46- const url =
47- input instanceof URL
48- ? input . toString ( )
49- : typeof input === 'string'
50- ? input
51- : input . url ;
52-
53- if ( url . includes ( 'google-analytics.com' ) ) {
54- if ( init ?. body ) {
55- ga4Bodies . push ( JSON . parse ( init . body as string ) ) ;
56- }
57- return new Response ( '' , { status : 200 } ) ;
58- }
59-
60- return new Response ( 'unexpected fetch' , { status : 500 } ) ;
61- } ) as typeof fetch ;
62-
63- return ga4Bodies ;
64- }
65-
66- function createWaitUntilSpy ( ) {
67- const promises : Promise < unknown > [ ] = [ ] ;
68- return {
69- waitUntil : ( p : Promise < unknown > ) => {
70- promises . push ( p ) ;
71- } ,
72- flush : ( ) => Promise . all ( promises ) ,
73- } ;
74- }
75-
7626test ( 'shouldTrackAssetFetch accepts GET .md requests' , ( ) => {
7727 const request = new Request (
7828 'https://example.com/docs/concepts/resources/index.md' ,
@@ -82,7 +32,11 @@ test('shouldTrackAssetFetch accepts GET .md requests', () => {
8232 status : 200 ,
8333 } ) ;
8434
85- assert . equal ( shouldTrackAssetFetch ( request , response ) , true ) ;
35+ assert . strictEqual (
36+ shouldTrackAssetFetch ( request , response ) ,
37+ true ,
38+ 'shouldTrackAssetFetch' ,
39+ ) ;
8640} ) ;
8741
8842test ( 'shouldTrackAssetFetch accepts GET .txt requests' , ( ) => {
@@ -92,7 +46,11 @@ test('shouldTrackAssetFetch accepts GET .txt requests', () => {
9246 status : 200 ,
9347 } ) ;
9448
95- assert . equal ( shouldTrackAssetFetch ( request , response ) , true ) ;
49+ assert . strictEqual (
50+ shouldTrackAssetFetch ( request , response ) ,
51+ true ,
52+ 'shouldTrackAssetFetch' ,
53+ ) ;
9654} ) ;
9755
9856test ( 'shouldTrackAssetFetch returns false for internal marked requests' , ( ) => {
@@ -109,7 +67,11 @@ test('shouldTrackAssetFetch returns false for internal marked requests', () => {
10967 status : 200 ,
11068 } ) ;
11169
112- assert . equal ( shouldTrackAssetFetch ( request , response ) , false ) ;
70+ assert . strictEqual (
71+ shouldTrackAssetFetch ( request , response ) ,
72+ false ,
73+ 'shouldTrackAssetFetch' ,
74+ ) ;
11375} ) ;
11476
11577test ( 'shouldTrackAssetFetch returns false for non-GET methods' , ( ) => {
@@ -123,7 +85,11 @@ test('shouldTrackAssetFetch returns false for non-GET methods', () => {
12385 status : 200 ,
12486 } ) ;
12587
126- assert . equal ( shouldTrackAssetFetch ( request , response ) , false ) ;
88+ assert . strictEqual (
89+ shouldTrackAssetFetch ( request , response ) ,
90+ false ,
91+ 'shouldTrackAssetFetch' ,
92+ ) ;
12793 }
12894} ) ;
12995
@@ -137,7 +103,11 @@ test('shouldTrackAssetFetch accepts non-2xx responses for tracked assets', () =>
137103 status,
138104 } ) ;
139105
140- assert . equal ( shouldTrackAssetFetch ( request , response ) , true ) ;
106+ assert . strictEqual (
107+ shouldTrackAssetFetch ( request , response ) ,
108+ true ,
109+ 'shouldTrackAssetFetch' ,
110+ ) ;
141111 }
142112} ) ;
143113
@@ -150,7 +120,11 @@ test('shouldTrackAssetFetch accepts non-markdown content type for tracked assets
150120 status : 200 ,
151121 } ) ;
152122
153- assert . equal ( shouldTrackAssetFetch ( request , response ) , true ) ;
123+ assert . strictEqual (
124+ shouldTrackAssetFetch ( request , response ) ,
125+ true ,
126+ 'shouldTrackAssetFetch' ,
127+ ) ;
154128} ) ;
155129
156130test ( 'shouldTrackAssetFetch returns false for non-tracked extensions' , ( ) => {
@@ -162,12 +136,16 @@ test('shouldTrackAssetFetch returns false for non-tracked extensions', () => {
162136 status : 200 ,
163137 } ) ;
164138
165- assert . equal ( shouldTrackAssetFetch ( request , response ) , false ) ;
139+ assert . strictEqual (
140+ shouldTrackAssetFetch ( request , response ) ,
141+ false ,
142+ 'shouldTrackAssetFetch' ,
143+ ) ;
166144} ) ;
167145
168146test ( 'handler emits asset_fetch for explicit .md requests' , async ( t ) => {
169147 setupNetlifyEnv ( t ) ;
170- const ga4Bodies = setupFetchMock ( t ) ;
148+ const ga4Bodies = setupGa4CapturingFetchMock ( t ) ;
171149 const spy = createWaitUntilSpy ( ) ;
172150
173151 const response = await assetTracking (
@@ -184,24 +162,28 @@ test('handler emits asset_fetch for explicit .md requests', async (t) => {
184162
185163 await spy . flush ( ) ;
186164
187- assert . equal ( response . status , 200 ) ;
188- assert . equal ( ga4Bodies . length , 1 ) ;
189-
190- const event = (
191- ga4Bodies [ 0 ] . events as { name : string ; params : Record < string , string > } [ ]
192- ) [ 0 ] ;
193- assert . equal ( event . name , 'asset_fetch' ) ;
194- assert . equal ( event . params . asset_group , 'markdown' ) ;
195- assert . equal ( event . params . asset_path , '/docs/concepts/resources/index.md' ) ;
196- assert . equal ( event . params . asset_ext , 'md' ) ;
197- assert . equal ( event . params . content_type , 'text/markdown' ) ;
198- assert . equal ( event . params . status_code , '200' ) ;
199- assert . ok ( ! ( 'original_path' in event . params ) ) ;
165+ assert . strictEqual ( response . status , 200 , 'HTTP status' ) ;
166+ assert . strictEqual (
167+ response . headers . get ( 'x-asset-fetch-ga-info' ) ,
168+ '/docs/concepts/resources/index.md;ga-event-candidate,config-present' ,
169+ 'X-Asset-Fetch-Ga-Info' ,
170+ ) ;
171+
172+ assertAssetFetchGa4Event (
173+ firstAssetFetchEvent ( ga4Bodies ) ,
174+ {
175+ asset_path : '/docs/concepts/resources/index.md' ,
176+ content_type : 'text/markdown' ,
177+ status_code : '200' ,
178+ event_emitter : 'tracking' ,
179+ } ,
180+ { expectOriginalPathAbsent : true } ,
181+ ) ;
200182} ) ;
201183
202184test ( 'handler emits asset_fetch for explicit .txt requests' , async ( t ) => {
203185 setupNetlifyEnv ( t ) ;
204- const ga4Bodies = setupFetchMock ( t ) ;
186+ const ga4Bodies = setupGa4CapturingFetchMock ( t ) ;
205187 const spy = createWaitUntilSpy ( ) ;
206188
207189 const response = await assetTracking (
@@ -218,24 +200,23 @@ test('handler emits asset_fetch for explicit .txt requests', async (t) => {
218200
219201 await spy . flush ( ) ;
220202
221- assert . equal ( response . status , 200 ) ;
222- assert . equal ( ga4Bodies . length , 1 ) ;
223-
224- const event = (
225- ga4Bodies [ 0 ] . events as { name : string ; params : Record < string , string > } [ ]
226- ) [ 0 ] ;
227- assert . equal ( event . name , 'asset_fetch' ) ;
228- assert . equal ( event . params . asset_group , 'text' ) ;
229- assert . equal ( event . params . asset_path , '/llms.txt' ) ;
230- assert . equal ( event . params . asset_ext , 'txt' ) ;
231- assert . equal ( event . params . content_type , 'text/plain' ) ;
232- assert . equal ( event . params . status_code , '200' ) ;
233- assert . ok ( ! ( 'original_path' in event . params ) ) ;
203+ assert . strictEqual ( response . status , 200 , 'HTTP status' ) ;
204+
205+ assertAssetFetchGa4Event (
206+ firstAssetFetchEvent ( ga4Bodies ) ,
207+ {
208+ asset_path : '/llms.txt' ,
209+ content_type : 'text/plain' ,
210+ status_code : '200' ,
211+ event_emitter : 'tracking' ,
212+ } ,
213+ { expectOriginalPathAbsent : true } ,
214+ ) ;
234215} ) ;
235216
236217test ( 'handler skips asset_fetch for internal marked explicit .md requests' , async ( t ) => {
237218 setupNetlifyEnv ( t ) ;
238- const ga4Bodies = setupFetchMock ( t ) ;
219+ const ga4Bodies = setupGa4CapturingFetchMock ( t ) ;
239220 const spy = createWaitUntilSpy ( ) ;
240221
241222 const response = await assetTracking (
@@ -256,13 +237,18 @@ test('handler skips asset_fetch for internal marked explicit .md requests', asyn
256237
257238 await spy . flush ( ) ;
258239
259- assert . equal ( response . status , 200 ) ;
260- assert . equal ( ga4Bodies . length , 0 ) ;
240+ assert . strictEqual ( response . status , 200 , 'HTTP status' ) ;
241+ assert . strictEqual ( ga4Bodies . length , 0 , 'GA4 body count' ) ;
242+ assert . strictEqual (
243+ response . headers . get ( 'x-asset-fetch-ga-info' ) ,
244+ 'none: internal subrequest' ,
245+ 'X-Asset-Fetch-Ga-Info' ,
246+ ) ;
261247} ) ;
262248
263249test ( 'handler emits asset_fetch for explicit .md requests regardless of response status' , async ( t ) => {
264250 setupNetlifyEnv ( t ) ;
265- const ga4Bodies = setupFetchMock ( t ) ;
251+ const ga4Bodies = setupGa4CapturingFetchMock ( t ) ;
266252 const spy = createWaitUntilSpy ( ) ;
267253
268254 const response = await assetTracking (
@@ -279,16 +265,12 @@ test('handler emits asset_fetch for explicit .md requests regardless of response
279265
280266 await spy . flush ( ) ;
281267
282- assert . equal ( response . status , 404 ) ;
283- assert . equal ( ga4Bodies . length , 1 ) ;
284-
285- const event = (
286- ga4Bodies [ 0 ] . events as { name : string ; params : Record < string , string > } [ ]
287- ) [ 0 ] ;
288- assert . equal ( event . name , 'asset_fetch' ) ;
289- assert . equal ( event . params . asset_group , 'markdown' ) ;
290- assert . equal ( event . params . asset_path , '/docs/concepts/resources/index.md' ) ;
291- assert . equal ( event . params . asset_ext , 'md' ) ;
292- assert . equal ( event . params . content_type , 'text/plain' ) ;
293- assert . equal ( event . params . status_code , '404' ) ;
268+ assert . strictEqual ( response . status , 404 , 'HTTP status' ) ;
269+
270+ assertAssetFetchGa4Event ( firstAssetFetchEvent ( ga4Bodies ) , {
271+ asset_path : '/docs/concepts/resources/index.md' ,
272+ content_type : 'text/plain' ,
273+ status_code : '404' ,
274+ event_emitter : 'tracking' ,
275+ } ) ;
294276} ) ;
0 commit comments