"""Tests for quit command.""" from unittest.mock import AsyncMock, MagicMock, patch import pytest from mudlib.commands.quit import cmd_quit from mudlib.player import Player, players from mudlib.zone import Zone @pytest.fixture(autouse=True) def clear_state(): """Clear players before and after each test.""" players.clear() yield players.clear() @pytest.fixture def test_zone(): """Create a test zone for players.""" terrain = [["." for _ in range(256)] for _ in range(256)] zone = Zone( name="testzone", width=256, height=256, toroidal=True, terrain=terrain, impassable=set(), ) return zone @pytest.fixture def mock_writer(): writer = MagicMock() writer.write = MagicMock() writer.drain = AsyncMock() writer.close = MagicMock() return writer @pytest.fixture def mock_reader(): return MagicMock() @pytest.fixture def player(mock_reader, mock_writer, test_zone): p = Player(name="Goku", x=0, y=0, reader=mock_reader, writer=mock_writer) p.location = test_zone test_zone._contents.append(p) players[p.name] = p return p @pytest.mark.asyncio async def test_quit_blocked_during_combat(player): """Test quit is blocked when player is in combat mode.""" player.mode_stack.append("combat") await cmd_quit(player, "") player.writer.write.assert_called_once_with("You can't quit during combat!\r\n") player.writer.close.assert_not_called() assert player.name in players # Still in player registry @pytest.mark.asyncio async def test_quit_works_when_not_in_combat(player): """Test quit works normally when not in combat.""" # Player starts in "normal" mode by default with patch("mudlib.commands.quit.save_player"): await cmd_quit(player, "") # Should write goodbye message player.writer.write.assert_called_with("Goodbye!\r\n") player.writer.drain.assert_called_once() player.writer.close.assert_called_once() assert player.name not in players # Removed from registry assert player.location is None # Removed from zone