mirror of
https://github.com/ipnet-mesh/meshcore-hub.git
synced 2026-03-28 17:42:56 +01:00
- Create conftest.py with MockHttpClient for testing web routes - Add test_home.py with 9 tests for home page - Add test_members.py with 11 tests for members page and load_members function - Add test_network.py with 7 tests for network overview page - Add test_nodes.py with 15 tests for nodes list and detail pages - Add test_map.py with 12 tests for map page and data endpoint - Add test_messages.py with 13 tests for messages page with filtering - All 67 web tests pass, 184 total tests pass - Update TASKS.md to mark Phase 5 as 100% complete (186/221 total)
175 lines
5.9 KiB
Python
175 lines
5.9 KiB
Python
"""Tests for the map page routes."""
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from tests.test_web.conftest import MockHttpClient
|
|
|
|
|
|
class TestMapPage:
|
|
"""Tests for the map page."""
|
|
|
|
def test_map_returns_200(self, client: TestClient) -> None:
|
|
"""Test that map page returns 200 status code."""
|
|
response = client.get("/map")
|
|
assert response.status_code == 200
|
|
|
|
def test_map_returns_html(self, client: TestClient) -> None:
|
|
"""Test that map page returns HTML content."""
|
|
response = client.get("/map")
|
|
assert "text/html" in response.headers["content-type"]
|
|
|
|
def test_map_contains_network_name(self, client: TestClient) -> None:
|
|
"""Test that map page contains the network name."""
|
|
response = client.get("/map")
|
|
assert "Test Network" in response.text
|
|
|
|
def test_map_contains_leaflet(self, client: TestClient) -> None:
|
|
"""Test that map page includes Leaflet library."""
|
|
response = client.get("/map")
|
|
# Should include Leaflet JS/CSS
|
|
assert "leaflet" in response.text.lower()
|
|
|
|
|
|
class TestMapDataEndpoint:
|
|
"""Tests for the map data JSON endpoint."""
|
|
|
|
def test_map_data_returns_200(self, client: TestClient) -> None:
|
|
"""Test that map data endpoint returns 200 status code."""
|
|
response = client.get("/map/data")
|
|
assert response.status_code == 200
|
|
|
|
def test_map_data_returns_json(self, client: TestClient) -> None:
|
|
"""Test that map data endpoint returns JSON content."""
|
|
response = client.get("/map/data")
|
|
assert "application/json" in response.headers["content-type"]
|
|
|
|
def test_map_data_contains_nodes(
|
|
self, client: TestClient, mock_http_client: MockHttpClient
|
|
) -> None:
|
|
"""Test that map data contains nodes with location."""
|
|
response = client.get("/map/data")
|
|
data = response.json()
|
|
|
|
assert "nodes" in data
|
|
# The mock includes a node with lat/lon tags
|
|
nodes = data["nodes"]
|
|
# Should have at least one node with location
|
|
assert len(nodes) == 1
|
|
assert nodes[0]["name"] == "Node Two"
|
|
assert nodes[0]["lat"] == 40.7128
|
|
assert nodes[0]["lon"] == -74.0060
|
|
|
|
def test_map_data_contains_center(
|
|
self, client: TestClient, mock_http_client: MockHttpClient
|
|
) -> None:
|
|
"""Test that map data contains network center location."""
|
|
response = client.get("/map/data")
|
|
data = response.json()
|
|
|
|
assert "center" in data
|
|
center = data["center"]
|
|
assert center["lat"] == 40.7128
|
|
assert center["lon"] == -74.0060
|
|
|
|
def test_map_data_excludes_nodes_without_location(
|
|
self, client: TestClient, mock_http_client: MockHttpClient
|
|
) -> None:
|
|
"""Test that map data excludes nodes without location tags."""
|
|
response = client.get("/map/data")
|
|
data = response.json()
|
|
|
|
nodes = data["nodes"]
|
|
# Node One has no location tags, so should not appear
|
|
node_names = [n["name"] for n in nodes]
|
|
assert "Node One" not in node_names
|
|
|
|
|
|
class TestMapDataAPIErrors:
|
|
"""Tests for map data handling API errors."""
|
|
|
|
def test_map_data_handles_api_error(
|
|
self, web_app: any, mock_http_client: MockHttpClient
|
|
) -> None:
|
|
"""Test that map data handles API errors gracefully."""
|
|
mock_http_client.set_response(
|
|
"GET", "/api/v1/nodes", status_code=500, json_data=None
|
|
)
|
|
web_app.state.http_client = mock_http_client
|
|
|
|
client = TestClient(web_app, raise_server_exceptions=True)
|
|
response = client.get("/map/data")
|
|
|
|
# Should still return 200 with empty nodes
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data["nodes"] == []
|
|
assert "center" in data
|
|
|
|
|
|
class TestMapDataFiltering:
|
|
"""Tests for map data location filtering."""
|
|
|
|
def test_map_data_filters_invalid_lat(
|
|
self, web_app: any, mock_http_client: MockHttpClient
|
|
) -> None:
|
|
"""Test that map data filters nodes with invalid latitude."""
|
|
mock_http_client.set_response(
|
|
"GET",
|
|
"/api/v1/nodes",
|
|
status_code=200,
|
|
json_data={
|
|
"items": [
|
|
{
|
|
"id": "node-1",
|
|
"public_key": "abc123",
|
|
"name": "Bad Lat Node",
|
|
"tags": [
|
|
{"key": "lat", "value": "not-a-number"},
|
|
{"key": "lon", "value": "-74.0060"},
|
|
],
|
|
},
|
|
],
|
|
"total": 1,
|
|
},
|
|
)
|
|
web_app.state.http_client = mock_http_client
|
|
|
|
client = TestClient(web_app, raise_server_exceptions=True)
|
|
response = client.get("/map/data")
|
|
data = response.json()
|
|
|
|
# Node with invalid lat should be excluded
|
|
assert len(data["nodes"]) == 0
|
|
|
|
def test_map_data_filters_missing_lon(
|
|
self, web_app: any, mock_http_client: MockHttpClient
|
|
) -> None:
|
|
"""Test that map data filters nodes with missing longitude."""
|
|
mock_http_client.set_response(
|
|
"GET",
|
|
"/api/v1/nodes",
|
|
status_code=200,
|
|
json_data={
|
|
"items": [
|
|
{
|
|
"id": "node-1",
|
|
"public_key": "abc123",
|
|
"name": "No Lon Node",
|
|
"tags": [
|
|
{"key": "lat", "value": "40.7128"},
|
|
],
|
|
},
|
|
],
|
|
"total": 1,
|
|
},
|
|
)
|
|
web_app.state.http_client = mock_http_client
|
|
|
|
client = TestClient(web_app, raise_server_exceptions=True)
|
|
response = client.get("/map/data")
|
|
data = response.json()
|
|
|
|
# Node with only lat should be excluded
|
|
assert len(data["nodes"]) == 0
|