import asyncio import json import logging import time import unittest from unittest.mock import AsyncMock, patch from app.mpv_player import MpvPlayer class _FakePipe: def __init__(self): self.closed = False self.response = b"" def write(self, request): payload = json.loads(request.decode("utf-8")) self.response = json.dumps({ "request_id": payload["request_id"], "error": "success", "data": payload["command"][1], }).encode("utf-8") + b"\n" def readline(self): response, self.response = self.response, b"" return response def close(self): self.closed = True class MpvPipeTests(unittest.TestCase): def test_pipe_connection_is_reused_across_commands(self): player = MpvPlayer("mpv.exe", logging.getLogger("test-mpv")) fake_pipe = _FakePipe() with patch("builtins.open", return_value=fake_pipe) as open_pipe: self.assertEqual(player._pipe_request_sync(["get_property", "duration"], 1), "duration") self.assertEqual(player._pipe_request_sync(["get_property", "time-pos"], 2), "time-pos") open_pipe.assert_called_once() player._reset_pipe_sync() self.assertTrue(fake_pipe.closed) class MpvMaintainTests(unittest.IsolatedAsyncioTestCase): async def test_maintain_returns_snapshot_for_caller_reuse(self): player = MpvPlayer("mpv.exe", logging.getLogger("test-mpv-maintain")) player.current_url = "https://example.invalid/audio" player.desired_state = "playing" player.started_at = time.time() - 10 player.last_progress_at = time.time() state = { "playing": True, "paused": False, "idle": False, "eof": False, "path": player.current_url, "current": {"progress": 10.0, "duration": 100.0}, } with patch.object(player, "running", return_value=True), patch.object( player, "snapshot", AsyncMock(return_value=state) ) as snapshot: result = await player.maintain() self.assertEqual(result["action"], "none") self.assertIs(result["snapshot"], state) snapshot.assert_awaited_once() if __name__ == "__main__": unittest.main()