/
/
/
1"""Tests for the URL used to reach the in-process Sendspin server."""
2
3from unittest.mock import MagicMock
4
5import pytest
6
7from music_assistant.controllers.webserver.controller import WebserverController
8
9
10@pytest.fixture
11def webserver(mock_mass: MagicMock) -> WebserverController:
12 """Create a WebserverController backed by a mocked Music Assistant instance."""
13 return WebserverController(mock_mass)
14
15
16@pytest.mark.parametrize(
17 ("bind_ip", "publish_ip", "expected"),
18 [
19 # pinned to a single interface: loopback would not reach the server
20 ("192.168.1.5", "192.168.1.5", "ws://192.168.1.5:8927/sendspin"),
21 ("fd00::5", "fd00::5", "ws://[fd00::5]:8927/sendspin"),
22 # wildcard bind: loopback reaches the server, whatever is advertised.
23 # a publish_ip that only exists outside a container/NAT must never be dialed
24 ("0.0.0.0", "203.0.113.10", "ws://127.0.0.1:8927/sendspin"),
25 ("::", "192.168.1.5", "ws://127.0.0.1:8927/sendspin"),
26 ("0.0.0.0", "fd00::1", "ws://[::1]:8927/sendspin"),
27 ("::", "fd00::1", "ws://[::1]:8927/sendspin"),
28 ("", "192.168.1.5", "ws://127.0.0.1:8927/sendspin"),
29 ],
30)
31def test_url_follows_the_bind_address(
32 webserver: WebserverController,
33 mock_mass: MagicMock,
34 bind_ip: str,
35 publish_ip: str,
36 expected: str,
37) -> None:
38 """Verify the URL resolves to an address that exists on this host."""
39 mock_mass.streams.bind_ip = bind_ip
40 mock_mass.streams.publish_ip = publish_ip
41
42 assert webserver.internal_sendspin_url == expected
43