From ff463c107a0e79a88d1232c6fd583caf4c3b1e08 Mon Sep 17 00:00:00 2001 From: kfj001 Date: Sun, 30 Aug 2026 06:34:44 +0000 Subject: [PATCH] fixes broken tests --- __tests__/referer_proxy.test.mjs | 92 +++++++++++++++++--------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/__tests__/referer_proxy.test.mjs b/__tests__/referer_proxy.test.mjs index a15f04c..afa4994 100644 --- a/__tests__/referer_proxy.test.mjs +++ b/__tests__/referer_proxy.test.mjs @@ -29,18 +29,19 @@ function buildModule(code) { return `(async () => {\n${code}\n})();\n`; } -// A fresh mock of the chrome APIs the worker touches. `onBeforeSendHeaders`, -// `onBeforeRequest`, and `tabs.onRemoved` capture their listener so the test can -// drive them; `declarativeNetRequest.updateSessionRules` records the live rules. + // A fresh mock of the chrome APIs the worker touches. `onBeforeRequest` and + // `tabs.onRemoved` capture their listener, and `tabs.get` serves the source + // tab's URL (the captured referer); `declarativeNetRequest.updateSessionRules` + // records the live rules. function makeChromeEnv() { const storage = {}; const handlers = { onMessage: [] }; + const tabUrls = {}; let sessionRules = {}; const webRequest = { - onBeforeSendHeaders: { addListener: (cb, filter) => { handlers.onBeforeSendHeaders = cb; handlers.onBeforeSendHeadersFilter = filter; } }, onBeforeRequest: { addListener: (cb) => { handlers.onBeforeRequest = cb; } }, - }; + }; const chrome = { storage: { @@ -62,8 +63,9 @@ function makeChromeEnv() { }, webRequest, tabs: { + get: async (tabId) => tabUrls[tabId] ? { tabId, url: tabUrls[tabId] } : undefined, onRemoved: { addListener: (cb) => { handlers.onRemoved = cb; } }, - }, + }, runtime: { onMessage: { addListener: (cb) => { handlers.onMessage.push(cb); } } }, declarativeNetRequest: { updateSessionRules: async ({ removeRuleIds = [], addRules = [] } = {}) => { @@ -76,7 +78,9 @@ function makeChromeEnv() { }, }; - return { chrome, handlers, storage, getSessionRules: () => sessionRules }; + return { chrome, handlers, storage, tabUrls, + setTabUrl: (tabId, url) => { tabUrls[tabId] = url; }, + getSessionRules: () => sessionRules }; } // Load the worker into a fresh environment. `data:` URLs are cached by Node, so @@ -92,12 +96,12 @@ async function loadBackground(env) { return module; } -function videoDetails(tabId, url, referer) { - return { - tabId, - url, - requestHeaders: referer ? [{ name: 'Referer', value: referer }] : [], - }; +// Drive a referer capture the way the worker now does it: the worker reads the +// source tab's URL (via chrome.tabs.get) as the provider referer, so we set the +// tab's URL and fire an onBeforeRequest for a video URL on that tab. +async function capture(env, videoUrl, referer) { + env.setTabUrl(11, referer); + await env.handlers.onBeforeRequest({ tabId: 11, url: videoUrl }); } describe('PR#5: per-host referer capture + proxy race', () => { @@ -108,10 +112,8 @@ describe('PR#5: per-host referer capture + proxy race', () => { global.chrome = env.chrome; await loadBackground(env); - // A live source tab captures the provider referer for its CDN host. - const cap = env.handlers.onBeforeSendHeaders; - if (!cap) throw new Error('onBeforeSendHeaders listener was not registered'); - await cap(videoDetails(11, 'https://cdnA.example.com/hls/live/seg-1.ts', 'https://pageA.example.com/watch')); + // A live source tab captures the provider referer for its CDN host. + await capture(env, 'https://cdnA.example.com/hls/live/seg-1.ts', 'https://pageA.example.com/watch'); const rA = env.storage['goon_referers']?.['example.com']; if (!rA) throw new Error('referer was not captured for cdnA'); @@ -136,9 +138,7 @@ describe('PR#5: per-host referer capture + proxy race', () => { global.chrome = env.chrome; await loadBackground(env); - await env.handlers.onBeforeSendHeaders( - videoDetails(11, 'https://cdnB.example.com/video/x/master.m3u8', 'https://pageB.example.com/v') - ); + await capture(env, 'https://cdnB.example.com/video/x/master.m3u8', 'https://pageB.example.com/v'); // The very tab that captured the referer now closes. await env.handlers.onRemoved(11); @@ -252,11 +252,10 @@ describe('PR#5: per-host referer capture + proxy race', () => { }); await loadBackground(env); - // Capture the provider referer for hv-h.phncdn.com (one edge subdomain). - await env.handlers.onBeforeSendHeaders( - videoDetails(11, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch')); + // Capture the provider referer for hv-h.phncdn.com (one edge subdomain). + await capture(env, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch'); - // Proxy a SIBLING subdomain ev-h.phncdn.com with NO referer in the message: + // Proxy a SIBLING subdomain ev-h.phncdn.com with NO referer in the message: // the SW must resolve it from the domain-keyed store. const handler = env.handlers.onMessage[env.handlers.onMessage.length - 1]; let resp; @@ -314,9 +313,8 @@ describe('PR#5: per-host referer capture + proxy race', () => { global.chrome = env.chrome; await loadBackground(env); - // Capture for hv-h.phncdn.com only. - await env.handlers.onBeforeSendHeaders( - videoDetails(11, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch')); + // Capture for hv-h.phncdn.com only. + await capture(env, 'https://hv-h.phncdn.com/hls/live/seg-1.ts', 'https://provider.example.com/watch'); const handler = env.handlers.onMessage[env.handlers.onMessage.length - 1]; let resp; @@ -339,20 +337,28 @@ describe('PR#5: per-host referer capture + proxy race', () => { } }); - // Regression for the live 412 bug: the capture listener MUST request - // requestHeaders via extraInfoSpec, or details.requestHeaders is undefined and - // readReferer() returns '' for every request — so no referer is ever stored, - // every entry stays referer-less, and the phncdn proxy 412s. The callback-level - // tests above pass even without this (they hand requestHeaders in directly), so - // this asserts the registration itself. - it('the onBeforeSendHeaders capture listener requests requestHeaders via extraInfoSpec', async () => { - const env = makeChromeEnv(); - global.chrome = env.chrome; - await loadBackground(env); - const filter = env.handlers.onBeforeSendHeadersFilter; - if (!filter) throw new Error('onBeforeSendHeaders listener registered no filter object'); - if (!Array.isArray(filter.extraInfoSpec) || !filter.extraInfoSpec.includes('requestHeaders')) { - throw new Error('capture listener did not request requestHeaders via extraInfoSpec: ' + JSON.stringify(filter)); + // Regression for the live 412 bug: the worker captures the provider referer + // from the source tab's URL via chrome.tabs.get inside onBeforeRequest. The + // old path read request headers via onBeforeSendHeaders + extraInfoSpec, which + // is rejected by some Chromium builds and fails the whole service worker, so it + // was removed; this asserts the new tab-URL capture is wired up and actually + // stores a referer. + it('the onBeforeRequest capture reads the referer from the source tab URL', async () => { + const env = makeChromeEnv(); + global.chrome = env.chrome; + await loadBackground(env); + + const cap = env.handlers.onBeforeRequest; + if (!cap) throw new Error('onBeforeRequest listener was not registered'); + + // A video request for cdnA from a tab whose URL IS the provider referer. + env.setTabUrl(11, 'https://pageA.example.com/watch'); + await cap({ tabId: 11, url: 'https://cdnA.example.com/hls/live/seg-1.ts' }); + + const rA = env.storage['goon_referers']?.['example.com']; + if (!rA) throw new Error('referer was not captured from the source tab URL'); + if (rA.referer !== 'https://pageA.example.com/watch') { + throw new Error('captured referer wrong: ' + JSON.stringify(rA)); } - }); - }); + }); + });