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