| 1 | from pathlib import Path |
| 2 | |
| 3 | |
| 4 | PROJECT_ROOT = Path(__file__).resolve().parents[1] |
| 5 | |
| 6 | |
| 7 | def read(*parts: str) -> str: |
| 8 | return PROJECT_ROOT.joinpath(*parts).read_text(encoding="utf-8") |
| 9 | |
| 10 | |
| 11 | def test_root_service_worker_prepares_one_bundle_and_caches_runtime_misses() -> None: |
| 12 | worker = read("webui", "sw.js") |
| 13 | |
| 14 | assert 'event.data?.type !== "preload-ui-bundle"' in worker |
| 15 | assert "const replyPort = event.ports?.[0];" in worker |
| 16 | assert 'replyPort?.postMessage({ ok: true, version: activeAssetVersion })' in worker |
| 17 | assert worker.index("replyPort?.postMessage({ ok: true") < worker.index( |
| 18 | "event.waitUntil(cachePopulation.promise" |
| 19 | ) |
| 20 | assert "await cache.put(request, response);" in worker |
| 21 | assert "activeBundleEntries.get(request.url)" in worker |
| 22 | assert "responseFromEntry(bundledEntry)" in worker |
| 23 | assert "const cached = await cache.match(request);" in worker |
| 24 | assert "const MAX_RUNTIME_CACHEABLE_TRANSFER_BYTES = 256 * 1024;" in worker |
| 25 | assert "CACHEABLE_FILE_PATTERN" in worker |
| 26 | assert "cacheRuntimeResponse(" in worker |
| 27 | assert 'entry[1] === "text"' in worker |
| 28 | assert "decodeBase64" not in worker |
| 29 | assert "body.byteLength > MAX_RUNTIME_CACHEABLE_TRANSFER_BYTES" in worker |
| 30 | assert "cacheMarkerRequest(targetCacheName)" in worker |
| 31 | assert "cacheBundleRequest(targetCacheName)" in worker |
| 32 | assert "new Response(JSON.stringify(bundle)" in worker |
| 33 | assert "const bundle = await response.json();" in worker |
| 34 | assert "await restorePersistedBundle();" in worker |
| 35 | assert "return fetchBackendAsset(request, cache);" in worker |
| 36 | assert "cleanupCaches(activeCacheName)" in worker |
| 37 | assert "catch(() => fetch(event.request))" in worker |
| 38 | assert "asset-graph" not in worker |
| 39 | assert "queueGraphRequest" not in worker |
| 40 | assert "preloadNetworkFiles" not in worker |
| 41 | assert "self.clients.get" not in worker |
| 42 | assert "CompressionStream" not in worker |
| 43 | assert 'url.pathname.startsWith("/api/")' in worker |
| 44 | assert 'request.mode === "navigate"' in worker |
| 45 | |
| 46 | |
| 47 | def test_splash_registers_root_cache_without_frontend_loader_hooks() -> None: |
| 48 | index = read("webui", "index.html") |
| 49 | splash = read("webui", "splash.html") |
| 50 | components = read("webui", "js", "components.js") |
| 51 | extensions = read("webui", "js", "extensions.js") |
| 52 | init_fw = read("webui", "js", "initFw.js") |
| 53 | |
| 54 | assert 'fetch("/ui/asset-bundle"' in splash |
| 55 | assert 'fetch("/ui/asset-bundle"' not in index |
| 56 | assert 'id="ui-asset-bundle"' not in index |
| 57 | assert 'navigator.serviceWorker.register(expectedUrl' in splash |
| 58 | assert 'updateViaCache: "none"' in splash |
| 59 | assert "preload-ui-bundle" in splash |
| 60 | assert "new MessageChannel()" in splash |
| 61 | assert "await sendBundle(worker, bundle, true)" in splash |
| 62 | assert "webuiComponentCache" not in components |
| 63 | assert "preload-ui-bundle" not in components |
| 64 | assert "preload-ui-bundle" not in extensions |
| 65 | assert "preload-ui-bundle" not in init_fw |