============================= test session starts =============================
platform win32 -- Python 3.12.9, pytest-8.3.5, pluggy-1.5.0
rootdir: C:\Users\micha\Drive\Projects\Python\iSubRip
configfile: pyproject.toml
plugins: anyio-4.9.0, pyfakefs-5.8.0, asyncio-0.26.0, httpx-0.35.0, mock-3.14.0
asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collected 45 items

tests\unit\scrapers\test_itunes_scraper.py ..F..FF...........F.......... [ 64%]
................                                                         [100%]

================================== FAILURES ===================================
________ TestItunesScraper.test_get_data_success_double_slash_redirect ________

self = <MagicMock name='get_scraper_instance().match_url' id='1933008070288'>
args = ('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid',)
kwargs = {}
msg = "Expected 'match_url' to be called once. Called 2 times.\nCalls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),\n call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid')]."

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
>           raise AssertionError(msg)
E           AssertionError: Expected 'match_url' to be called once. Called 2 times.
E           Calls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),
E            call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid')].

C:\Users\micha\AppData\Roaming\uv\python\cpython-3.12.9-windows-x86_64-none\Lib\unittest\mock.py:960: AssertionError

During handling of the above exception, another exception occurred:

self = <tests.unit.scrapers.test_itunes_scraper.TestItunesScraper object at 0x000001C2102DBA10>
scraper = <isubrip.scrapers.itunes_scraper.ItunesScraper object at 0x000001C20EAD7440>
httpx_mock = <pytest_httpx._httpx_mock.HTTPXMock object at 0x000001C2104A1250>
mocker = <pytest_mock.plugin.MockerFixture object at 0x000001C210426600>

    @pytest.mark.asyncio
    async def test_get_data_success_double_slash_redirect(
        self,
        scraper: ItunesScraper,
        httpx_mock: HTTPXMock,
        mocker: MockerFixture,
    ):
        """Test get_data handles redirect URLs starting with //."""
        self.mock_appletv_scraper.reset_mock() # Reset mock for this test
        itunes_url = "https://itunes.apple.com/gb/movie/another-movie/id0987654321"
        redirect_find_url = "https://tv.apple.com/gb/movie/id0987654321"
        redirect_target_relative = "//tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid"
        redirect_target_absolute = "https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid"
        mock_appletv_response = ScrapedMediaResponse(
            media_data=[Movie(id="umc.cmc.anotherid", name="Another Movie", release_date=2022)],
            metadata_scraper="appletv",
            playlist_scraper="itunes",
            original_data={},
        )
    
        httpx_mock.add_response(
            url=redirect_find_url,
            method="GET",
            status_code=301,
            headers={"Location": redirect_target_relative},
        )
        # Configure the mock AppleTVScraper directly
        scraper._appletv_scraper.match_url.return_value = True
        scraper._appletv_scraper.get_data.return_value = mock_appletv_response
    
        result = await scraper.get_data(itunes_url)
    
        # Reset mock before assertion in this specific test
        # self.mock_appletv_scraper.reset_mock() # Resetting in fixture should be enough
>       scraper._appletv_scraper.match_url.assert_called_once_with(redirect_target_absolute) # Check absolute URL is used
E       AssertionError: Expected 'match_url' to be called once. Called 2 times.
E       Calls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),
E        call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid')].

c:\Users\micha\Drive\Projects\Python\iSubRip\tests\unit\scrapers\test_itunes_scraper.py:124: AssertionError
________ TestItunesScraper.test_get_data_redirect_invalid_appletv_url _________

self = <MagicMock name='get_scraper_instance().match_url' id='1933008070288'>
args = ('https://some.other.site/movie',), kwargs = {}
msg = "Expected 'match_url' to be called once. Called 3 times.\nCalls: [call('https://tv.apple.com/us/movie/mock-movie-title...call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid'),\n call('https://some.other.site/movie')]."

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
>           raise AssertionError(msg)
E           AssertionError: Expected 'match_url' to be called once. Called 3 times.
E           Calls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),
E            call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid'),
E            call('https://some.other.site/movie')].

C:\Users\micha\AppData\Roaming\uv\python\cpython-3.12.9-windows-x86_64-none\Lib\unittest\mock.py:960: AssertionError

During handling of the above exception, another exception occurred:

self = <tests.unit.scrapers.test_itunes_scraper.TestItunesScraper object at 0x000001C2103083E0>
scraper = <isubrip.scrapers.itunes_scraper.ItunesScraper object at 0x000001C20EAD7440>
httpx_mock = <pytest_httpx._httpx_mock.HTTPXMock object at 0x000001C21052CCB0>
mocker = <pytest_mock.plugin.MockerFixture object at 0x000001C2104A1F10>

    @pytest.mark.asyncio
    async def test_get_data_redirect_invalid_appletv_url(
        self,
        scraper: ItunesScraper,
        httpx_mock: HTTPXMock,
        mocker: MockerFixture,
    ):
        """Test get_data raises ScraperError if redirect URL is not a valid AppleTV URL."""
        self.mock_appletv_scraper.reset_mock() # Reset mock for this test
        itunes_url = "https://itunes.apple.com/us/movie/mock-movie/id1234567890"
        redirect_find_url = "https://tv.apple.com/us/movie/id1234567890"
        invalid_redirect_target_url = "https://some.other.site/movie"
    
        httpx_mock.add_response(
            url=redirect_find_url,
            method="GET",
            status_code=301,
            headers={"Location": invalid_redirect_target_url},
        )
        # Configure the mock AppleTVScraper directly
        scraper._appletv_scraper.match_url.return_value = False
        # scraper._appletv_scraper.get_data should not be called
    
        with pytest.raises(ScraperError, match="Redirect URL is not a valid AppleTV URL."):
            await scraper.get_data(itunes_url)
    
        # Reset mock before assertion in this specific test
        # self.mock_appletv_scraper.reset_mock() # Resetting in fixture should be enough
>       scraper._appletv_scraper.match_url.assert_called_once_with(invalid_redirect_target_url)
E       AssertionError: Expected 'match_url' to be called once. Called 3 times.
E       Calls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),
E        call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid'),
E        call('https://some.other.site/movie')].

c:\Users\micha\Drive\Projects\Python\iSubRip\tests\unit\scrapers\test_itunes_scraper.py:190: AssertionError
____________ TestItunesScraper.test_get_data_appletv_scraper_error ____________

self = <MagicMock name='get_scraper_instance().match_url' id='1933008070288'>
args = ('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123',)
kwargs = {}
msg = "Expected 'match_url' to be called once. Called 4 times.\nCalls: [call('https://tv.apple.com/us/movie/mock-movie-title...ll('https://some.other.site/movie'),\n call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123')]."

    def assert_called_once_with(self, /, *args, **kwargs):
        """assert that the mock was called exactly once and that that call was
        with the specified arguments."""
        if not self.call_count == 1:
            msg = ("Expected '%s' to be called once. Called %s times.%s"
                   % (self._mock_name or 'mock',
                      self.call_count,
                      self._calls_repr()))
>           raise AssertionError(msg)
E           AssertionError: Expected 'match_url' to be called once. Called 4 times.
E           Calls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),
E            call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid'),
E            call('https://some.other.site/movie'),
E            call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123')].

C:\Users\micha\AppData\Roaming\uv\python\cpython-3.12.9-windows-x86_64-none\Lib\unittest\mock.py:960: AssertionError

During handling of the above exception, another exception occurred:

self = <tests.unit.scrapers.test_itunes_scraper.TestItunesScraper object at 0x000001C2102DBEC0>
scraper = <isubrip.scrapers.itunes_scraper.ItunesScraper object at 0x000001C20EAD7440>
httpx_mock = <pytest_httpx._httpx_mock.HTTPXMock object at 0x000001C210425880>
mocker = <pytest_mock.plugin.MockerFixture object at 0x000001C2104A1EB0>

    @pytest.mark.asyncio
    async def test_get_data_appletv_scraper_error(
        self,
        scraper: ItunesScraper,
        httpx_mock: HTTPXMock,
        mocker: MockerFixture,
    ):
        """Test get_data propagates errors from AppleTVScraper.get_data."""
        self.mock_appletv_scraper.reset_mock() # Reset mock for this test
        itunes_url = "https://itunes.apple.com/us/movie/mock-movie/id1234567890"
        redirect_find_url = "https://tv.apple.com/us/movie/id1234567890"
        redirect_target_url = "https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123"
    
        httpx_mock.add_response(
            url=redirect_find_url,
            method="GET",
            status_code=301,
            headers={"Location": redirect_target_url},
        )
        # Configure the mock AppleTVScraper directly
        scraper._appletv_scraper.match_url.return_value = True
        scraper._appletv_scraper.get_data.side_effect = ScraperError("Error from AppleTV")
    
        with pytest.raises(ScraperError, match="Error from AppleTV"):
            await scraper.get_data(itunes_url)
    
        # Reset mock before assertion in this specific test
        # self.mock_appletv_scraper.reset_mock() # Resetting in fixture should be enough
>       scraper._appletv_scraper.match_url.assert_called_once_with(redirect_target_url)
E       AssertionError: Expected 'match_url' to be called once. Called 4 times.
E       Calls: [call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123'),
E        call('https://tv.apple.com/gb/movie/another-movie-title/umc.cmc.anotherid'),
E        call('https://some.other.site/movie'),
E        call('https://tv.apple.com/us/movie/mock-movie-title/umc.cmc.mockmovieid123')].

c:\Users\micha\Drive\Projects\Python\iSubRip\tests\unit\scrapers\test_itunes_scraper.py:222: AssertionError
____________ TestItunesScraper.test_load_playlist_invalid_content _____________

self = <tests.unit.scrapers.test_itunes_scraper.TestItunesScraper object at 0x000001C210309A60>
scraper = <isubrip.scrapers.itunes_scraper.ItunesScraper object at 0x000001C20EAD7440>
httpx_mock = <pytest_httpx._httpx_mock.HTTPXMock object at 0x000001C21050C500>

    @pytest.mark.asyncio
    async def test_load_playlist_invalid_content(
        self,
        scraper: ItunesScraper,
        httpx_mock: HTTPXMock,
    ):
        """Test load_playlist raises ValueError on invalid M3U8 content."""
        main_playlist_url = "http://mock.itunes.com/main_invalid.m3u8"
        # Use content missing the required #EXTM3U header
        invalid_content = "EXT-X-VERSION:3\n#EXTINF:10,\nsegment.ts"
        httpx_mock.add_response(url=main_playlist_url, text=invalid_content)
    
        # m3u8.loads raises ValueError for content missing the #EXTM3U header
        # Ensure the match string is exact
>       with pytest.raises(ValueError, match=r"Playlist does not start with #EXTM3U"):
E       Failed: DID NOT RAISE <class 'ValueError'>

c:\Users\micha\Drive\Projects\Python\iSubRip\tests\unit\scrapers\test_itunes_scraper.py:306: Failed
=========================== short test summary info ===========================
FAILED tests/unit/scrapers/test_itunes_scraper.py::TestItunesScraper::test_get_data_success_double_slash_redirect
FAILED tests/unit/scrapers/test_itunes_scraper.py::TestItunesScraper::test_get_data_redirect_invalid_appletv_url
FAILED tests/unit/scrapers/test_itunes_scraper.py::TestItunesScraper::test_get_data_appletv_scraper_error
FAILED tests/unit/scrapers/test_itunes_scraper.py::TestItunesScraper::test_load_playlist_invalid_content
======================== 4 failed, 41 passed in 1.13s =========================
