""" "Copy link": the `#/name@owner/path` address of a file or folder, from the views that show one (harness/copy_link_probe.py). Files offers it for one row — right-click, or the toolbar with one row ticked, which is how a phone reaches it; Music on one track's menu, whose dots are a phone's way in; Photos on a right-clicked tile and in the lightbox. The video player and the file preview carry a button. Search passes the same `linkFor`, naming each result's own group and its path there rather than the merged tree's. """ import json import re import shutil import subprocess import sys from pathlib import Path import pytest HARNESS = Path(__file__).parent / "harness" / "copy_link_probe.py" STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static" ORIGIN = "http://127.0.0.1:8775" @pytest.fixture(scope="module") def cases(): if shutil.which("google-chrome") is None: pytest.skip("Chrome is not available") proc = subprocess.run([sys.executable, str(HARNESS)], capture_output=True, text=True, timeout=180) assert proc.returncode == 0, f"probe failed: {proc.stdout}{proc.stderr}" out = json.loads(proc.stdout) assert "error" not in out, out["error"] assert out["logs"] == [] return {c["case"]: c for c in out["cases"]} def test_files_a_folder(cases): c = cases["files folder"] assert "Copy link" in c["labels"] assert c["copied"] == f"{ORIGIN}/#/demo@someowner/Root" assert c["note"] == "Link copied" def test_files_a_file(cases): c = cases["files file"] assert c["labels"].index("Copy link") > c["labels"].index("Download") assert c["copied"] == f"{ORIGIN}/#/demo@someowner/Root/trip_2015/IMG%200001.JPG" def test_files_toolbar_one_ticked_row_only(cases): c = cases["files toolbar"] assert c["one_enabled"] is True and c["two_enabled"] is False assert c["copied"] == f"{ORIGIN}/#/demo@someowner/Root/trip_2015/notes.txt" def test_music_a_track_from_its_dots(cases): c = cases["music track"] assert c["dots"] and c["labels"][-1] == "Copy link" assert c["copied"] == f"{ORIGIN}/#/demo@someowner/Music/Some%20Album/track%2001.flac" def test_photos_tile_and_lightbox(cases): c = cases["photos"] link = f"{ORIGIN}/#/demo@someowner/Pics/Summer/beach.jpg" assert c["labels"] == ["Copy link"] and c["copied"] == link assert c["lightbox_button"] and c["lightbox_copied"] == link @pytest.mark.parametrize("module", ["video-player.js", "files-app.js"]) def test_the_modals_carry_a_link_button(module): source = (STATIC / module).read_text(encoding="utf-8") assert re.search(r"function (VideoPlayer|FilePreview)\(\{[^}]*onCopyLink", source) assert "${onCopyLink && html`" in source @pytest.mark.parametrize("page, n", [("group-page.js", 2), ("search-page.js", 2)]) def test_both_pages_hand_the_modals_a_link(page, n): source = (STATIC / page).read_text(encoding="utf-8") assert source.count("onCopyLink=${linkFor(") == n def test_search_names_each_results_own_group_and_path(): source = (STATIC / "search-page.js").read_text(encoding="utf-8") # Every view prefixes `path`; the link is built from the original. assert source.count("_origPath: e.path,") == 4 assert "entryPath(target, target._origPath)" in source for view in ("FilesPanel", "MusicApp", "PhotosApp"): at = source.index(f"<${{{view}}}") assert "linkFor=${linkFor}" in source[at:source.index("/>", at)], view def test_the_link_is_the_hubs_not_the_pages(): """In the desktop application the page is app://meshbay.""" source = (STATIC / "copy-link.js").read_text(encoding="utf-8") assert "platform.hubOrigin() + '/#' + groupLinkRoute(" in source assert "location.origin" not in source