106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
from __future__ import annotations
|
|
|
|
import queue
|
|
|
|
import pytest
|
|
|
|
from somafm_tui import mpris
|
|
|
|
|
|
def test_build_metadata() -> None:
|
|
metadata = mpris.build_metadata(
|
|
station="Groove Salad",
|
|
title="Rauschebart",
|
|
artist="Jens Buchert",
|
|
album="Gravity",
|
|
art_url="https://example.com/art.jpg",
|
|
stream_url="https://ice2.somafm.com/groovesalad-256-mp3",
|
|
track_key="groovesalad|Jens Buchert|Rauschebart|Gravity",
|
|
)
|
|
assert metadata["mpris:trackid"].value.startswith("/org/somafm/track/")
|
|
assert metadata["xesam:title"].value == "Rauschebart"
|
|
assert metadata["xesam:artist"].value == ["Jens Buchert"]
|
|
assert metadata["xesam:album"].value == "Gravity"
|
|
assert metadata["mpris:artUrl"].value == "https://example.com/art.jpg"
|
|
assert metadata["xesam:url"].value.startswith("https://ice2.")
|
|
assert metadata["xesam:comment"].value == ["SomaFM · Groove Salad"]
|
|
|
|
minimal = mpris.build_metadata(station="X", title="", artist="")
|
|
assert minimal["xesam:artist"].value == ["SomaFM"]
|
|
assert "xesam:album" not in minimal
|
|
assert "mpris:artUrl" not in minimal
|
|
|
|
|
|
def test_disabled_service_is_inert() -> None:
|
|
service = mpris.MprisService(queue.Queue(), enabled=False)
|
|
assert service.status_label == "off"
|
|
service.start()
|
|
service.set_track(station="X", title="T", artist="A")
|
|
service.set_status("Playing")
|
|
service.set_volume(0.5)
|
|
service.stop()
|
|
assert service.available is False
|
|
|
|
|
|
@pytest.mark.skipif(not mpris.DBUS_AVAILABLE, reason="dbus-next not installed")
|
|
def test_interfaces_introspect_and_queue_actions() -> None:
|
|
actions: queue.Queue[str] = queue.Queue()
|
|
service = mpris.MprisService(actions, enabled=False)
|
|
|
|
player = mpris._PlayerInterface(service)
|
|
interface = player.introspect()
|
|
properties = {prop.name: prop for prop in interface.properties}
|
|
assert properties["Metadata"].signature == "a{sv}"
|
|
assert properties["PlaybackStatus"].signature == "s"
|
|
assert properties["Volume"].signature == "d"
|
|
assert properties["Volume"].access == mpris.PropertyAccess.READWRITE
|
|
assert properties["Position"].signature == "x"
|
|
|
|
methods = {method.name: method.in_signature for method in interface.methods}
|
|
assert methods["Play"] == ""
|
|
assert methods["Seek"] == "x"
|
|
assert methods["SetPosition"] == "ox"
|
|
assert methods["OpenUri"] == "s"
|
|
|
|
player.Volume = 0.33
|
|
assert actions.get_nowait() == "volume:33"
|
|
player.Play()
|
|
player.Pause()
|
|
player.PlayPause()
|
|
player.Stop()
|
|
player.Next()
|
|
player.Previous()
|
|
assert [actions.get_nowait() for _ in range(6)] == [
|
|
"play",
|
|
"pause",
|
|
"toggle",
|
|
"stop",
|
|
"next",
|
|
"prev",
|
|
]
|
|
|
|
root = mpris._RootInterface(service)
|
|
root_interface = root.introspect()
|
|
root_props = {prop.name: prop.signature for prop in root_interface.properties}
|
|
assert root_props["Identity"] == "s"
|
|
assert root_props["SupportedUriSchemes"] == "as"
|
|
assert "Quit" in {method.name for method in root_interface.methods}
|
|
|
|
|
|
@pytest.mark.skipif(not mpris.DBUS_AVAILABLE, reason="dbus-next not installed")
|
|
def test_service_stores_state_without_bus() -> None:
|
|
service = mpris.MprisService(queue.Queue(), enabled=False)
|
|
service.set_track(
|
|
station="Groove Salad",
|
|
title="Rauschebart",
|
|
artist="Jens Buchert",
|
|
album="Gravity",
|
|
art_url="https://example.com/art.jpg",
|
|
stream_url="https://ice2.somafm.com/x-256-mp3",
|
|
)
|
|
service.set_status("Playing")
|
|
service.set_volume(0.8)
|
|
assert service._metadata["xesam:title"].value == "Rauschebart"
|
|
assert service._status == "Playing"
|
|
assert service._volume == 0.8
|