mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-03-31 20:45:39 +00:00
New test modules: - test_announcements_command: parse, record_trigger, execute paths - test_aurora_command: KP index parsing, alert levels, execute paths - test_channel_manager: generate_hashtag_key, cache lookups, validation - test_channels_command: remaining channel info display paths - test_dadjoke_command: format, split, length, execute - test_graph_trace_helper: geo-location helper and graph algorithm paths - test_hacker_command: text transform logic - test_help_command: format list, channel filter, general/specific help - test_i18n: fallback loops, format failure, PermissionError, get_value - test_joke_command: seasonal, format, split, dark, execute - test_moon_command: phase calc, execute success/error - test_multitest_command: multi-channel test sequences - test_stats_command: adverts leaderboard, get_stats_summary, cleanup - test_trace_command: path extract, parse, format inline/vertical - test_web_viewer_integration: circuit breaker, JSON serializer, packet capture, channel message - test_webviewer_command: 100% coverage Extended existing: test_command_manager, test_feed_manager, test_message_handler, test_rate_limiter, test_repeater_manager, test_scheduler_logic, test_security_utils, test_transmission_tracker, test_utils, test_web_viewer
157 lines
4.9 KiB
Python
157 lines
4.9 KiB
Python
"""Tests for modules.commands.multitest_command — pure logic functions."""
|
|
|
|
import configparser
|
|
from unittest.mock import MagicMock, Mock
|
|
|
|
import pytest
|
|
|
|
from modules.commands.multitest_command import MultitestCommand
|
|
from tests.conftest import mock_message
|
|
|
|
|
|
def _make_bot():
|
|
bot = MagicMock()
|
|
bot.logger = Mock()
|
|
config = configparser.ConfigParser()
|
|
config.add_section("Bot")
|
|
config.set("Bot", "bot_name", "TestBot")
|
|
config.add_section("Channels")
|
|
config.set("Channels", "monitor_channels", "general")
|
|
config.set("Channels", "respond_to_dms", "true")
|
|
config.add_section("Keywords")
|
|
config.add_section("Multitest_Command")
|
|
config.set("Multitest_Command", "enabled", "true")
|
|
bot.config = config
|
|
bot.translator = MagicMock()
|
|
bot.translator.translate = Mock(side_effect=lambda key, **kw: key)
|
|
bot.command_manager = MagicMock()
|
|
bot.command_manager.monitor_channels = ["general"]
|
|
bot.prefix_hex_chars = 2
|
|
return bot
|
|
|
|
|
|
class TestExtractPathFromRfData:
|
|
"""Tests for extract_path_from_rf_data."""
|
|
|
|
def setup_method(self):
|
|
self.cmd = MultitestCommand(_make_bot())
|
|
|
|
def test_no_routing_info_returns_none(self):
|
|
result = self.cmd.extract_path_from_rf_data({})
|
|
assert result is None
|
|
|
|
def test_empty_routing_info_returns_none(self):
|
|
result = self.cmd.extract_path_from_rf_data({"routing_info": {}})
|
|
assert result is None
|
|
|
|
def test_path_nodes_extracted(self):
|
|
rf_data = {
|
|
"routing_info": {
|
|
"path_nodes": ["01", "7a", "55"]
|
|
}
|
|
}
|
|
result = self.cmd.extract_path_from_rf_data(rf_data)
|
|
assert result == "01,7a,55"
|
|
|
|
def test_path_hex_fallback(self):
|
|
rf_data = {
|
|
"routing_info": {
|
|
"path_nodes": [],
|
|
"path_hex": "017a55",
|
|
"bytes_per_hop": 1
|
|
}
|
|
}
|
|
result = self.cmd.extract_path_from_rf_data(rf_data)
|
|
assert result is not None
|
|
assert "01" in result
|
|
|
|
def test_invalid_nodes_skipped(self):
|
|
rf_data = {
|
|
"routing_info": {
|
|
"path_nodes": ["01", "zz", "55"]
|
|
}
|
|
}
|
|
result = self.cmd.extract_path_from_rf_data(rf_data)
|
|
# zz is invalid hex, should be excluded
|
|
if result:
|
|
assert "zz" not in result
|
|
|
|
|
|
class TestExtractPathFromMessage:
|
|
"""Tests for extract_path_from_message."""
|
|
|
|
def setup_method(self):
|
|
self.cmd = MultitestCommand(_make_bot())
|
|
|
|
def test_no_path_returns_none(self):
|
|
msg = mock_message(content="multitest", path=None)
|
|
msg.routing_info = None
|
|
result = self.cmd.extract_path_from_message(msg)
|
|
assert result is None
|
|
|
|
def test_direct_returns_none(self):
|
|
msg = mock_message(content="multitest", path="Direct")
|
|
msg.routing_info = None
|
|
result = self.cmd.extract_path_from_message(msg)
|
|
assert result is None
|
|
|
|
def test_zero_hops_returns_none(self):
|
|
msg = mock_message(content="multitest", path="0 hops")
|
|
msg.routing_info = None
|
|
result = self.cmd.extract_path_from_message(msg)
|
|
assert result is None
|
|
|
|
def test_comma_path_extracted(self):
|
|
msg = mock_message(content="multitest", path="01,7a,55")
|
|
msg.routing_info = None
|
|
result = self.cmd.extract_path_from_message(msg)
|
|
assert result is not None
|
|
assert "01" in result
|
|
|
|
def test_routing_info_path_preferred(self):
|
|
msg = mock_message(content="multitest", path="01,7a")
|
|
msg.routing_info = {
|
|
"path_length": 2,
|
|
"path_nodes": ["7a", "55"],
|
|
"bytes_per_hop": None
|
|
}
|
|
result = self.cmd.extract_path_from_message(msg)
|
|
# routing_info is preferred
|
|
assert result is not None
|
|
|
|
|
|
class TestMatchesKeyword:
|
|
"""Tests for matches_keyword."""
|
|
|
|
def setup_method(self):
|
|
self.cmd = MultitestCommand(_make_bot())
|
|
|
|
def test_multitest_matches(self):
|
|
assert self.cmd.matches_keyword(mock_message(content="multitest")) is True
|
|
|
|
def test_mt_matches(self):
|
|
assert self.cmd.matches_keyword(mock_message(content="mt")) is True
|
|
|
|
def test_exclamation_prefix(self):
|
|
assert self.cmd.matches_keyword(mock_message(content="!multitest")) is True
|
|
|
|
def test_other_does_not_match(self):
|
|
assert self.cmd.matches_keyword(mock_message(content="ping")) is False
|
|
|
|
|
|
class TestCanExecute:
|
|
"""Tests for can_execute."""
|
|
|
|
def test_enabled(self):
|
|
bot = _make_bot()
|
|
cmd = MultitestCommand(bot)
|
|
msg = mock_message(content="multitest", channel="general")
|
|
assert cmd.can_execute(msg) is True
|
|
|
|
def test_disabled(self):
|
|
bot = _make_bot()
|
|
bot.config.set("Multitest_Command", "enabled", "false")
|
|
cmd = MultitestCommand(bot)
|
|
msg = mock_message(content="multitest", channel="general")
|
|
assert cmd.can_execute(msg) is False
|