aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_streamed_download_reliability.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests/test_streamed_download_reliability.py')
-rw-r--r--packages/meshbay-hub/tests/test_streamed_download_reliability.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_streamed_download_reliability.py b/packages/meshbay-hub/tests/test_streamed_download_reliability.py
index 9e6f77d..3033a95 100644
--- a/packages/meshbay-hub/tests/test_streamed_download_reliability.py
+++ b/packages/meshbay-hub/tests/test_streamed_download_reliability.py
@@ -110,6 +110,16 @@ Object.defineProperty(globalThis, 'navigator', {
globalThis.window = globalThis;
globalThis.isSecureContext = true;
+// The self-test's repair reloads once and remembers it for the tab; both have
+// to exist here or priming the worker throws instead of repairing.
+const session = new Map();
+globalThis.sessionStorage = {
+ getItem: k => (session.has(k) ? session.get(k) : null),
+ setItem: (k, v) => session.set(k, String(v)),
+ removeItem: k => session.delete(k),
+};
+log.reloads = 0;
+globalThis.location = { reload: () => { log.reloads += 1; } };
globalThis.document = {
createElement: () => ({ hidden: false, src: '', remove() {} }),
body: {
@@ -377,3 +387,67 @@ if (target) await target.writable.close();
"the stuck registration was left in place")
assert out["target"] is True, (
"discarding it did not get the page a worker it could stream to")
+
+
+# ── A page the worker cannot serve ──────────────────────────────────────────
+
+def test_a_page_the_worker_cannot_serve_reloads_itself_once(tmp_path):
+ """Being controlled is not being servable, and the gap is a real failure.
+
+ A document fetched by a hard reload — Ctrl+F5, Ctrl+Shift+R — is loaded with
+ the service worker bypassed. It can be claimed afterwards, so `controller`
+ comes back and every check in `_claimController` passes; but the navigations
+ it starts keep missing the worker, and the hidden iframe a streamed download
+ needs is a navigation. Every download then fails with "the worker did not
+ answer" for the life of that page — on Firefox and Safari, the only path
+ there is for a file too large to hold in memory.
+
+ Reported after an operator was told to hard-reload after each deployment:
+ four downloads out of four worked on a freshly started browser, and the
+ first attempt after a Ctrl+F5 failed, every time. An ordinary reload puts
+ the document back under the worker, so priming does exactly that, once.
+ """
+ out = _run(tmp_path, """
+ M.primeServiceWorker();
+ await new Promise((r) => setTimeout(r, 6000));
+ out.reloads = log.reloads;
+ """, serve="never")
+ assert out["reloads"] == 1, (
+ "a page that cannot be served by the worker was left that way")
+
+
+def test_a_page_that_works_is_not_reloaded(tmp_path):
+ """The self-test costs milliseconds when it passes, and must cost nothing
+ else. Reloading a healthy page at boot would be a flicker on every visit."""
+ out = _run(tmp_path, """
+ M.primeServiceWorker();
+ await new Promise((r) => setTimeout(r, 3000));
+ out.reloads = log.reloads;
+ """)
+ assert out["reloads"] == 0
+
+
+def test_the_repair_happens_at_most_once(tmp_path):
+ """The flag is in sessionStorage rather than a variable because the point is
+ to survive the reload it triggers. If reloading does not help, the page
+ stays broken and says so — it does not reload again, and again."""
+ out = _run(tmp_path, """
+ sessionStorage.setItem('meshbay.sw-repaired', '1');
+ M.primeServiceWorker();
+ await new Promise((r) => setTimeout(r, 6000));
+ out.reloads = log.reloads;
+ """, serve="never")
+ assert out["reloads"] == 0, "a page that had already been repaired reloaded again"
+
+
+def test_the_self_test_leaves_no_file_behind(tmp_path):
+ """It opens a real download target to ask a real question, so it must also
+ tear it down: a completed one would drop `meshbay-selftest.bin` into the
+ download folder on every page load."""
+ src = DOWNLOADS.read_text()
+ fn = src[src.index("async function _canServeDownloads"):]
+ fn = fn[:fn.index("\n}\n")]
+ assert "writable.abort" in fn, (
+ "the self-test's stream is never aborted, so the browser keeps what it "
+ "was given")
+ assert "frame.remove" in fn