Release 2.22.0: normalize playlist schedules and unify player sync
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m21s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 32s

This commit is contained in:
lzstealth committed 2026-10-27 22:54:38 +00:00
1 parent 7748129307
commit b71958cb38
39 files changed
+1174 -314

No files matched your search

+39 -2
View File
@@ -62,10 +62,11 @@ test('player service worker retention supports opaque versions before active cac
]);
});
function createFetchWorker({ failure, cachedResponse = null, fetchError = false } = {}) {
function createFetchWorker({ failure, cachedResponse = null, cacheMatchResponse = null, fetchError = false, networkStatus = 200 } = {}) {
const networkResponse = new Response('fresh network body', {
status: 200, headers: { ETag: '"fresh"', 'Content-Type': 'text/plain' }
status: networkStatus, headers: { ETag: '"fresh"', 'Content-Type': 'text/plain' }
});
const namedCacheResponse = cacheMatchResponse === null ? cachedResponse : cacheMatchResponse;
const calls = { fetch: 0, writes: [] };
const listeners = new Map();
const sandbox = {
@@ -87,6 +88,7 @@ function createFetchWorker({ failure, cachedResponse = null, fetchError = false
async open() {
if (failure === 'open') throw new Error('Cache storage unavailable');
return {
async match() { return namedCacheResponse; },
async put(key, response) {
if (failure === 'put') throw new Error('QuotaExceededError');
calls.writes.push({ key, response });
@@ -158,4 +160,39 @@ test('player script assets refresh from network and retain offline cache fallbac
respondWith(promise) { offlineResponsePromise = promise; }
});
assert.equal(await offlineResponsePromise, cachedResponse);
});
test('playlist HTTP errors are not hidden by a stale cached playlist', async () => {
const cachedResponse = new Response('stale playlist body', { status: 200 });
const worker = createFetchWorker({ cachedResponse, networkStatus: 403 });
const request = new Request('http://localhost/api/screens/test/playlist?ts=2');
const response = await worker.sandbox.networkFirst(
request,
'playlists',
{ url: 'http://localhost/api/screens/test/playlist' },
false
);
assert.equal(response.status, 403);
assert.equal(await response.text(), 'fresh network body');
});
test('playlist offline fallback does not read an older cache generation', async () => {
const staleResponse = new Response('stale QR playlist', { status: 200 });
const currentResponse = new Response('current Video playlist', { status: 200 });
const worker = createFetchWorker({
cachedResponse: staleResponse,
cacheMatchResponse: currentResponse,
fetchError: true
});
const request = new Request('http://localhost/api/screens/test/playlist?ts=3');
const response = await worker.sandbox.networkFirst(
request,
'playlists-current',
{ url: 'http://localhost/api/screens/test/playlist' },
false
);
assert.equal(response, currentResponse);
assert.equal(await response.text(), 'current Video playlist');
});