120 lines
3.4 KiB
Python
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 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())
|
|
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()
|