mud/tests/test_play_command.py

120 lines
3.4 KiB
Python

"""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" 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())
mock_session.stop = AsyncMock()
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
# Verify session.stop() was called
mock_session.stop.assert_called_once()