@@ -1069,6 +1069,179 @@ describe("asset-server handler", () => {
10691069 ) ;
10701070 } ) ;
10711071 } ) ;
1072+
1073+ const findIndexHtmlAssetEntryForPath = async ( path : string ) => {
1074+ if ( path === "/index.html" ) {
1075+ return "asset-key-index.html" ;
1076+ }
1077+ return null ;
1078+ } ;
1079+
1080+ const fetchHtmlAsset = ( ) =>
1081+ Promise . resolve (
1082+ Object . assign (
1083+ new Response ( `
1084+ <!DOCTYPE html>
1085+ <html>
1086+ <body>
1087+ <h1>Hello World</h1>
1088+ </body>
1089+ </html>
1090+ ` ) ,
1091+ { contentType : "text/html" }
1092+ )
1093+ ) ;
1094+
1095+ const fetchHtmlAssetWithoutBody = ( ) =>
1096+ Promise . resolve (
1097+ Object . assign (
1098+ new Response ( `
1099+ <!DOCTYPE html>
1100+ <html>
1101+ <head>
1102+ <title>No Body</title>
1103+ </head>
1104+ </html>
1105+ ` ) ,
1106+ { contentType : "text/html" }
1107+ )
1108+ ) ;
1109+
1110+ const findStyleCssAssetEntryForPath = async ( path : string ) =>
1111+ path === "/style.css" ? "asset-key-style.css" : null ;
1112+
1113+ const fetchCssAsset = ( ) =>
1114+ Promise . resolve (
1115+ Object . assign (
1116+ new Response ( `
1117+ body {
1118+ font-family: Arial, sans-serif;
1119+ color: #333;
1120+ }
1121+ ` ) ,
1122+ { contentType : "text/css" }
1123+ )
1124+ ) ;
1125+
1126+ test ( "should emit header when Web Analytics Token is injected" , async ( ) => {
1127+ const { response } = await getTestResponse ( {
1128+ request : "https://example.com/" ,
1129+ metadata : createMetadataObject ( {
1130+ deploymentId : "mock-deployment-id" ,
1131+ webAnalyticsToken : "test-analytics-token" ,
1132+ } ) as Metadata ,
1133+ findAssetEntryForPath : findIndexHtmlAssetEntryForPath ,
1134+ fetchAsset : fetchHtmlAsset ,
1135+ xWebAnalyticsHeader : true ,
1136+ } ) ;
1137+
1138+ expect ( response . status ) . toBe ( 200 ) ;
1139+ expect ( response . headers . get ( "x-cf-pages-analytics" ) ) . toBe ( "1" ) ;
1140+
1141+ const responseText = await response . text ( ) ;
1142+ expect ( responseText ) . toContain (
1143+ 'data-cf-beacon=\'{"token": "test-analytics-token"}\''
1144+ ) ;
1145+ } ) ;
1146+
1147+ test ( "should not emit header when Web Analytics Token is not configured" , async ( ) => {
1148+ const { response } = await getTestResponse ( {
1149+ request : "https://example.com/" ,
1150+ metadata : createMetadataObject ( {
1151+ deploymentId : "mock-deployment-id" ,
1152+ } ) as Metadata ,
1153+ findAssetEntryForPath : findIndexHtmlAssetEntryForPath ,
1154+ fetchAsset : fetchHtmlAsset ,
1155+ } ) ;
1156+
1157+ expect ( response . status ) . toBe ( 200 ) ;
1158+ expect ( response . headers . get ( "x-cf-pages-analytics" ) ) . toBeNull ( ) ;
1159+
1160+ const responseText = await response . text ( ) ;
1161+ expect ( responseText ) . not . toContain ( "data-cf-beacon" ) ;
1162+ } ) ;
1163+
1164+ test ( "should emit header for HTML without <body> element but not inject script" , async ( ) => {
1165+ const { response } = await getTestResponse ( {
1166+ request : "https://example.com/" ,
1167+ metadata : createMetadataObject ( {
1168+ deploymentId : "mock-deployment-id" ,
1169+ webAnalyticsToken : "test-analytics-token" ,
1170+ } ) as Metadata ,
1171+ findAssetEntryForPath : findIndexHtmlAssetEntryForPath ,
1172+ fetchAsset : fetchHtmlAssetWithoutBody ,
1173+ xWebAnalyticsHeader : true ,
1174+ } ) ;
1175+
1176+ expect ( response . status ) . toBe ( 200 ) ;
1177+ expect ( response . headers . get ( "x-cf-pages-analytics" ) ) . toBe ( "1" ) ;
1178+
1179+ const responseText = await response . text ( ) ;
1180+ expect ( responseText ) . not . toContain ( "data-cf-beacon" ) ;
1181+ expect ( responseText ) . toContain ( "<title>No Body</title>" ) ;
1182+ } ) ;
1183+
1184+ test ( "should not emit header for non-HTML responses" , async ( ) => {
1185+ const { response } = await getTestResponse ( {
1186+ request : "https://example.com/style.css" ,
1187+ metadata : createMetadataObject ( {
1188+ deploymentId : "mock-deployment-id" ,
1189+ webAnalyticsToken : "test-analytics-token" ,
1190+ } ) as Metadata ,
1191+ findAssetEntryForPath : findStyleCssAssetEntryForPath ,
1192+ fetchAsset : fetchCssAsset ,
1193+ } ) ;
1194+
1195+ expect ( response . status ) . toBe ( 200 ) ;
1196+ expect ( response . headers . get ( "x-cf-pages-analytics" ) ) . toBeNull ( ) ;
1197+ expect ( response . headers . get ( "content-type" ) ) . toBe ( "text/css" ) ;
1198+
1199+ const responseText = await response . text ( ) ;
1200+ expect ( responseText ) . not . toContain ( "data-cf-beacon" ) ;
1201+ expect ( responseText ) . toContain ( "font-family: Arial" ) ;
1202+ } ) ;
1203+
1204+ test ( "should not emit header when xWebAnalyticsHeader is false" , async ( ) => {
1205+ const { response } = await getTestResponse ( {
1206+ request : "https://example.com/" ,
1207+ metadata : createMetadataObject ( {
1208+ deploymentId : "mock-deployment-id" ,
1209+ webAnalyticsToken : "test-analytics-token" ,
1210+ } ) as Metadata ,
1211+ findAssetEntryForPath : findIndexHtmlAssetEntryForPath ,
1212+ fetchAsset : fetchHtmlAsset ,
1213+ xWebAnalyticsHeader : false ,
1214+ } ) ;
1215+
1216+ expect ( response . status ) . toBe ( 200 ) ;
1217+ expect ( response . headers . get ( "x-cf-pages-analytics" ) ) . toBeNull ( ) ;
1218+
1219+ const responseText = await response . text ( ) ;
1220+ expect ( responseText ) . toContain (
1221+ 'data-cf-beacon=\'{"token": "test-analytics-token"}\''
1222+ ) ;
1223+ } ) ;
1224+
1225+ test ( "should not emit header when xWebAnalyticsHeader is undefined" , async ( ) => {
1226+ const { response } = await getTestResponse ( {
1227+ request : "https://example.com/" ,
1228+ metadata : createMetadataObject ( {
1229+ deploymentId : "mock-deployment-id" ,
1230+ webAnalyticsToken : "test-analytics-token" ,
1231+ } ) as Metadata ,
1232+ findAssetEntryForPath : findIndexHtmlAssetEntryForPath ,
1233+ fetchAsset : fetchHtmlAsset ,
1234+ xWebAnalyticsHeader : undefined ,
1235+ } ) ;
1236+
1237+ expect ( response . status ) . toBe ( 200 ) ;
1238+ expect ( response . headers . get ( "x-cf-pages-analytics" ) ) . toBeNull ( ) ;
1239+
1240+ const responseText = await response . text ( ) ;
1241+ expect ( responseText ) . toContain (
1242+ 'data-cf-beacon=\'{"token": "test-analytics-token"}\''
1243+ ) ;
1244+ } ) ;
10721245} ) ;
10731246
10741247interface HandlerSpies {
@@ -1121,6 +1294,7 @@ async function getTestResponse({
11211294 request : request instanceof Request ? request : new Request ( request ) ,
11221295 metadata,
11231296 xServerEnvHeader : "dev" ,
1297+ xWebAnalyticsHeader : options . xWebAnalyticsHeader ,
11241298 logError : console . error ,
11251299 findAssetEntryForPath : async ( ...args ) => {
11261300 spies . findAssetEntryForPath ++ ;
0 commit comments