From 1b6019ad182de0871e6b7a6b7bdd16d96f28e621 Mon Sep 17 00:00:00 2001 From: Teagan Glenn Date: Fri, 29 Aug 2025 18:25:51 -0600 Subject: [PATCH 1/4] test: add async fetch tests and rename workflow --- .github/workflows/{ci.yaml => test.yaml} | 2 +- tests/test_loader_unit.py | 85 +++++++++++++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) rename .github/workflows/{ci.yaml => test.yaml} (98%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/test.yaml similarity index 98% rename from .github/workflows/ci.yaml rename to .github/workflows/test.yaml index bf6b26b..3e37af8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/test.yaml @@ -1,4 +1,4 @@ -name: Test and Lint +name: test permissions: contents: write diff --git a/tests/test_loader_unit.py b/tests/test_loader_unit.py index a40c376..de7ea72 100644 --- a/tests/test_loader_unit.py +++ b/tests/test_loader_unit.py @@ -1,7 +1,15 @@ import types from pathlib import Path -from mcp_plex.loader import _extract_external_ids, _load_from_sample +from mcp_plex.loader import ( + _extract_external_ids, + _load_from_sample, + _build_plex_item, + _fetch_imdb, + _fetch_tmdb_movie, + _fetch_tmdb_show, + _fetch_tmdb_episode, +) def test_extract_external_ids(): @@ -17,3 +25,78 @@ def test_load_from_sample_returns_items(): items = _load_from_sample(sample_dir) assert len(items) == 2 assert {i.plex.type for i in items} == {"movie", "episode"} + + +def test_build_plex_item_handles_full_metadata(): + guid_objs = [types.SimpleNamespace(id="imdb://tt123"), types.SimpleNamespace(id="tmdb://456")] + raw = types.SimpleNamespace( + ratingKey="1", + guid="guid", + type="movie", + title="Title", + summary="Summary", + year=2024, + guids=guid_objs, + thumb="thumb.jpg", + art="art.jpg", + tagline="Tagline", + contentRating="PG", + directors=[types.SimpleNamespace(id=1, tag="Director", thumb="d.jpg")], + writers=[types.SimpleNamespace(id=2, tag="Writer", thumb="w.jpg")], + actors=[types.SimpleNamespace(id=3, tag="Actor", thumb="a.jpg", role="Role")], + ) + + item = _build_plex_item(raw) + assert item.rating_key == "1" + assert item.directors[0].tag == "Director" + assert item.actors[0].role == "Role" + + +import asyncio +import httpx + + +def test_fetch_functions_success_and_failure(): + async def imdb_mock(request): + if "good" in str(request.url): + return httpx.Response(200, json={"id": "tt1", "type": "movie", "primaryTitle": "T"}) + return httpx.Response(404) + + async def tmdb_movie_mock(request): + if "good" in str(request.url): + return httpx.Response(200, json={"id": 1, "title": "M"}) + return httpx.Response(404) + + async def tmdb_show_mock(request): + if "good" in str(request.url): + return httpx.Response(200, json={"id": 1, "name": "S"}) + return httpx.Response(404) + + async def tmdb_episode_mock(request): + if "good" in str(request.url): + return httpx.Response(200, json={"id": 1, "name": "E"}) + return httpx.Response(404) + + async def main(): + imdb_transport = httpx.MockTransport(imdb_mock) + movie_transport = httpx.MockTransport(tmdb_movie_mock) + show_transport = httpx.MockTransport(tmdb_show_mock) + episode_transport = httpx.MockTransport(tmdb_episode_mock) + + async with httpx.AsyncClient(transport=imdb_transport) as client: + assert (await _fetch_imdb(client, "good")) is not None + assert (await _fetch_imdb(client, "bad")) is None + + async with httpx.AsyncClient(transport=movie_transport) as client: + assert (await _fetch_tmdb_movie(client, "good", "k")) is not None + assert (await _fetch_tmdb_movie(client, "bad", "k")) is None + + async with httpx.AsyncClient(transport=show_transport) as client: + assert (await _fetch_tmdb_show(client, "good", "k")) is not None + assert (await _fetch_tmdb_show(client, "bad", "k")) is None + + async with httpx.AsyncClient(transport=episode_transport) as client: + assert (await _fetch_tmdb_episode(client, "good", "k")) is not None + assert (await _fetch_tmdb_episode(client, "bad", "k")) is None + + asyncio.run(main()) From 3e8464124376d2b23ab62836d3d73ee52d3e4291 Mon Sep 17 00:00:00 2001 From: Teagan Glenn Date: Fri, 29 Aug 2025 18:27:46 -0600 Subject: [PATCH 2/4] Update permissions on workflow --- .github/workflows/test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3e37af8..7a3a8b8 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,7 +1,8 @@ -name: test +name: Lint and Test permissions: contents: write + checks: write pull-requests: write on: From 92626564cddfaabd3867ccae0a00c02382798d80 Mon Sep 17 00:00:00 2001 From: Teagan Glenn Date: Fri, 29 Aug 2025 18:29:57 -0600 Subject: [PATCH 3/4] Move imports --- tests/test_loader_unit.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/test_loader_unit.py b/tests/test_loader_unit.py index de7ea72..6ba2114 100644 --- a/tests/test_loader_unit.py +++ b/tests/test_loader_unit.py @@ -1,4 +1,7 @@ import types +import asyncio +import httpx + from pathlib import Path from mcp_plex.loader import ( @@ -52,10 +55,6 @@ def test_build_plex_item_handles_full_metadata(): assert item.actors[0].role == "Role" -import asyncio -import httpx - - def test_fetch_functions_success_and_failure(): async def imdb_mock(request): if "good" in str(request.url): From 542a12714801feabfc55f19e7ec7fca9a2593a68 Mon Sep 17 00:00:00 2001 From: Teagan42 <2989925+Teagan42@users.noreply.github.com> Date: Sat, 30 Aug 2025 00:30:29 +0000 Subject: [PATCH 4/4] docs: update coverage badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a5c5c1..556277e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -Coverage
Coverage Report
FileStmtsMissCoverMissing
mcp_plex
   loader.py1727358%40–44, 50–56, 62–68, 76–80, 100–118, 139–190, 295–302, 337–346, 450–463
TOTAL2747373% 
+Coverage
Coverage Report
FileStmtsMissCoverMissing
mcp_plex
   loader.py1724872%139–190, 295–302, 337–346, 450–463
TOTAL2744882% 
# mcp-plex