diff options
Diffstat (limited to 'packages/meshbay-hub/tests')
| -rw-r--r-- | packages/meshbay-hub/tests/test_downloads.py | 13 | ||||
| -rw-r--r-- | packages/meshbay-hub/tests/test_spa_ordering.py | 30 |
2 files changed, 43 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_downloads.py b/packages/meshbay-hub/tests/test_downloads.py index cc4fdd1..cd0cded 100644 --- a/packages/meshbay-hub/tests/test_downloads.py +++ b/packages/meshbay-hub/tests/test_downloads.py @@ -95,3 +95,16 @@ say(await M.freeName('clip.mp4', async n => n === 'clip.mp4')); def test_a_browser_without_the_api_reports_it(tmp_path): """`SUPPORTED` decides whether Settings offers a choice or an explanation.""" assert _run("say(M.SUPPORTED);", tmp_path) == [False] + + +def test_the_open_action_reads_the_file_back(tmp_path): + """ + "Open" is the browser being handed the bytes, not a desktop application + being started — no web page can do the second, and none can show a file + manager either. It is only offered for a file written into a granted folder, + since that is the one a page can read back. + """ + src = DOWNLOADS.read_text() + target = src[src.index("export async function openTarget"):] + assert "getFile()" in target and "window.open(" in target + assert "revokeObjectURL" in target, "the blob URL must not be leaked" diff --git a/packages/meshbay-hub/tests/test_spa_ordering.py b/packages/meshbay-hub/tests/test_spa_ordering.py index 04c5159..79d7c9a 100644 --- a/packages/meshbay-hub/tests/test_spa_ordering.py +++ b/packages/meshbay-hub/tests/test_spa_ordering.py @@ -199,3 +199,33 @@ def test_the_files_panel_no_longer_carries_its_own_progress_bars(): app = APP.read_text() for gone in ("setUlState", "setDlState", "dl-bar"): assert gone not in app, f"{gone} survived the move to the transfer widget" + + +# ── Downloading a selection ───────────────────────────────────────────────── + +def test_a_multi_file_download_waits_for_each_picker(): + """ + A browser allows one file picker at a time. Firing every download at once + meant the first opened a dialog and the rest were rejected — two files + selected, one file downloaded. + """ + app = APP.read_text() + block = app[app.index("${selectedFiles.length > 0 && html`"):] + block = block[:block.index("`}")] + assert "await downloadFile(e)" in block, ( + "downloads are fired without awaiting again; only the first will ask " + "for a save location and the others will be rejected") + + +def test_links_in_chat_are_built_as_elements_not_markup(): + """ + A message is something another member wrote. It becomes an anchor element, + never HTML, and only for http(s) — otherwise javascript: would be one + message away from running here. + """ + app = APP.read_text() + fn = app[app.index("function linkify("):] + fn = fn[:fn.index("\nfunction ", 1)] + assert "innerHTML" not in fn and "dangerouslySetInnerHTML" not in fn + assert 'rel="noopener noreferrer"' in fn + assert "https?" in app[app.index("const URL_RE"):app.index("function linkify(")] |