Files
MeshChatX/tests/backend/test_community_interfaces.py
T

152 lines
4.7 KiB
Python

# SPDX-License-Identifier: 0BSD
import json
from unittest.mock import MagicMock, patch
import pytest
from meshchatx.src.backend.community_interfaces import CommunityInterfacesManager
from meshchatx.src.backend.rnstatus_handler import RNStatusHandler
@pytest.mark.asyncio
async def test_community_interfaces_manager_no_probe():
manager = CommunityInterfacesManager()
interfaces = await manager.get_interfaces()
assert len(interfaces) >= 1
for iface in interfaces:
assert "name" in iface and "target_host" in iface and "target_port" in iface
assert iface.get("online") is None
assert iface.get("last_check") == 0
@pytest.mark.asyncio
async def test_rnstatus_integration_simulated():
# Simulate how rnstatus would see these interfaces if they were added
mock_reticulum = MagicMock()
mock_reticulum.get_interface_stats.return_value = {
"interfaces": [
{
"name": "noDNS1",
"status": True,
"rxb": 100,
"txb": 200,
},
{
"name": "Remote TCP relay",
"status": False,
"rxb": 0,
"txb": 0,
},
],
}
handler = RNStatusHandler(mock_reticulum)
status = handler.get_status()
assert len(status["interfaces"]) == 2
assert status["interfaces"][0]["name"] == "noDNS1"
assert status["interfaces"][0]["status"] == "Up"
assert status["interfaces"][1]["name"] == "Remote TCP relay"
assert status["interfaces"][1]["status"] == "Down"
@pytest.mark.asyncio
async def test_community_interfaces_static_list():
manager = CommunityInterfacesManager()
ifaces1 = await manager.get_interfaces()
ifaces2 = await manager.get_interfaces()
assert ifaces1 == ifaces2
assert all(iface.get("online") is None for iface in ifaces1)
@pytest.mark.asyncio
async def test_community_interfaces_cache_used_when_no_public_override(tmp_path):
cache = tmp_path / "community_interfaces_cache.json"
cache.write_text(
json.dumps(
{
"interfaces": [
{
"name": "CacheOnly",
"type": "TCPClientInterface",
"target_host": "10.0.0.1",
"target_port": 4242,
},
],
},
),
encoding="utf-8",
)
manager = CommunityInterfacesManager(public_override_path=None, cache_path=cache)
ifaces = await manager.get_interfaces()
assert len(ifaces) == 1
assert ifaces[0]["name"] == "CacheOnly"
@pytest.mark.asyncio
async def test_community_interfaces_public_override_beats_cache(tmp_path):
public = tmp_path / "public.json"
public.write_text(
json.dumps(
{
"interfaces": [
{
"name": "FromPublic",
"type": "TCPClientInterface",
"target_host": "10.0.0.2",
"target_port": 4242,
},
],
},
),
encoding="utf-8",
)
cache = tmp_path / "cache.json"
cache.write_text(
json.dumps(
{
"interfaces": [
{
"name": "FromCache",
"type": "TCPClientInterface",
"target_host": "10.0.0.3",
"target_port": 4242,
},
],
},
),
encoding="utf-8",
)
manager = CommunityInterfacesManager(
public_override_path=str(public),
cache_path=str(cache),
)
ifaces = await manager.get_interfaces()
assert len(ifaces) == 1
assert ifaces[0]["name"] == "FromPublic"
def test_refresh_from_directory_writes_cache(tmp_path):
fake = [
{
"name": "FromNet",
"type": "TCPClientInterface",
"target_host": "9.9.9.9",
"target_port": 4242,
},
]
cache = tmp_path / "community_interfaces_cache.json"
manager = CommunityInterfacesManager(public_override_path=None, cache_path=cache)
with patch(
"meshchatx.src.backend.community_interfaces_directory.build_interfaces_from_directory_url",
return_value=(fake, "https://example.test/list"),
) as mock_build:
out = manager.refresh_from_directory()
mock_build.assert_called_once()
assert out["count"] == 1
assert out["source"] == "https://example.test/list"
assert cache.is_file()
manager2 = CommunityInterfacesManager(public_override_path=None, cache_path=cache)
assert manager2.interfaces[0]["name"] == "FromNet"