From 47e007ba213a2c5cc168750338dc7f2cad71d302 Mon Sep 17 00:00:00 2001 From: BTerell82 Date: Mon, 25 Aug 2025 11:33:33 -0500 Subject: [PATCH] Fix: use DISCOVER host for watchlist (metadata host now 404s) - Changed MyPlexAccount.watchlist() to use self.DISCOVER instead of self.METADATA - Plex moved watchlist API from metadata.provider.plex.tv to discover.provider.plex.tv - Added test to verify the endpoint change - Addresses issues reported in Overseerr#4230, Kometa#2745 --- plexapi/myplex.py | 2 +- test_watchlist_endpoint.py | 46 ++++++++++++++++++++++++++++++++++++++ tests/test_myplex.py | 16 +++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 test_watchlist_endpoint.py diff --git a/plexapi/myplex.py b/plexapi/myplex.py index 411d56183..8edb040c9 100644 --- a/plexapi/myplex.py +++ b/plexapi/myplex.py @@ -949,7 +949,7 @@ def watchlist(self, filter=None, sort=None, libtype=None, maxresults=None, **kwa params.update(kwargs) - key = f'{self.METADATA}/library/sections/watchlist/{filter}{utils.joinArgs(params)}' + key = f'{self.DISCOVER}/library/sections/watchlist/{filter}{utils.joinArgs(params)}' return self._toOnlineMetadata(self.fetchItems(key, maxresults=maxresults), **kwargs) def onWatchlist(self, item): diff --git a/test_watchlist_endpoint.py b/test_watchlist_endpoint.py new file mode 100644 index 000000000..d94085867 --- /dev/null +++ b/test_watchlist_endpoint.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +""" +Standalone test to verify watchlist uses DISCOVER endpoint. +""" + +import unittest +from unittest.mock import MagicMock, patch +from plexapi.myplex import MyPlexAccount + + +class TestWatchlistEndpoint(unittest.TestCase): + def test_watchlist_uses_discover_endpoint(self): + """Test that watchlist method uses DISCOVER endpoint instead of METADATA.""" + # Create a MyPlexAccount instance + account = MyPlexAccount.__new__(MyPlexAccount) + account._token = "test_token" + account._session = MagicMock() + account._timeout = 30 + + # Mock the fetchItems and _toOnlineMetadata methods + with patch.object(MyPlexAccount, 'fetchItems', return_value=[]) as mock_fetchItems, \ + patch.object(MyPlexAccount, '_toOnlineMetadata', return_value=[]) as mock_toOnlineMetadata: + + # Call the watchlist method + result = MyPlexAccount.watchlist(account, filter='all') + + # Verify that fetchItems was called + self.assertTrue(mock_fetchItems.called) + + # Get the URL that was passed to fetchItems + url_arg = mock_fetchItems.call_args[0][0] + + # Verify that the URL starts with DISCOVER endpoint + self.assertTrue(url_arg.startswith(MyPlexAccount.DISCOVER), + f"Expected URL to start with {MyPlexAccount.DISCOVER}, got {url_arg}") + + # Verify that METADATA endpoint is not used + self.assertNotIn(MyPlexAccount.METADATA, url_arg, + f"URL should not contain METADATA endpoint: {url_arg}") + + # Verify the exact expected URL pattern + self.assertTrue('/library/sections/watchlist/all' in url_arg, + f"URL should contain watchlist path: {url_arg}") + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_myplex.py b/tests/test_myplex.py index e17358bb5..79b24eb80 100644 --- a/tests/test_myplex.py +++ b/tests/test_myplex.py @@ -314,6 +314,22 @@ def test_myplex_watchlist(account, movie, show, artist): account.addToWatchlist(artist) +def test_myplex_watchlist_uses_discover_endpoint(account, mocker): + """Test that watchlist method uses DISCOVER endpoint instead of METADATA.""" + # Mock the fetchItems method to capture the URL being called + mock_fetchItems = mocker.patch.object(account, 'fetchItems', return_value=[]) + mock_toOnlineMetadata = mocker.patch.object(account, '_toOnlineMetadata', return_value=[]) + + # Call watchlist method + account.watchlist() + + # Verify that fetchItems was called with a URL that starts with DISCOVER endpoint + assert mock_fetchItems.called + url_arg = mock_fetchItems.call_args[0][0] + assert url_arg.startswith(account.DISCOVER), f"Expected URL to start with {account.DISCOVER}, got {url_arg}" + assert account.METADATA not in url_arg, f"URL should not contain METADATA endpoint: {url_arg}" + + def test_myplex_searchDiscover(account, movie, show): guids = lambda x: [r.guid for r in x]