mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-06-07 16:11:39 +00:00
9b437efb05
- Introduced a new utility function `public_key_has_prefix` to check if a public key starts with a specified prefix in a case-insensitive manner. - Updated the `PathCommand` class to utilize the new utility function for public key prefix matching, enhancing code readability and maintainability. - Refactored logic in `PathCommand` and `BotDataViewer` to streamline the handling of recent repeaters based on recency scores, improving clarity in the filtering process.
117 lines
4.0 KiB
Python
117 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Unit tests for PathCommand repeater lookup (recency filter and prefix matching)."""
|
|
|
|
from datetime import datetime, timedelta
|
|
from unittest.mock import AsyncMock, Mock
|
|
|
|
import pytest
|
|
|
|
from modules.commands.path_command import PathCommand
|
|
from modules.utils import public_key_has_prefix
|
|
from tests.helpers import create_test_repeater
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestPublicKeyHasPrefix:
|
|
def test_case_insensitive_match(self):
|
|
assert public_key_has_prefix("155eabcd", "155E") is True
|
|
assert public_key_has_prefix("155EABCD", "155e") is True
|
|
|
|
def test_empty_inputs(self):
|
|
assert public_key_has_prefix("", "155E") is False
|
|
assert public_key_has_prefix("155eabcd", "") is False
|
|
|
|
|
|
@pytest.mark.unit
|
|
class TestPathCommandLookupRecency:
|
|
@pytest.fixture
|
|
def path_command(self, mock_bot):
|
|
cmd = PathCommand(mock_bot)
|
|
cmd.graph_based_validation = False
|
|
cmd.geographic_guessing_enabled = False
|
|
return cmd
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_single_stale_repeater_resolves(self, path_command):
|
|
stale = datetime.now() - timedelta(days=30)
|
|
|
|
def lookup(node_id):
|
|
return [
|
|
create_test_repeater(
|
|
prefix="15",
|
|
name="Stale Repeater",
|
|
public_key="155e" + "ab" * 31,
|
|
last_heard=stale,
|
|
last_advert_timestamp=stale,
|
|
)
|
|
]
|
|
|
|
result = await path_command._lookup_repeater_names(["155E"], lookup_func=lookup)
|
|
|
|
assert result["155E"]["found"] is True
|
|
assert result["155E"]["collision"] is False
|
|
assert result["155E"]["name"] == "Stale Repeater"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_multiple_stale_repeaters_remain_unknown(self, path_command):
|
|
stale = datetime.now() - timedelta(days=30)
|
|
|
|
def lookup(node_id):
|
|
return [
|
|
create_test_repeater(
|
|
prefix="15",
|
|
name="Stale A",
|
|
public_key="155e" + "11" * 31,
|
|
last_heard=stale,
|
|
last_advert_timestamp=stale,
|
|
),
|
|
create_test_repeater(
|
|
prefix="15",
|
|
name="Stale B",
|
|
public_key="155e" + "22" * 31,
|
|
last_heard=stale,
|
|
last_advert_timestamp=stale,
|
|
),
|
|
]
|
|
|
|
result = await path_command._lookup_repeater_names(["155E"], lookup_func=lookup)
|
|
|
|
assert result["155E"]["found"] is False
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_case_insensitive_repeater_manager_match(self, mock_bot):
|
|
mock_bot.repeater_manager.get_repeater_devices = AsyncMock(
|
|
return_value=[
|
|
{
|
|
"public_key": "155e" + "ab" * 31,
|
|
"name": "Repeater 155E",
|
|
"device_type": "repeater",
|
|
"last_heard": datetime.now() - timedelta(days=30),
|
|
"last_advert_timestamp": datetime.now() - timedelta(days=30),
|
|
"is_currently_tracked": False,
|
|
"latitude": 47.6,
|
|
"longitude": -122.3,
|
|
"city": "Seattle",
|
|
"state": "WA",
|
|
"country": "USA",
|
|
"advert_count": 1,
|
|
"signal_strength": None,
|
|
"snr": None,
|
|
"hop_count": 0,
|
|
"role": "repeater",
|
|
"is_starred": 0,
|
|
}
|
|
]
|
|
)
|
|
mock_bot.meshcore = Mock()
|
|
mock_bot.meshcore.contacts = {}
|
|
|
|
path_command = PathCommand(mock_bot)
|
|
path_command.graph_based_validation = False
|
|
path_command.geographic_guessing_enabled = False
|
|
|
|
result = await path_command._lookup_repeater_names(["155E"])
|
|
|
|
assert result["155E"]["found"] is True
|
|
assert result["155E"]["name"] == "Repeater 155E"
|