"""A share link's address says what it opens: /watch/ a video, /file/ anything else, /folder/ a folder. Only a word for the reader: the token is the key, so every path opens every link, and the links already sent out on /watch/ keep working for good. DB-lane. """ import pytest from cryptography.fernet import Fernet from app import main, security from app.config import settings from app.downloads import og from app.downloads import probe as probemod _PAGE = """
""" _VIDEO = { "streams": [ {"codec_type": "video", "codec_name": "h264", "pix_fmt": "yuv420p"}, {"codec_type": "audio", "codec_name": "aac"}, ], "format": {"format_name": "mov,mp4", "duration": "5"}, } _AUDIO = { "streams": [{"codec_type": "audio", "codec_name": "aac"}], "format": {"format_name": "mov,mp4", "duration": "5"}, } @pytest.fixture def pages(tmp_path, monkeypatch): index, watch = tmp_path / "index.html", tmp_path / "watch.html" index.write_text(_PAGE.format(entry="app"), encoding="utf-8") watch.write_text(_PAGE.format(entry="watch"), encoding="utf-8") monkeypatch.setattr(main, "INDEX_HTML", index) monkeypatch.setattr(main, "WATCH_HTML", watch) @pytest.fixture def key(monkeypatch): """A link's address is read back from its encrypted token.""" monkeypatch.setattr(security, "_fernet", Fernet(Fernet.generate_key())) @pytest.fixture def shared(as_user, make_user, tmp_path, monkeypatch, upload_headers): """Uploads a file ffprobe reads as `data` (None: it cannot read it) and shares it.""" monkeypatch.setattr(settings, "files_root", str(tmp_path / "media")) owner = as_user(make_user()) def share(name: str, data: dict | None, **link: object) -> dict: monkeypatch.setattr(probemod, "probe_json", lambda _p: data) job = owner.post( "/api/files/upload", content=b"some bytes", headers=upload_headers(name, display_name=name), ) assert job.status_code == 200, job.text made = owner.post(f"/api/downloads/{job.json()['id']}/links", json=link) assert made.status_code == 200, made.text return made.json() share.owner = owner # type: ignore[attr-defined] return share @pytest.mark.parametrize( ("name", "data", "prefix"), [ ("clip.mp4", _VIDEO, "/watch/"), ("song.m4a", _AUDIO, "/file/"), ("backup.tar.gz", None, "/file/"), ], ) def test_a_link_is_given_out_on_the_path_of_what_it_opens(shared, name, data, prefix): made = shared(name, data) assert made["url"] == f"{prefix}{made['token']}" def test_a_folder_link_is_given_out_on_folder(shared, key): owner = shared.owner folder = owner.post("/api/files/folders", json={"name": "Friends"}).json() made = owner.post(f"/api/downloads/folders/{folder['id']}/links", json={}).json() assert made["url"] == f"/folder/{made['token']}" listed = owner.get(f"/api/downloads/folders/{folder['id']}/links").json() assert [entry["url"] for entry in listed] == [made["url"]] def test_the_list_gives_the_same_address_as_the_making(shared, key): made = shared("backup.tar.gz", None) owner = shared.owner files = owner.get("/api/files").json() job_id = next(f["id"] for f in files if f["display_name"] == "backup.tar.gz") listed = owner.get(f"/api/downloads/{job_id}/links").json() assert [entry["url"] for entry in listed] == [made["url"]] @pytest.mark.parametrize("path", ["watch", "file", "folder"]) @pytest.mark.parametrize( ("name", "data"), [("clip.mp4", _VIDEO), ("backup.tar.gz", None)], ids=["video", "file"] ) def test_every_path_opens_every_link(pages, shared, client, path, name, data): """The links already sent on /watch/ open whatever they open, for good.""" token = shared(name, data)["token"] r = client.get(f"/{path}/{token}") assert r.status_code == 200 assert "/assets/watch.js" in r.text and "/assets/app.js" not in r.text assert f'content="{name}"' in r.text @pytest.mark.parametrize("path", ["/file/no-such-token", "/folder/no-such-token", "/file/a/b"]) def test_a_new_path_without_a_live_link_still_gets_the_player(pages, client, path): r = client.get(path) assert r.status_code == 200 assert "/assets/watch.js" in r.text and "/assets/app.js" not in r.text def test_a_card_names_a_file_as_a_file(shared, db): made = shared("backup.tar.gz", None) tags = og._watch_tags(made["token"], db) assert f'{made["url"]}"' in tags assert "video.other" not in tags locked = shared("notes.tar.gz", None, password="pw") hidden = og._watch_tags(locked["token"], db) assert "Password-protected file" in hidden and "notes" not in hidden assert "video.other" not in hidden def test_a_card_of_a_video_stays_a_video(shared, db): made = shared("clip.mp4", _VIDEO) tags = og._watch_tags(made["token"], db) assert f"/watch/{made['token']}" in tags and "video.other" in tags locked = shared("other.mp4", _VIDEO, password="pw") assert "Password-protected video" in og._watch_tags(locked["token"], db) @pytest.mark.parametrize( ("name", "data", "video"), [("clip.mp4", _VIDEO, True), ("song.m4a", _AUDIO, False), ("backup.tar.gz", None, False)], ) def test_a_password_link_says_whether_it_opens_a_video(shared, client, name, data, video): """The lock screen asks to watch a video and to open anything else, whichever path it is on.""" token = shared(name, data, password="pw")["token"] meta = client.get(f"/api/public/watch/{token}").json() assert meta == {"needs_password": True, "kind": "file", "video": video}