Files
MeshChatX/tests/backend/test_csp_logic.py
Sudo-Ivan e2586e9052
Some checks failed
CI / test-backend (push) Successful in 32s
CI / lint (push) Failing after 2m12s
CI / build-frontend (pull_request) Successful in 1m38s
Build and Publish Docker Image / build (pull_request) Has been skipped
CI / test-backend (pull_request) Successful in 24s
OSV-Scanner PR Scan / scan-pr (pull_request) Successful in 53s
CI / test-lang (pull_request) Successful in 1m15s
CI / lint (pull_request) Failing after 5m8s
CI / build-frontend (push) Successful in 9m46s
CI / test-lang (push) Successful in 9m48s
Tests / test (push) Successful in 13m32s
Tests / test (pull_request) Successful in 11m23s
Build Test / Build and Test (push) Successful in 15m56s
Build and Publish Docker Image / build-dev (pull_request) Successful in 13m42s
Build Test / Build and Test (pull_request) Successful in 16m9s
feat(tests): add comprehensive telemetry and interface tests
- Introduced new test files for telemetry functionality, including integration, fuzzing, and extended tests to ensure robustness and performance.
- Added tests for parsing LXMF display names and telemetry data, addressing potential bugs and ensuring correct handling of various input formats.
- Implemented performance tests for the InterfacesPage component, validating rendering efficiency with a large number of discovered interfaces.
- Enhanced existing tests for markdown rendering and link utilities to cover additional edge cases and improve stability.
2026-01-07 19:22:00 -06:00

114 lines
4.0 KiB
Python

from unittest.mock import MagicMock, patch, AsyncMock
import pytest
import RNS
from aiohttp import web
from meshchatx.meshchat import ReticulumMeshChat
@pytest.fixture
def mock_rns_minimal():
with (
patch("RNS.Reticulum") as mock_rns,
patch("RNS.Transport"),
patch("LXMF.LXMRouter"),
patch("meshchatx.meshchat.get_file_path", return_value="/tmp/mock_path"),
):
mock_rns_instance = mock_rns.return_value
mock_rns_instance.configpath = "/tmp/mock_config"
mock_rns_instance.is_connected_to_shared_instance = False
mock_rns_instance.transport_enabled.return_value = True
mock_id = MagicMock(spec=RNS.Identity)
mock_id.hash = b"test_hash_32_bytes_long_01234567"
mock_id.hexhash = mock_id.hash.hex()
mock_id.get_private_key.return_value = b"test_private_key"
yield mock_id
@pytest.mark.asyncio
async def test_csp_header_logic(mock_rns_minimal, tmp_path):
storage_dir = str(tmp_path / "storage")
config_dir = str(tmp_path / "config")
with patch("meshchatx.meshchat.generate_ssl_certificate"):
app_instance = ReticulumMeshChat(
identity=mock_rns_minimal,
storage_dir=storage_dir,
reticulum_config_dir=config_dir,
)
# Mock the config values
app_instance.config.csp_extra_connect_src.set("https://api.example.com")
app_instance.config.map_tile_server_url.set(
"https://tiles.example.com/{z}/{x}/{y}.png"
)
# Mock a request and handler
request = MagicMock(spec=web.Request)
request.path = "/"
request.app = {}
# We need to mock the handler to return a real response
async def mock_handler(req):
return web.Response(text="test")
# Call _define_routes to get the security_middleware
routes = web.RouteTableDef()
_, _, security_middleware = app_instance._define_routes(routes)
response = await security_middleware(request, mock_handler)
csp = response.headers.get("Content-Security-Policy", "")
assert "https://api.example.com" in csp
assert "https://tiles.example.com" in csp
assert "default-src 'self'" in csp
@pytest.mark.asyncio
async def test_config_update_csp(mock_rns_minimal, tmp_path):
storage_dir = str(tmp_path / "storage")
config_dir = str(tmp_path / "config")
with patch("meshchatx.meshchat.generate_ssl_certificate"):
app_instance = ReticulumMeshChat(
identity=mock_rns_minimal,
storage_dir=storage_dir,
reticulum_config_dir=config_dir,
)
# Find the config update handler
config_update_handler = None
for route in app_instance.get_routes():
if route.path == "/api/v1/config" and route.method == "PATCH":
config_update_handler = route.handler
break
assert config_update_handler is not None
# Mock request with new CSP settings
request_data = {
"csp_extra_connect_src": "https://api1.com, https://api2.com",
"csp_extra_img_src": "https://img.com",
}
request = MagicMock(spec=web.Request)
# request.json() must be awaited, so it should return an awaitable
request.json = AsyncMock(return_value=request_data)
# To avoid the JSON serialization error of MagicMock in get_config_dict,
# we mock get_config_dict to return a serializable dict.
with patch.object(
app_instance, "get_config_dict", return_value={"status": "ok"}
):
with patch.object(app_instance, "send_config_to_websocket_clients"):
response = await config_update_handler(request)
assert response.status == 200
assert (
app_instance.config.csp_extra_connect_src.get()
== "https://api1.com, https://api2.com"
)
assert app_instance.config.csp_extra_img_src.get() == "https://img.com"