"""Tests for the standalone help command.""" import pytest from mudlib import commands # Import command modules to register their commands from mudlib.commands import ( help, # noqa: F401 look, # noqa: F401 movement, # noqa: F401 ) from mudlib.commands.help import _help_topics from mudlib.content import load_help_topics @pytest.fixture def player(mock_reader, mock_writer): from mudlib.player import Player return Player(name="TestPlayer", x=5, y=5, reader=mock_reader, writer=mock_writer) @pytest.fixture def admin_player(mock_reader, mock_writer): from mudlib.player import Player p = Player(name="AdminPlayer", x=5, y=5, reader=mock_reader, writer=mock_writer) p.is_admin = True return p @pytest.fixture(autouse=True) def _load_zones_topic(): """Load the zones help topic for tests that need it.""" from pathlib import Path help_dir = Path(__file__).resolve().parents[1] / "content" / "help" if help_dir.exists(): loaded = load_help_topics(help_dir) _help_topics.update(loaded) yield _help_topics.clear() @pytest.mark.asyncio async def test_help_command_is_registered(): """The help command should be registered in the command registry.""" assert "help" in commands._registry @pytest.mark.asyncio async def test_help_has_wildcard_mode(): """Help should work from any mode.""" cmd_def = commands._registry["help"] assert cmd_def.mode == "*" @pytest.mark.asyncio async def test_help_no_args_shows_usage(player): """help with no args shows usage hint.""" await commands.dispatch(player, "help") output = "".join([call[0][0] for call in player.writer.write.call_args_list]) assert "help " in output assert "commands" in output assert "skills" in output @pytest.mark.asyncio async def test_help_known_command_shows_detail(player): """help shows detail view.""" await commands.dispatch(player, "help look") output = "".join([call[0][0] for call in player.writer.write.call_args_list]) assert "look" in output.lower() assert "mode:" in output.lower() @pytest.mark.asyncio async def test_help_unknown_command_shows_error(player): """help shows error message.""" await commands.dispatch(player, "help nonexistent") output = "".join([call[0][0] for call in player.writer.write.call_args_list]) assert "nonexistent" in output.lower() assert "unknown" in output.lower() or "not found" in output.lower() @pytest.mark.asyncio async def test_help_and_commands_both_exist(): """Both help and commands should be registered independently.""" assert "help" in commands._registry assert "commands" in commands._registry # They should be different functions assert commands._registry["help"].handler != commands._registry["commands"].handler @pytest.mark.asyncio async def test_help_zones_shows_guide(admin_player): """help zones shows zone guide text with command references.""" await commands.dispatch(admin_player, "help zones") output = "".join([call[0][0] for call in admin_player.writer.write.call_args_list]) assert "zones" in output assert "@zones" in output assert "@goto" in output assert "@dig" in output assert "@paint" in output assert "@save" in output @pytest.mark.asyncio async def test_help_zones_shows_see_also(admin_player): """help zones output contains see also cross-references.""" await commands.dispatch(admin_player, "help zones") output = "".join([call[0][0] for call in admin_player.writer.write.call_args_list]) assert "see:" in output @pytest.mark.asyncio async def test_help_zones_requires_admin(player): """Non-admin players cannot see admin help topics.""" await commands.dispatch(player, "help zones") output = "".join([call[0][0] for call in player.writer.write.call_args_list]) assert "unknown" in output.lower()