11import asyncio
22import logging
3+ from typing import cast
4+ from unittest .mock import Mock , create_autospec
35
46import pytest
7+ from plexapi .server import PlexServer
8+ from plexapi .video import Episode , Movie , Season , Show
59
610from mcp_plex .common .types import AggregatedItem , PlexItem
711from mcp_plex .loader .pipeline .channels import (
@@ -28,7 +32,7 @@ def test_ingestion_stage_logger_name() -> None:
2832 async def scenario () -> str :
2933 queue : asyncio .Queue = asyncio .Queue ()
3034 stage = IngestionStage (
31- plex_server = object (),
35+ plex_server = cast ( PlexServer , object () ),
3236 sample_items = None ,
3337 movie_batch_size = 50 ,
3438 episode_batch_size = 25 ,
@@ -159,45 +163,49 @@ async def scenario() -> tuple[list[SampleBatch], object | None, object | None, i
159163def test_ingestion_stage_ingest_plex_batches_movies_and_episodes (caplog ) -> None :
160164 caplog .set_level (logging .INFO )
161165
162- class FakeMovie :
163- def __init__ (self , title : str ) -> None :
164- self .title = title
166+ sentinel = object ()
165167
166- class FakeEpisode :
167- def __init__ (self , title : str ) -> None :
168- self .title = title
168+ async def scenario () -> tuple [list [object ], int , int , Mock ]:
169+ queue : asyncio .Queue = asyncio .Queue ()
169170
170- class FakeShow :
171- def __init__ (self , title : str , episode_titles : list [str ]) -> None :
172- self .title = title
173- self ._episodes = [FakeEpisode (ep_title ) for ep_title in episode_titles ]
171+ movie_section = Mock ()
172+ movies = [
173+ create_autospec (Movie , instance = True , title = "Movie 1" ),
174+ create_autospec (Movie , instance = True , title = "Movie 2" ),
175+ create_autospec (Movie , instance = True , title = "Movie 3" ),
176+ ]
177+ movie_section .all .return_value = movies
174178
175- def episodes ( self ) -> list [FakeEpisode ]:
176- return list ( self . _episodes )
179+ def _episodes ( titles : list [ str ] ) -> list [Episode ]:
180+ return [ create_autospec ( Episode , instance = True , title = title ) for title in titles ]
177181
178- class FakePlex :
179- def __init__ (self ) -> None :
180- self ._movies = [
181- FakeMovie ("Movie 1" ),
182- FakeMovie ("Movie 2" ),
183- FakeMovie ("Movie 3" ),
184- ]
185- self ._shows = [
186- FakeShow ("Show A" , ["S01E01" , "S01E02" , "S01E03" ]),
187- FakeShow ("Show B" , ["S01E01" , "S01E02" ]),
188- ]
182+ show_a_season_1 = create_autospec (Season , instance = True )
183+ show_a_season_1 .episodes .return_value = _episodes (["S01E01" , "S01E02" ])
184+ show_a_season_2 = create_autospec (Season , instance = True )
185+ show_a_season_2 .episodes .return_value = _episodes (["S01E03" ])
189186
190- def movies ( self ) -> list [ FakeMovie ]:
191- return list ( self . _movies )
187+ show_a = create_autospec ( Show , instance = True , title = "Show A" )
188+ show_a . seasons . return_value = [ show_a_season_1 , show_a_season_2 ]
192189
193- def shows ( self ) -> list [ FakeShow ]:
194- return list ( self . _shows )
190+ show_b_season_1 = create_autospec ( Season , instance = True )
191+ show_b_season_1 . episodes . return_value = _episodes ([ "S01E01" , "S01E02" ] )
195192
196- sentinel = object ()
193+ show_b = create_autospec (Show , instance = True , title = "Show B" )
194+ show_b .seasons .return_value = [show_b_season_1 ]
195+
196+ shows = [show_a , show_b ]
197+ show_section = Mock ()
198+ show_section .all .return_value = shows
199+
200+ library = Mock ()
201+ library .section .side_effect = lambda name : {
202+ "Movies" : movie_section ,
203+ "TV Shows" : show_section ,
204+ }[name ]
205+
206+ plex = create_autospec (PlexServer , instance = True )
207+ plex .library = library
197208
198- async def scenario () -> tuple [list [object ], int , int ]:
199- queue : asyncio .Queue = asyncio .Queue ()
200- plex = FakePlex ()
201209 stage = IngestionStage (
202210 plex_server = plex ,
203211 sample_items = None ,
@@ -220,10 +228,14 @@ async def scenario() -> tuple[list[object], int, int]:
220228 while not queue .empty ():
221229 batches .append (await queue .get ())
222230
223- return batches , stage .items_ingested , stage .batches_ingested
231+ return batches , stage .items_ingested , stage .batches_ingested , library
224232
225- batches , items_ingested , batches_ingested = asyncio .run (scenario ())
233+ batches , items_ingested , batches_ingested , library = asyncio .run (scenario ())
226234
235+ assert library .section .call_args_list == [
236+ (("Movies" ,),),
237+ (("TV Shows" ,),),
238+ ]
227239 assert items_ingested == 8
228240 assert batches_ingested == 5
229241
0 commit comments