aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_portable_save_names.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-28 22:25:07 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-28 22:25:07 +0200
commit7cec0e9199753e11b95500da14d3fd89835e1aa3 (patch)
treec134f460c9dba281db2fe32712766cf9524ca9da /packages/meshbay-hub/tests/test_portable_save_names.py
parentf04b4e0c4350a5acc539a8f15bc9df4bfd10a537 (diff)
downloadmeshbay-7cec0e9199753e11b95500da14d3fd89835e1aa3.tar.gz
feat(client): save files under a name every platform can write
A node serves the name its disk gave a file; the client now makes it portable at save time (single file, zip entries, zip name) and says so on the transfer row. Same rule as paths.sanitize_for_download, held by a parity test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/tests/test_portable_save_names.py')
-rw-r--r--packages/meshbay-hub/tests/test_portable_save_names.py42
1 files changed, 42 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_portable_save_names.py b/packages/meshbay-hub/tests/test_portable_save_names.py
new file mode 100644
index 0000000..05a4af7
--- /dev/null
+++ b/packages/meshbay-hub/tests/test_portable_save_names.py
@@ -0,0 +1,42 @@
+"""
+Every way a file is saved goes through a name that can be written everywhere
+(docs/MESHBAY_DESIGN.md §10, `static/portable-name.js`).
+
+The rule itself is held to Python's by `test_portable_name_parity.py`. What this
+holds is that the save paths use it: a single file under `portableName`, the
+entries of a folder's zip and the archive's own name under `portablePath` /
+`portableName`, and the node's own name never handed to a save target directly.
+Read from the source, because these paths need a browser and a disk to run.
+"""
+
+import re
+from pathlib import Path
+
+STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static"
+FILE_UTILS = (STATIC / "file-utils.js").read_text(encoding="utf-8")
+
+
+def _body(name: str) -> str:
+ m = re.search(rf"^async function {name}\(.*?^\}}", FILE_UTILS, re.M | re.S)
+ assert m, f"file-utils.js no longer has {name}"
+ return m.group(0)
+
+
+def test_a_single_file_is_saved_under_a_portable_name():
+ body = _body("downloadEntry")
+ assert "portableName(entry.name)" in body
+ assert "_openTargetInTurn(saveName" in body
+ assert "_saveBlob(blob, saveName)" in body
+ assert "_openTargetInTurn(entry.name" not in body
+ assert "_saveBlob(blob, entry.name)" not in body
+
+
+def test_a_zip_writes_portable_names_and_is_named_portably():
+ body = _body("downloadDirectory")
+ assert "zip.begin(portablePath(name)" in body
+ assert "portableName(dir.split('/').pop()" in body
+
+
+def test_a_renamed_file_is_said_so_on_its_row():
+ assert "t('transfers.renamed'" in _body("downloadEntry")
+ assert "t('transfers.renamed_n'" in _body("downloadDirectory")