Files
meshcore-bot/tests/test_checkin_service.py
T
Stacy Olivas ae57e651ea test: expanded test suite for v0.9.0 modules
Command tests:
- tests/commands/: test_base_command, test_cmd_command, test_dice_command,
  test_hello_command, test_help_command, test_magic8_command,
  test_ping_command, test_roll_command
- tests/test_bridge_bot_responses, test_channel_manager_logic,
  test_checkin_service, test_command_manager, test_command_prefix,
  test_config_merge, test_config_validation, test_db_manager,
  test_plugin_loader, test_profanity_filter, test_security_utils,
  test_service_plugin_loader, test_utils

Integration and unit:
- tests/integration/: test_path_graph_integration, test_path_resolution
- tests/regression/: test_keyword_escapes
- tests/unit/: test_mesh_graph, test_mesh_graph_edges,
  test_mesh_graph_multihop, test_mesh_graph_optimizations,
  test_mesh_graph_scoring, test_mesh_graph_validation,
  test_path_command_graph, test_path_command_graph_selection,
  test_path_command_multibyte

Helpers: tests/conftest.py, tests/helpers.py
2026-03-17 18:07:18 -07:00

146 lines
5.7 KiB
Python

"""Tests for local check-in service plugin.
Skipped when the checkin_service local plugin is not present (it does not ship with the bot).
"""
import configparser
# Import from local plugin (repo root is on path when running tests)
import sys
from datetime import datetime
from pathlib import Path
from unittest.mock import MagicMock, Mock, patch
import pytest
_root = Path(__file__).resolve().parent.parent
if str(_root) not in sys.path:
sys.path.insert(0, str(_root))
try:
from local.service_plugins.checkin_service import CheckInService
except ImportError:
CheckInService = None
pytestmark = pytest.mark.skip(reason="local checkin_service plugin not installed")
def _make_bot(config_overrides=None):
"""Build a mock bot with [CheckIn] and channel_manager."""
bot = MagicMock()
bot.logger = Mock()
bot.logger.info = Mock()
bot.logger.warning = Mock()
bot.logger.error = Mock()
bot.logger.debug = Mock()
bot.config = configparser.ConfigParser()
bot.config.add_section("Connection")
bot.config.add_section("Bot")
bot.config.add_section("Channels")
bot.config.add_section("CheckIn")
bot.config.set("CheckIn", "enabled", "true")
bot.config.set("CheckIn", "channel", "#meshmonday")
bot.config.set("CheckIn", "check_in_days", "daily")
bot.config.set("CheckIn", "require_phrase", "check in")
bot.config.set("CheckIn", "any_message_counts", "false")
bot.config.set("CheckIn", "flush_time", "23:59")
bot.config.set("CheckIn", "api_url", "")
bot.config.set("CheckIn", "api_key", "")
if config_overrides:
for k, v in config_overrides.items():
bot.config.set("CheckIn", k, str(v))
channel_manager = MagicMock()
channel_manager.get_channel_name = Mock(return_value="#meshmonday")
bot.channel_manager = channel_manager
return bot
def _make_event(channel_idx=0, text="HOWL: check in", raw_hex=None):
event = MagicMock()
event.payload = {
"channel_idx": channel_idx,
"text": text,
}
if raw_hex is not None:
event.payload["raw_hex"] = raw_hex
return event
@pytest.mark.asyncio
async def test_message_wrong_channel_not_stored():
"""Message in a different channel is not stored."""
bot = _make_bot()
bot.channel_manager.get_channel_name.return_value = "#other"
service = CheckInService(bot)
with patch("local.service_plugins.checkin_service.get_config_timezone") as gtz:
gtz.return_value = (MagicMock(), "America/Los_Angeles")
await service._on_channel_message(_make_event(), None)
assert not service._buckets
@pytest.mark.asyncio
async def test_message_correct_channel_with_phrase_stored():
"""Message in configured channel containing the phrase is stored."""
bot = _make_bot()
service = CheckInService(bot)
with patch("local.service_plugins.checkin_service.get_config_timezone") as gtz:
tz = MagicMock()
gtz.return_value = (tz, "America/Los_Angeles")
with patch("local.service_plugins.checkin_service.datetime") as dt:
dt.now.return_value = datetime(2025, 3, 3, 12, 0, 0) # Monday
await service._on_channel_message(_make_event(text="HOWL: check in"), None)
assert len(service._buckets) == 1
date_str = "2025-03-03"
assert date_str in service._buckets
records = service._buckets[date_str]
assert len(records) == 1
rec = next(iter(records.values()))
assert rec["username"] == "HOWL"
assert rec["message"] == "check in"
assert "packet_hash" in rec
@pytest.mark.asyncio
async def test_message_without_phrase_when_required_not_stored():
"""When require_phrase is set and any_message_counts is false, message without phrase is not stored."""
bot = _make_bot({"require_phrase": "check in", "any_message_counts": "false"})
service = CheckInService(bot)
with patch("local.service_plugins.checkin_service.get_config_timezone") as gtz:
gtz.return_value = (MagicMock(), "America/Los_Angeles")
with patch("local.service_plugins.checkin_service.datetime") as dt:
dt.now.return_value = datetime(2025, 3, 3, 12, 0, 0)
await service._on_channel_message(_make_event(text="HOWL: hello world"), None)
assert not service._buckets
@pytest.mark.asyncio
async def test_any_message_counts_stored():
"""When any_message_counts is true, any message in the channel is stored."""
bot = _make_bot({"any_message_counts": "true", "require_phrase": ""})
service = CheckInService(bot)
with patch("local.service_plugins.checkin_service.get_config_timezone") as gtz:
gtz.return_value = (MagicMock(), "America/Los_Angeles")
with patch("local.service_plugins.checkin_service.datetime") as dt:
dt.now.return_value = datetime(2025, 3, 4, 14, 0, 0)
await service._on_channel_message(_make_event(text="ALICE: random message"), None)
assert len(service._buckets) == 1
assert "2025-03-04" in service._buckets
records = service._buckets["2025-03-04"]
assert len(records) == 1
rec = next(iter(records.values()))
assert rec["username"] == "ALICE"
assert rec["message"] == "random message"
@pytest.mark.asyncio
async def test_monday_only_skips_tuesday():
"""When check_in_days is monday, message on Tuesday is not stored."""
bot = _make_bot({"check_in_days": "monday"})
service = CheckInService(bot)
with patch("local.service_plugins.checkin_service.get_config_timezone") as gtz:
gtz.return_value = (MagicMock(), "America/Los_Angeles")
with patch("local.service_plugins.checkin_service.datetime") as dt:
# Tuesday 2025-03-04
dt.now.return_value = datetime(2025, 3, 4, 12, 0, 0)
await service._on_channel_message(_make_event(text="HOWL: check in"), None)
assert not service._buckets