/
/
/
1"""Tests that HTTP error responses do not leak exception details to the client."""
2
3from __future__ import annotations
4
5from typing import Any
6from unittest.mock import AsyncMock, Mock
7
8import pytest
9
10from music_assistant.providers.plex_connect.playback import PlaybackMixin
11from music_assistant.providers.plex_connect.queue_commands import QueueCommandsMixin
12
13
14class _PlaybackHandler(PlaybackMixin):
15 """PlaybackMixin with the host-class attributes mocked."""
16
17 def __init__(self) -> None:
18 self.provider = Mock()
19 self._ma_player_id = "player1"
20 self._updating_from_plex = False
21 self.play_queue_id = None
22 self.play_queue_item_ids: dict[int, int] = {}
23 self._broadcast_timeline = AsyncMock() # type: ignore[method-assign]
24
25
26class _QueueHandler(QueueCommandsMixin):
27 """QueueCommandsMixin with the host-class attributes mocked."""
28
29 def __init__(self) -> None:
30 self.provider = Mock()
31 self._ma_player_id = "player1"
32 self._updating_from_plex = False
33 self.play_queue_id = None
34 self.play_queue_version = 1
35 self.play_queue_item_ids: dict[int, int] = {}
36 self._broadcast_timeline = AsyncMock() # type: ignore[method-assign]
37
38
39def _request_with_query(query: dict[str, str]) -> Any:
40 request = Mock()
41 request.query = query
42 return request
43
44
45@pytest.mark.asyncio
46async def test_skip_to_error_does_not_leak_exception() -> None:
47 """An internal error in skipTo must return a generic 500 body."""
48 handler = _PlaybackHandler()
49 provider_mock = Mock()
50 provider_mock.mass.player_queues.items = Mock(
51 side_effect=RuntimeError("secret internal details")
52 )
53 handler.provider = provider_mock
54
55 response = await handler.handle_skip_to(_request_with_query({"key": "/library/item/1"}))
56
57 assert response.status == 500
58 assert "secret internal details" not in (response.text or "")
59
60
61@pytest.mark.asyncio
62async def test_create_play_queue_error_does_not_leak_exception() -> None:
63 """An internal error in createPlayQueue must return a generic 500 body."""
64 handler = _QueueHandler()
65 provider_mock = Mock()
66 provider_mock._plex_server.fetchItem = Mock(side_effect=RuntimeError("secret internal details"))
67 handler.provider = provider_mock
68
69 response = await handler.handle_create_play_queue(
70 _request_with_query({"uri": "server://xyz/library/item/1"})
71 )
72
73 assert response.status == 500
74 assert "secret internal details" not in (response.text or "")
75