Removed identical local copies from 45 test files. These fixtures are already defined in conftest.py.
255 lines
7.9 KiB
Python
255 lines
7.9 KiB
Python
"""Tests for TOML help topic loading."""
|
|
|
|
import textwrap
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from mudlib import commands
|
|
from mudlib.commands import help as help_mod # noqa: F401
|
|
from mudlib.commands import helpadmin # noqa: F401
|
|
from mudlib.commands.help import _help_topics
|
|
from mudlib.content import HelpTopic, load_help_topics
|
|
|
|
|
|
@pytest.fixture
|
|
def help_dir(tmp_path):
|
|
"""Create a temp directory with sample help TOML files."""
|
|
topic = tmp_path / "combat.toml"
|
|
topic.write_text(
|
|
textwrap.dedent("""\
|
|
name = "combat"
|
|
title = "combat primer"
|
|
body = \"\"\"
|
|
combat is initiated when you attack another entity.
|
|
use skills to learn your available moves.
|
|
\"\"\"
|
|
""")
|
|
)
|
|
|
|
admin_topic = tmp_path / "building.toml"
|
|
admin_topic.write_text(
|
|
textwrap.dedent("""\
|
|
name = "building"
|
|
title = "builder's guide"
|
|
admin = true
|
|
body = \"\"\"
|
|
use @dig to create zones and @paint to edit terrain.
|
|
\"\"\"
|
|
""")
|
|
)
|
|
return tmp_path
|
|
|
|
|
|
def test_load_help_topics(help_dir):
|
|
topics = load_help_topics(help_dir)
|
|
assert "combat" in topics
|
|
assert "building" in topics
|
|
|
|
|
|
def test_help_topic_fields(help_dir):
|
|
topics = load_help_topics(help_dir)
|
|
combat = topics["combat"]
|
|
assert combat.name == "combat"
|
|
assert combat.title == "combat primer"
|
|
assert combat.admin is False
|
|
assert "combat is initiated" in combat.body
|
|
|
|
|
|
def test_help_topic_admin_flag(help_dir):
|
|
topics = load_help_topics(help_dir)
|
|
building = topics["building"]
|
|
assert building.admin is True
|
|
|
|
|
|
def test_help_topic_title_defaults_to_name(tmp_path):
|
|
topic = tmp_path / "simple.toml"
|
|
topic.write_text('name = "simple"\nbody = "just a test"\n')
|
|
topics = load_help_topics(tmp_path)
|
|
assert topics["simple"].title == "simple"
|
|
|
|
|
|
def test_load_help_topics_empty_dir(tmp_path):
|
|
topics = load_help_topics(tmp_path)
|
|
assert topics == {}
|
|
|
|
|
|
def test_load_help_topics_skips_bad_files(tmp_path):
|
|
bad = tmp_path / "broken.toml"
|
|
bad.write_text("not valid toml [[[")
|
|
good = tmp_path / "good.toml"
|
|
good.write_text('name = "good"\nbody = "works"\n')
|
|
topics = load_help_topics(tmp_path)
|
|
assert "good" in topics
|
|
assert "broken" not in topics
|
|
|
|
|
|
@pytest.fixture
|
|
def player(mock_writer):
|
|
from mudlib.player import Player
|
|
|
|
return Player(name="Tester", x=0, y=0, reader=MagicMock(), writer=mock_writer)
|
|
|
|
|
|
@pytest.fixture
|
|
def admin_player(mock_writer):
|
|
from mudlib.player import Player
|
|
|
|
p = Player(name="Admin", x=0, y=0, reader=MagicMock(), writer=mock_writer)
|
|
p.is_admin = True
|
|
return p
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _clear_topics():
|
|
_help_topics.clear()
|
|
yield
|
|
_help_topics.clear()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_help_shows_toml_topic(player):
|
|
_help_topics["combat"] = HelpTopic(
|
|
name="combat", body="fight stuff", title="combat primer"
|
|
)
|
|
await commands.dispatch(player, "help combat")
|
|
output = "".join(c[0][0] for c in player.writer.write.call_args_list)
|
|
assert "combat primer" in output
|
|
assert "fight stuff" in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_help_admin_topic_hidden_from_players(player):
|
|
_help_topics["secret"] = HelpTopic(
|
|
name="secret", body="hidden", title="secret stuff", admin=True
|
|
)
|
|
await commands.dispatch(player, "help secret")
|
|
output = "".join(c[0][0] for c in player.writer.write.call_args_list)
|
|
assert "hidden" not in output
|
|
assert "unknown" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_help_admin_topic_visible_to_admins(admin_player):
|
|
_help_topics["secret"] = HelpTopic(
|
|
name="secret", body="hidden", title="secret stuff", admin=True
|
|
)
|
|
await commands.dispatch(admin_player, "help secret")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "hidden" in output
|
|
|
|
|
|
def test_zones_toml_loads_from_content():
|
|
from pathlib import Path
|
|
|
|
help_dir = Path(__file__).resolve().parents[1] / "content" / "help"
|
|
topics = load_help_topics(help_dir)
|
|
assert "zones" in topics
|
|
assert topics["zones"].admin is True
|
|
assert "@zones" in topics["zones"].body
|
|
|
|
|
|
def test_player_has_pending_input():
|
|
from mudlib.player import Player
|
|
|
|
p = Player(name="Test", x=0, y=0, reader=MagicMock(), writer=MagicMock())
|
|
assert p.pending_input is None
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_lists_topics(admin_player):
|
|
_help_topics["combat"] = HelpTopic(
|
|
name="combat", body="fight", title="combat primer"
|
|
)
|
|
_help_topics["zones"] = HelpTopic(
|
|
name="zones", body="build", title="zone guide", admin=True
|
|
)
|
|
await commands.dispatch(admin_player, "@help")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "combat" in output
|
|
assert "combat primer" in output
|
|
assert "zones" in output
|
|
assert "[admin]" in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_requires_admin(player):
|
|
await commands.dispatch(player, "@help")
|
|
output = "".join(c[0][0] for c in player.writer.write.call_args_list)
|
|
# Should be rejected by dispatch (admin=True check)
|
|
assert "permission" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_create_with_name_prompts_title(admin_player):
|
|
"""@help create <name> should prompt for title."""
|
|
await commands.dispatch(admin_player, "@help create combat")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "title" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_create_no_args_prompts_name(admin_player):
|
|
"""@help create with no args prompts for the topic name."""
|
|
await commands.dispatch(admin_player, "@help create")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "name" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_edit_unknown_topic(admin_player):
|
|
await commands.dispatch(admin_player, "@help edit bogus")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "not found" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_edit_no_args(admin_player):
|
|
await commands.dispatch(admin_player, "@help edit")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "usage" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_edit_prompts_title(admin_player):
|
|
_help_topics["combat"] = HelpTopic(
|
|
name="combat", body="old body", title="combat primer"
|
|
)
|
|
await commands.dispatch(admin_player, "@help edit combat")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
# Should show current title as default
|
|
assert "combat primer" in output
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_remove_unknown_topic(admin_player):
|
|
await commands.dispatch(admin_player, "@help remove bogus")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "not found" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_remove_no_args(admin_player):
|
|
await commands.dispatch(admin_player, "@help remove")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "usage" in output.lower()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_at_help_remove_prompts_confirmation(admin_player):
|
|
_help_topics["combat"] = HelpTopic(
|
|
name="combat", body="fight", title="combat primer"
|
|
)
|
|
await commands.dispatch(admin_player, "@help remove combat")
|
|
output = "".join(c[0][0] for c in admin_player.writer.write.call_args_list)
|
|
assert "y/n" in output.lower() or "confirm" in output.lower()
|
|
|
|
|
|
def test_at_help_toml_loads_from_content():
|
|
from pathlib import Path
|
|
|
|
help_dir = Path(__file__).resolve().parents[1] / "content" / "help"
|
|
if help_dir.exists():
|
|
topics = load_help_topics(help_dir)
|
|
assert "@help" in topics
|
|
assert topics["@help"].admin is True
|