From adea7583f03176abd0723a0d92d873817a926715 Mon Sep 17 00:00:00 2001 From: imSp4rky Date: Sat, 5 Sep 2026 22:16:22 -0600 Subject: [PATCH] test(services): use placeholder tags instead of real service names --- docs/dev/rest-api/dashboard.md | 6 +-- tests/core/test_cdm_detect.py | 14 +++--- tests/core/test_config_resolution.py | 44 +++++++++---------- tests/core/test_service_repo.py | 6 ++- .../unit/test_download_gates_redaction.py | 18 ++++---- tests/remote/unit/test_download_manager.py | 26 +++++------ tests/remote/unit/test_errors.py | 4 +- tests/remote/unit/test_remote_client.py | 4 +- .../unit/test_remote_command_unknown_tag.py | 30 ++++++++----- tests/remote/unit/test_remote_resolve.py | 4 +- .../unit/test_remote_service_helpers.py | 6 +-- tests/remote/unit/test_session_store.py | 18 ++++---- tests/tracks/test_hybrid_selection.py | 4 +- 13 files changed, 97 insertions(+), 87 deletions(-) diff --git a/docs/dev/rest-api/dashboard.md b/docs/dev/rest-api/dashboard.md index 77524dd8..e1d8cf68 100644 --- a/docs/dev/rest-api/dashboard.md +++ b/docs/dev/rest-api/dashboard.md @@ -117,7 +117,7 @@ never keeps it alive or makes it look active. ``` GET /api/dashboard/keys -[{"id": "3ed054be9371", "role": "user", "label": "tier1", "services": ["ATV", "DSNP"], +[{"id": "3ed054be9371", "role": "user", "label": "tier1", "services": ["EXAMPLE", "DEMO"], "server_cdm": false, "server_accounts": false, "server_proxy": false, "tier": "bot", "rate_limit": 600, "window_used": 412, "requests": 41300, "rejected": 4, "bytes_out": 103079215104, "last_seen": 1756909188.2}, @@ -179,10 +179,10 @@ limit never applies to the dashboard key, and never to `/api/health`. ``` GET /api/dashboard/services -[{"tag": "MAX", "state": "staged", "error": null, +[{"tag": "EXAMPLE", "state": "staged", "error": null, "commit": "9cc230c98f13b83f6c6fe831595b9702d3ba2786", "staged_commit": "5f0aa17...", "staged_since": 1756908900.0, "sessions": 1, "jobs": 1, - "aliases": ["HBO"], "geofence": ["US"]}] + "aliases": ["EXMPL"], "geofence": ["US"]}] ``` `state` is `loaded`, `staged` or `failed`. A service that failed to import keeps its error diff --git a/tests/core/test_cdm_detect.py b/tests/core/test_cdm_detect.py index 55c0736f..6e3f50e4 100644 --- a/tests/core/test_cdm_detect.py +++ b/tests/core/test_cdm_detect.py @@ -2,9 +2,9 @@ Covers the predicates in ``unshackle.core.cdm.detect`` (playready/widevine, local/remote, and the remote combinations) and the loader stamping that sets a remote CDM's DRM type at -load time instead of guessing it on each call. Services such as AMZN route to a device -profile off that type, so a wrong classification here is what produces a Downgrade.Hd -license denial. +load time instead of guessing it on each call. Services such as EXAMPLE choose a device +profile from that type, so a wrong classification here is what produces a licence denial +for the requested resolution. """ from __future__ import annotations @@ -143,7 +143,7 @@ def test_stamp_remote_is_best_effort_on_unsettable_object(): def test_load_remote_decryptlabs_playready_is_stamped(): cdm_api = {"name": "dl-pr", "type": "decrypt_labs", "secret": "x", "device_name": "SL3000"} - cdm = loader_mod.load_remote_cdm(dict(cdm_api), "dl-pr", "AMZN", None) + cdm = loader_mod.load_remote_cdm(dict(cdm_api), "dl-pr", "EXAMPLE", None) assert cdm.drm == "playready" assert cdm.is_remote_cdm is True assert is_remote_playready_cdm(cdm) @@ -151,7 +151,7 @@ def test_load_remote_decryptlabs_playready_is_stamped(): def test_load_remote_decryptlabs_widevine_is_stamped(): cdm_api = {"name": "dl-wv", "type": "decrypt_labs", "secret": "x", "device_name": "ChromeCDM"} - cdm = loader_mod.load_remote_cdm(dict(cdm_api), "dl-wv", "AMZN", None) + cdm = loader_mod.load_remote_cdm(dict(cdm_api), "dl-wv", "EXAMPLE", None) assert cdm.drm == "widevine" assert is_remote_widevine_cdm(cdm) @@ -165,7 +165,7 @@ def test_load_remote_native_playready_is_stamped(monkeypatch): monkeypatch.setattr(prmod, "RemoteCdm", FakePlayReadyRemote) cdm_api = {"name": "pr", "Device Type": "PLAYREADY", "host": "h", "secret": "s", "device_name": "d"} - cdm = loader_mod.load_remote_cdm(dict(cdm_api), "pr", "AMZN", None) + cdm = loader_mod.load_remote_cdm(dict(cdm_api), "pr", "EXAMPLE", None) assert isinstance(cdm, FakePlayReadyRemote) assert cdm.drm == "playready" assert cdm.is_remote_cdm is True @@ -181,7 +181,7 @@ def test_load_remote_native_widevine_is_stamped(monkeypatch): monkeypatch.setattr(wvmod, "RemoteCdm", FakeWidevineRemote) cdm_api = {"name": "wv", "Device Type": "ANDROID", "host": "h", "secret": "s", "device_name": "d"} - cdm = loader_mod.load_remote_cdm(dict(cdm_api), "wv", "AMZN", None) + cdm = loader_mod.load_remote_cdm(dict(cdm_api), "wv", "EXAMPLE", None) assert isinstance(cdm, FakeWidevineRemote) assert cdm.drm == "widevine" assert is_remote_widevine_cdm(cdm) diff --git a/tests/core/test_config_resolution.py b/tests/core/test_config_resolution.py index 09d64caf..ad73eb56 100644 --- a/tests/core/test_config_resolution.py +++ b/tests/core/test_config_resolution.py @@ -16,29 +16,29 @@ pytestmark = pytest.mark.unit def test_ci_get_exact_and_case_insensitive(): - m = {"NF": "a", "Default": "b"} - assert ci_get(m, "NF") == "a" - assert ci_get(m, "nf") == "a" + m = {"DEMO": "a", "Default": "b"} + assert ci_get(m, "DEMO") == "a" + assert ci_get(m, "demo") == "a" assert ci_get(m, "default") == "b" assert ci_get(m, "missing") is None assert ci_get(m, "missing", "fallback") == "fallback" - assert ci_get({}, "NF", "fallback") == "fallback" + assert ci_get({}, "DEMO", "fallback") == "fallback" def test_decryption_map_keys_upper_cased_on_build(): - c = Config(decryption={"cr": "mp4decrypt", "default": "shaka"}) - assert c.decryption_map == {"CR": "mp4decrypt", "DEFAULT": "shaka"} + c = Config(decryption={"example": "mp4decrypt", "default": "shaka"}) + assert c.decryption_map == {"EXAMPLE": "mp4decrypt", "DEFAULT": "shaka"} assert c.decryption == "shaka" def test_resolve_decryption_per_service_and_default(): - c = Config(decryption={"CR": "mp4decrypt", "default": "shaka"}) - assert resolve_decryption(c.decryption_map, c.decryption, "CR") == "mp4decrypt" + c = Config(decryption={"EXAMPLE": "mp4decrypt", "default": "shaka"}) + assert resolve_decryption(c.decryption_map, c.decryption, "EXAMPLE") == "mp4decrypt" # service not mapped -> default - assert resolve_decryption(c.decryption_map, c.decryption, "NF") == "shaka" + assert resolve_decryption(c.decryption_map, c.decryption, "DEMO") == "shaka" # case-insensitive both ways (lowercase yaml key, mixed-case lookup) - c2 = Config(decryption={"cr": "mp4decrypt", "default": "shaka"}) - assert resolve_decryption(c2.decryption_map, c2.decryption, "Cr") == "mp4decrypt" + c2 = Config(decryption={"example": "mp4decrypt", "default": "shaka"}) + assert resolve_decryption(c2.decryption_map, c2.decryption, "Example") == "mp4decrypt" def test_decryption_scalar_form(): @@ -48,26 +48,26 @@ def test_decryption_scalar_form(): def test_cdm_keys_preserved_on_build(): - c = Config(cdm={"nf": "dev_a", "default": "dev_b"}) - assert c.cdm == {"nf": "dev_a", "default": "dev_b"} + c = Config(cdm={"demo": "dev_a", "default": "dev_b"}) + assert c.cdm == {"demo": "dev_a", "default": "dev_b"} def test_resolve_cdm_name_case_insensitive(): # lowercase yaml key must resolve for an uppercase service tag (the bug being fixed) - c = Config(cdm={"nf": "dev_a", "default": "dev_b"}) - assert resolve_cdm_name(c.cdm, "NF") == "dev_a" + c = Config(cdm={"demo": "dev_a", "default": "dev_b"}) + assert resolve_cdm_name(c.cdm, "DEMO") == "dev_a" # unmapped service -> default - assert resolve_cdm_name(c.cdm, "ATV") == "dev_b" + assert resolve_cdm_name(c.cdm, "EXAMPLE") == "dev_b" # uppercase yaml key, lowercase lookup - c2 = Config(cdm={"NF": "dev_a", "default": "dev_b"}) - assert resolve_cdm_name(c2.cdm, "nf") == "dev_a" + c2 = Config(cdm={"DEMO": "dev_a", "default": "dev_b"}) + assert resolve_cdm_name(c2.cdm, "demo") == "dev_a" def test_resolve_cdm_name_override_wins(): - c = Config(cdm={"NF": "dev_a", "default": "dev_b"}) - assert resolve_cdm_name(c.cdm, "NF", override="dev_override") == "dev_override" + c = Config(cdm={"DEMO": "dev_a", "default": "dev_b"}) + assert resolve_cdm_name(c.cdm, "DEMO", override="dev_override") == "dev_override" def test_resolve_cdm_name_no_match_no_default(): - c = Config(cdm={"NF": "dev_a"}) - assert resolve_cdm_name(c.cdm, "ATV") is None + c = Config(cdm={"DEMO": "dev_a"}) + assert resolve_cdm_name(c.cdm, "EXAMPLE") is None diff --git a/tests/core/test_service_repo.py b/tests/core/test_service_repo.py index be2013d9..6b1c3749 100644 --- a/tests/core/test_service_repo.py +++ b/tests/core/test_service_repo.py @@ -212,9 +212,11 @@ def test_local_dirty_services_lists_edited_dirs(monkeypatch): monkeypatch.setattr( service_repo.subprocess, "run", - lambda *a, **k: subprocess.CompletedProcess(a, 0, b"CR/__init__.py\nCR/config.yaml\nNF/__init__.py\n", b""), + lambda *a, **k: subprocess.CompletedProcess( + a, 0, b"EXAMPLE/__init__.py\nEXAMPLE/config.yaml\nDEMO/__init__.py\n", b"" + ), ) - assert service_repo.local_dirty_services(Path("/x")) == ["CR", "NF"] + assert service_repo.local_dirty_services(Path("/x")) == ["DEMO", "EXAMPLE"] def test_refresh_reports_discarded_local_edits(monkeypatch, tmp_path): diff --git a/tests/remote/unit/test_download_gates_redaction.py b/tests/remote/unit/test_download_gates_redaction.py index a76ce17f..b17a5ae9 100644 --- a/tests/remote/unit/test_download_gates_redaction.py +++ b/tests/remote/unit/test_download_gates_redaction.py @@ -23,7 +23,7 @@ pytestmark = pytest.mark.unit def test_redact_parameters_masks_secrets_and_proxy_userinfo(): params = { - "service": "ATV", + "service": "EXAMPLE", "credential": "user:hunter2", "password": "pw", "token": "tok", @@ -70,7 +70,7 @@ def test_to_dict_full_details_redacts_error_fields_and_parameters(): job_id="j1", status=JobStatus.FAILED, created_time=datetime(2026, 1, 1), - service="ATV", + service="EXAMPLE", title_id="t", parameters={"credential": "user:hunter2"}, ) @@ -102,35 +102,37 @@ def stub_handler(monkeypatch): async def test_cdm_override_forbidden_by_default(stub_handler): stub_handler.setattr(handlers.config, "serve", {}) with pytest.raises(APIError) as ei: - await handlers.download_handler({"service": "ATV", "title_id": "t", "cdm": "dev"}) + await handlers.download_handler({"service": "EXAMPLE", "title_id": "t", "cdm": "dev"}) assert ei.value.error_code == APIErrorCode.FORBIDDEN async def test_cdm_override_allowed_when_enabled(stub_handler): stub_handler.setattr(handlers.config, "serve", {"cdm_overrides": True}) # passing the gate reaches the stubbed Services.load, whose error is caught and returned as a response - resp = await handlers.download_handler({"service": "ATV", "title_id": "t", "cdm": "dev"}) + resp = await handlers.download_handler({"service": "EXAMPLE", "title_id": "t", "cdm": "dev"}) assert isinstance(resp, web.Response) async def test_cdm_override_allowlist_permits_only_named_device(stub_handler): stub_handler.setattr(handlers.config, "serve", {"cdm_overrides": ["good"]}) - assert isinstance(await handlers.download_handler({"service": "ATV", "title_id": "t", "cdm": "good"}), web.Response) + assert isinstance( + await handlers.download_handler({"service": "EXAMPLE", "title_id": "t", "cdm": "good"}), web.Response + ) with pytest.raises(APIError) as ei: - await handlers.download_handler({"service": "ATV", "title_id": "t", "cdm": "other"}) + await handlers.download_handler({"service": "EXAMPLE", "title_id": "t", "cdm": "other"}) assert ei.value.error_code == APIErrorCode.FORBIDDEN async def test_credential_forbidden_by_default(stub_handler): stub_handler.setattr(handlers.config, "serve", {}) with pytest.raises(APIError) as ei: - await handlers.download_handler({"service": "ATV", "title_id": "t", "credential": "u:p"}) + await handlers.download_handler({"service": "EXAMPLE", "title_id": "t", "credential": "u:p"}) assert ei.value.error_code == APIErrorCode.FORBIDDEN async def test_credential_allowed_when_enabled(stub_handler): stub_handler.setattr(handlers.config, "serve", {"allow_job_credentials": True}) - resp = await handlers.download_handler({"service": "ATV", "title_id": "t", "credential": "u:p"}) + resp = await handlers.download_handler({"service": "EXAMPLE", "title_id": "t", "credential": "u:p"}) assert isinstance(resp, web.Response) diff --git a/tests/remote/unit/test_download_manager.py b/tests/remote/unit/test_download_manager.py index 14d3d11f..e3939a0b 100644 --- a/tests/remote/unit/test_download_manager.py +++ b/tests/remote/unit/test_download_manager.py @@ -23,17 +23,17 @@ def manager() -> DownloadQueueManager: def test_create_job_returns_queued_job(manager: DownloadQueueManager) -> None: - job = manager.create_job("ATV", "movie-123", profile="default") + job = manager.create_job("EXAMPLE", "movie-123", profile="default") assert isinstance(job, DownloadJob) assert job.status is JobStatus.QUEUED - assert job.service == "ATV" + assert job.service == "EXAMPLE" assert job.title_id == "movie-123" assert job.parameters == {"profile": "default"} def test_get_and_list_jobs(manager: DownloadQueueManager) -> None: - a = manager.create_job("ATV", "a") - b = manager.create_job("NF", "b") + a = manager.create_job("EXAMPLE", "a") + b = manager.create_job("DEMO", "b") assert manager.get_job(a.job_id) is a assert manager.get_job("missing") is None listed = manager.list_jobs() @@ -41,11 +41,11 @@ def test_get_and_list_jobs(manager: DownloadQueueManager) -> None: def test_to_dict_short_vs_full(manager: DownloadQueueManager) -> None: - job = manager.create_job("ATV", "t", profile="p") + job = manager.create_job("EXAMPLE", "t", profile="p") short = job.to_dict() assert "parameters" not in short assert short["status"] == "queued" - assert short["service"] == "ATV" + assert short["service"] == "EXAMPLE" full = job.to_dict(include_full_details=True) assert full["parameters"] == {"profile": "p"} assert "error_message" in full @@ -53,7 +53,7 @@ def test_to_dict_short_vs_full(manager: DownloadQueueManager) -> None: def test_cancel_queued_job_sets_cancelled_and_signals_event(manager: DownloadQueueManager) -> None: - job = manager.create_job("ATV", "t") + job = manager.create_job("EXAMPLE", "t") assert manager.cancel_job(job.job_id) is True assert job.status is JobStatus.CANCELLED assert job.cancel_event.is_set() @@ -64,13 +64,13 @@ def test_cancel_unknown_job_returns_false(manager: DownloadQueueManager) -> None def test_cancel_completed_job_returns_false(manager: DownloadQueueManager) -> None: - job = manager.create_job("ATV", "t") + job = manager.create_job("EXAMPLE", "t") job.status = JobStatus.COMPLETED assert manager.cancel_job(job.job_id) is False def test_cancel_downloading_job_signals(manager: DownloadQueueManager) -> None: - job = manager.create_job("ATV", "t") + job = manager.create_job("EXAMPLE", "t") job.status = JobStatus.DOWNLOADING assert manager.cancel_job(job.job_id) is True assert job.status is JobStatus.CANCELLED @@ -80,10 +80,10 @@ def test_cancel_downloading_job_signals(manager: DownloadQueueManager) -> None: def test_cleanup_old_jobs_drops_old_terminal_states(manager: DownloadQueueManager) -> None: now = datetime.now() old = now - timedelta(hours=48) - keep_recent = manager.create_job("ATV", "recent") - drop_old_done = manager.create_job("ATV", "old-done") - drop_old_failed = manager.create_job("ATV", "old-failed") - keep_running = manager.create_job("ATV", "running") + keep_recent = manager.create_job("EXAMPLE", "recent") + drop_old_done = manager.create_job("EXAMPLE", "old-done") + drop_old_failed = manager.create_job("EXAMPLE", "old-failed") + keep_running = manager.create_job("EXAMPLE", "running") keep_recent.status = JobStatus.COMPLETED keep_recent.completed_time = now diff --git a/tests/remote/unit/test_errors.py b/tests/remote/unit/test_errors.py index 96e2f127..76a7b2dc 100644 --- a/tests/remote/unit/test_errors.py +++ b/tests/remote/unit/test_errors.py @@ -118,9 +118,9 @@ def test_build_error_response_debug_mode_includes_traceback() -> None: ], ) def test_categorize_exception(exc: Exception, expected_code: APIErrorCode) -> None: - api_err = categorize_exception(exc, context={"service": "ATV"}) + api_err = categorize_exception(exc, context={"service": "EXAMPLE"}) assert api_err.error_code == expected_code - assert api_err.details.get("service") == "ATV" + assert api_err.details.get("service") == "EXAMPLE" def test_categorize_preserves_context() -> None: diff --git a/tests/remote/unit/test_remote_client.py b/tests/remote/unit/test_remote_client.py index 9ee379d9..62c2720d 100644 --- a/tests/remote/unit/test_remote_client.py +++ b/tests/remote/unit/test_remote_client.py @@ -55,9 +55,9 @@ def test_post_sends_json_body(client: RemoteClient) -> None: responses.add_callback( responses.POST, "http://srv:8786/api/session/create", callback=cb, content_type="application/json" ) - result = client.post("/api/session/create", {"service": "ATV"}) + result = client.post("/api/session/create", {"service": "EXAMPLE"}) assert result == {"session_id": "abc"} - assert captured["body"] == {"service": "ATV"} + assert captured["body"] == {"service": "EXAMPLE"} @responses.activate diff --git a/tests/remote/unit/test_remote_command_unknown_tag.py b/tests/remote/unit/test_remote_command_unknown_tag.py index 23ce558a..277543fa 100644 --- a/tests/remote/unit/test_remote_command_unknown_tag.py +++ b/tests/remote/unit/test_remote_command_unknown_tag.py @@ -10,8 +10,14 @@ import pytest from unshackle.core.services import Services SERVED = [ - {"tag": "AMZN", "url": "https://example.com", "help": "Amazon.", "cli_params": [], "aliases": []}, - {"tag": "HMAX", "url": "https://example.com", "help": "Max.", "cli_params": [], "aliases": ["MAX", "hbomax"]}, + {"tag": "EXAMPLE", "url": "https://example.com", "help": "Example service.", "cli_params": [], "aliases": []}, + { + "tag": "DEMO", + "url": "https://example.com", + "help": "Demo service.", + "cli_params": [], + "aliases": ["ALT", "alt-demo"], + }, ] @@ -21,31 +27,31 @@ def _make(name: str) -> click.Command: def test_unknown_name_raises_with_typed_name_and_available_list() -> None: with patch.object(Services, "fetch_remote_services", return_value=SERVED): - with pytest.raises(click.ClickException, match=r"does not offer a service named 'BBC'.*AMZN, HMAX"): - _make("BBC") + with pytest.raises(click.ClickException, match=r"does not offer a service named 'NOPE'.*DEMO, EXAMPLE"): + _make("NOPE") def test_served_tag_builds_full_command() -> None: with patch.object(Services, "fetch_remote_services", return_value=SERVED): - cmd = _make("AMZN") - assert cmd.help == "Amazon." + cmd = _make("EXAMPLE") + assert cmd.help == "Example service." def test_server_alias_resolves_to_server_tag() -> None: with patch.object(Services, "fetch_remote_services", return_value=SERVED): - cmd = _make("max") - assert cmd.name == "HMAX" - assert cmd.help == "Max." + cmd = _make("alt") + assert cmd.name == "DEMO" + assert cmd.help == "Demo service." def test_empty_service_list_raises_no_services_message() -> None: with patch.object(Services, "fetch_remote_services", return_value=[]): with pytest.raises(click.ClickException, match=r"offers no services to your API key"): - _make("AMZN") + _make("EXAMPLE") def test_fetch_failure_keeps_stub_instead_of_raising() -> None: with patch.object(Services, "fetch_remote_services", return_value=None): - cmd = _make("AMZN") - assert cmd.name == "AMZN" + cmd = _make("EXAMPLE") + assert cmd.name == "EXAMPLE" assert cmd.help is None diff --git a/tests/remote/unit/test_remote_resolve.py b/tests/remote/unit/test_remote_resolve.py index 7ae0718e..fec626ad 100644 --- a/tests/remote/unit/test_remote_resolve.py +++ b/tests/remote/unit/test_remote_resolve.py @@ -28,7 +28,7 @@ def single_remote_service(monkeypatch: pytest.MonkeyPatch) -> None: "primary": { "url": "https://primary:8080", "api_key": "key-abc", - "services": {"ATV": True, "NF": True}, + "services": {"EXAMPLE": True, "DEMO": True}, "server_cdm": True, } }, @@ -97,7 +97,7 @@ def test_resolve_server_single_picks_only_entry(single_remote_service) -> None: assert url == "https://primary:8080" assert key == "key-abc" assert services["_server_cdm"] is True - assert services.get("ATV") is True + assert services.get("EXAMPLE") is True def test_resolve_server_explicit_name(single_remote_service) -> None: diff --git a/tests/remote/unit/test_remote_service_helpers.py b/tests/remote/unit/test_remote_service_helpers.py index 499077a2..d866e7fd 100644 --- a/tests/remote/unit/test_remote_service_helpers.py +++ b/tests/remote/unit/test_remote_service_helpers.py @@ -182,7 +182,7 @@ def test_match_track_no_candidates_returns_none() -> None: def test_build_title_movie() -> None: info = {"type": "movie", "id": "movie-0001", "name": "Foo", "year": 2024, "language": "en"} - title = build_title(info, "ATV", "fallback") + title = build_title(info, "EXAMPLE", "fallback") assert isinstance(title, Movie) assert title.id == "movie-0001" assert title.name == "Foo" @@ -199,7 +199,7 @@ def test_build_title_episode() -> None: "year": 2024, "language": "en", } - title = build_title(info, "ATV", "fallback") + title = build_title(info, "EXAMPLE", "fallback") assert isinstance(title, Episode) assert title.season == 1 assert title.number == 2 @@ -207,7 +207,7 @@ def test_build_title_episode() -> None: def test_build_title_falls_back_to_id_when_missing() -> None: - title = build_title({"type": "movie", "name": "x"}, "ATV", "fallback-id") + title = build_title({"type": "movie", "name": "x"}, "EXAMPLE", "fallback-id") assert title.id == "fallback-id" diff --git a/tests/remote/unit/test_session_store.py b/tests/remote/unit/test_session_store.py index 0ebff67c..6252368b 100644 --- a/tests/remote/unit/test_session_store.py +++ b/tests/remote/unit/test_session_store.py @@ -25,15 +25,15 @@ def store() -> SessionStore: async def test_create_returns_entry_with_uuid(store: SessionStore) -> None: - entry = await store.create("ATV", _FakeService()) + entry = await store.create("EXAMPLE", _FakeService()) assert isinstance(entry, SessionEntry) - assert entry.service_tag == "ATV" + assert entry.service_tag == "EXAMPLE" assert entry.session_id and len(entry.session_id) >= 32 assert store.session_count == 1 async def test_create_with_explicit_session_id(store: SessionStore) -> None: - entry = await store.create("NF", _FakeService(), session_id="fixed-id") + entry = await store.create("DEMO", _FakeService(), session_id="fixed-id") assert entry.session_id == "fixed-id" @@ -42,7 +42,7 @@ async def test_get_returns_none_for_missing(store: SessionStore) -> None: async def test_get_touches_last_accessed(store: SessionStore) -> None: - entry = await store.create("DSNP", _FakeService()) + entry = await store.create("DEMO", _FakeService()) before = entry.last_accessed await asyncio.sleep(0.01) fetched = await store.get(entry.session_id) @@ -68,7 +68,7 @@ async def test_delete_returns_false_when_missing(store: SessionStore) -> None: async def test_cleanup_expired_drops_old_authenticated(store: SessionStore, monkeypatch: pytest.MonkeyPatch) -> None: from datetime import datetime, timedelta, timezone - entry = await store.create("ATV", _FakeService()) + entry = await store.create("EXAMPLE", _FakeService()) entry.last_accessed = datetime.now(timezone.utc) - timedelta(seconds=store.ttl + 100) removed = await store.cleanup_expired() assert removed == 1 @@ -77,7 +77,7 @@ async def test_cleanup_expired_drops_old_authenticated(store: SessionStore, monk async def test_cleanup_expired_keeps_pending_input_under_grace(store: SessionStore) -> None: """Sessions awaiting user input get a longer grace period (10 min) than authenticated TTL.""" - entry = await store.create("ATV", _FakeService()) + entry = await store.create("EXAMPLE", _FakeService()) entry.input_bridge = InputBridge() entry.auth_status = AuthStatus.PENDING_INPUT removed = await store.cleanup_expired() @@ -91,7 +91,7 @@ async def test_cleanup_expired_drops_pending_input_past_grace(store: SessionStor from unshackle.core.api.input_bridge import AUTH_INPUT_TIMEOUT - entry = await store.create("ATV", _FakeService()) + entry = await store.create("EXAMPLE", _FakeService()) entry.input_bridge = InputBridge() entry.auth_status = AuthStatus.PENDING_INPUT entry.last_accessed = datetime.now(timezone.utc) - timedelta(seconds=AUTH_INPUT_TIMEOUT + 1) @@ -101,8 +101,8 @@ async def test_cleanup_expired_drops_pending_input_past_grace(store: SessionStor async def test_cancel_all_bridges(store: SessionStore) -> None: - a = await store.create("ATV", _FakeService()) - b = await store.create("NF", _FakeService()) + a = await store.create("EXAMPLE", _FakeService()) + b = await store.create("DEMO", _FakeService()) a.input_bridge = InputBridge() b.input_bridge = InputBridge() diff --git a/tests/tracks/test_hybrid_selection.py b/tests/tracks/test_hybrid_selection.py index 61ad1d75..515fbafd 100644 --- a/tests/tracks/test_hybrid_selection.py +++ b/tests/tracks/test_hybrid_selection.py @@ -14,7 +14,7 @@ Covers the selection primitives that back `-r ...,DV,HYBRID` downloads: The remaining ``dl`` glue (the Cartesian deliverable product and the mux loop) is orchestration inside the Click command; these tests lock down the pure -units it relies on plus the documented end-state of a realistic ATV-style ladder. +units it relies on plus the documented end-state of a realistic streaming ladder. """ from __future__ import annotations @@ -39,7 +39,7 @@ def make_video(track_id: str, *, range_: Video.Range, height: int, bitrate: int, @pytest.fixture def ladder() -> list[Video]: - """Mirrors the reported ATV ladder: HDR10+, DV and SDR at multiple resolutions.""" + """Mirrors the ladder from the reported fault: HDR10+, DV and SDR at multiple resolutions.""" H = Video.Codec.HEVC A = Video.Codec.AVC return [