mud/tests/test_help_topics.py

156 lines
4.2 KiB
Python

"""Tests for TOML help topic loading."""
import textwrap
from unittest.mock import AsyncMock, MagicMock
import pytest
from mudlib import commands
from mudlib.commands import help as help_mod # 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 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=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