"""Tests for the play command.""" from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest @pytest.fixture def mock_writer(): writer = MagicMock() writer.write = MagicMock() writer.drain = AsyncMock() return writer @pytest.fixture def player(mock_writer): from mudlib.player import Player return Player(name="tester", x=5, y=5, writer=mock_writer) def test_play_command_registered(): """Verify play command is registered.""" import mudlib.commands.play # noqa: F401 from mudlib import commands assert "play" in commands._registry cmd = commands._registry["play"] assert cmd.name == "play" assert cmd.mode == "normal" @pytest.mark.asyncio async def test_play_no_args(player): """Playing with no args sends usage message.""" from mudlib.commands.play import cmd_play await cmd_play(player, "") player.writer.write.assert_called() output = player.writer.write.call_args[0][0] assert "play what?" in output.lower() @pytest.mark.asyncio async def test_play_unknown_story(player): """Playing unknown story sends error message.""" from mudlib.commands.play import cmd_play await cmd_play(player, "nosuchgame") player.writer.write.assert_called() output = player.writer.write.call_args[0][0] assert "no story found" in output.lower() assert "nosuchgame" in output.lower() @pytest.mark.asyncio async def test_play_enters_if_mode(player): """Playing a valid story enters IF mode and creates session.""" from mudlib.commands.play import cmd_play # Mock IFSession mock_session = Mock() mock_session.start = AsyncMock(return_value="Welcome to Zork!") with patch("mudlib.commands.play.IFSession") as MockIFSession: MockIFSession.return_value = mock_session # Ensure story file exists check passes with patch("mudlib.commands.play._find_story") as mock_find: mock_find.return_value = "/fake/path/zork1.z3" await cmd_play(player, "zork1") # Verify session was created and started mock_session.start.assert_called_once() # Verify mode was pushed assert "if" in player.mode_stack # Verify session was attached to player assert player.if_session is mock_session # Verify intro was sent player.writer.write.assert_called() output = player.writer.write.call_args[0][0] assert "Welcome to Zork!" in output @pytest.mark.asyncio async def test_play_handles_dfrotz_missing(player): """Playing when dfrotz is missing sends error.""" from mudlib.commands.play import cmd_play # Mock IFSession to raise FileNotFoundError on start mock_session = Mock() mock_session.start = AsyncMock(side_effect=FileNotFoundError()) with patch("mudlib.commands.play.IFSession") as MockIFSession: MockIFSession.return_value = mock_session with patch("mudlib.commands.play._find_story") as mock_find: mock_find.return_value = "/fake/path/zork1.z3" await cmd_play(player, "zork1") # Verify error message was sent player.writer.write.assert_called() output = player.writer.write.call_args[0][0] assert "dfrotz not found" in output.lower() # Verify mode was NOT pushed assert "if" not in player.mode_stack # Verify session was NOT attached assert player.if_session is None