This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/geo-service/tests/test_tiles.py
Benjamin Admin bfdaf63ba9 fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

284 lines
9.7 KiB
Python

"""
Tests for Tile Server API
"""
import pytest
from fastapi.testclient import TestClient
from unittest.mock import patch, MagicMock
# Import app after mocking to avoid import errors
import sys
sys.path.insert(0, '/app')
@pytest.fixture
def client():
"""Create test client."""
from main import app
return TestClient(app)
class TestTileEndpoints:
"""Tests for tile server endpoints."""
def test_health_check(self, client):
"""Test health check endpoint returns healthy status."""
response = client.get("/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "healthy"
assert data["service"] == "geo-service"
assert "data_status" in data
def test_root_endpoint(self, client):
"""Test root endpoint returns service info."""
response = client.get("/")
assert response.status_code == 200
data = response.json()
assert data["service"] == "GeoEdu Service"
assert "endpoints" in data
assert "attribution" in data
def test_tile_metadata(self, client):
"""Test tile metadata endpoint."""
response = client.get("/api/v1/tiles/metadata")
assert response.status_code == 200
data = response.json()
assert "name" in data
assert "minzoom" in data
assert "maxzoom" in data
assert "bounds" in data
assert data["attribution"] == "© OpenStreetMap contributors (ODbL)"
def test_tile_bounds(self, client):
"""Test tile bounds endpoint returns Germany bounds."""
response = client.get("/api/v1/tiles/bounds")
assert response.status_code == 200
data = response.json()
assert "bounds" in data
# Germany approximate bounds
bounds = data["bounds"]
assert bounds[0] < 6 # west
assert bounds[1] > 47 # south
assert bounds[2] > 14 # east
assert bounds[3] < 56 # north
def test_style_json(self, client):
"""Test MapLibre style endpoint."""
response = client.get("/api/v1/tiles/style.json")
assert response.status_code == 200
data = response.json()
assert data["version"] == 8
assert "sources" in data
assert "layers" in data
assert "osm" in data["sources"]
def test_tile_request_without_data(self, client):
"""Test tile request returns 503 when data not available."""
response = client.get("/api/v1/tiles/0/0/0.pbf")
# Should return 503 (data not available) or 204 (empty tile)
assert response.status_code in [204, 503]
def test_tile_request_invalid_zoom(self, client):
"""Test tile request with invalid zoom level."""
response = client.get("/api/v1/tiles/25/0/0.pbf")
assert response.status_code == 422 # Validation error
class TestTerrainEndpoints:
"""Tests for terrain/DEM endpoints."""
def test_terrain_metadata(self, client):
"""Test terrain metadata endpoint."""
response = client.get("/api/v1/terrain/metadata")
assert response.status_code == 200
data = response.json()
assert data["name"] == "Copernicus DEM GLO-30"
assert data["resolution_m"] == 30
assert "bounds" in data
def test_heightmap_request_without_data(self, client):
"""Test heightmap request returns appropriate status when no data."""
response = client.get("/api/v1/terrain/10/500/500.png")
# Should return 204 (no content) or 503 (data not available)
assert response.status_code in [204, 503]
def test_elevation_at_point_within_germany(self, client):
"""Test elevation endpoint with valid Germany coordinates."""
# Berlin coordinates
response = client.get("/api/v1/terrain/elevation?lat=52.52&lon=13.405")
# Should return 404 (no data) or 200 (with elevation) or 503
assert response.status_code in [200, 404, 503]
def test_elevation_at_point_outside_germany(self, client):
"""Test elevation endpoint with coordinates outside Germany."""
# Paris coordinates (outside Germany)
response = client.get("/api/v1/terrain/elevation?lat=48.8566&lon=2.3522")
# Should return 422 (validation error - outside bounds)
assert response.status_code == 422
class TestAOIEndpoints:
"""Tests for AOI (Area of Interest) endpoints."""
def test_validate_polygon_valid(self, client):
"""Test polygon validation with valid polygon."""
polygon = {
"type": "Polygon",
"coordinates": [
[
[9.19, 47.71],
[9.20, 47.71],
[9.20, 47.70],
[9.19, 47.70],
[9.19, 47.71],
]
],
}
response = client.post("/api/v1/aoi/validate", json=polygon)
assert response.status_code == 200
data = response.json()
assert "valid" in data
assert "area_km2" in data
assert "within_germany" in data
def test_validate_polygon_too_large(self, client):
"""Test polygon validation with too large area."""
# Large polygon (> 4 km²)
polygon = {
"type": "Polygon",
"coordinates": [
[
[9.0, 47.5],
[9.5, 47.5],
[9.5, 48.0],
[9.0, 48.0],
[9.0, 47.5],
]
],
}
response = client.post("/api/v1/aoi/validate", json=polygon)
assert response.status_code == 200
data = response.json()
assert data["within_size_limit"] == False
def test_validate_polygon_outside_germany(self, client):
"""Test polygon validation outside Germany."""
# Paris area
polygon = {
"type": "Polygon",
"coordinates": [
[
[2.3, 48.8],
[2.4, 48.8],
[2.4, 48.9],
[2.3, 48.9],
[2.3, 48.8],
]
],
}
response = client.post("/api/v1/aoi/validate", json=polygon)
assert response.status_code == 200
data = response.json()
assert data["within_germany"] == False
def test_mainau_template(self, client):
"""Test Mainau demo template endpoint."""
response = client.get("/api/v1/aoi/templates/mainau")
assert response.status_code == 200
data = response.json()
assert data["name"] == "Insel Mainau"
assert "polygon" in data
assert "center" in data
assert "suggested_themes" in data
def test_create_aoi(self, client):
"""Test AOI creation with valid polygon."""
request = {
"polygon": {
"type": "Polygon",
"coordinates": [
[
[9.1875, 47.7055],
[9.1975, 47.7055],
[9.1975, 47.7115],
[9.1875, 47.7115],
[9.1875, 47.7055],
]
],
},
"theme": "topographie",
"quality": "medium",
}
response = client.post("/api/v1/aoi", json=request)
assert response.status_code == 200
data = response.json()
assert "aoi_id" in data
assert data["status"] == "queued"
assert "area_km2" in data
def test_create_aoi_too_large(self, client):
"""Test AOI creation fails with too large area."""
request = {
"polygon": {
"type": "Polygon",
"coordinates": [
[
[9.0, 47.5],
[9.5, 47.5],
[9.5, 48.0],
[9.0, 48.0],
[9.0, 47.5],
]
],
},
"theme": "topographie",
"quality": "medium",
}
response = client.post("/api/v1/aoi", json=request)
assert response.status_code == 400
def test_get_nonexistent_aoi(self, client):
"""Test getting non-existent AOI returns 404."""
response = client.get("/api/v1/aoi/nonexistent-id")
assert response.status_code == 404
class TestLearningEndpoints:
"""Tests for Learning Nodes endpoints."""
def test_learning_templates(self, client):
"""Test learning templates endpoint."""
response = client.get("/api/v1/learning/templates")
assert response.status_code == 200
data = response.json()
assert "themes" in data
assert "difficulties" in data
assert len(data["themes"]) == 6 # 6 themes
# Check theme structure
theme = data["themes"][0]
assert "id" in theme
assert "name" in theme
assert "description" in theme
assert "example_questions" in theme
def test_learning_statistics(self, client):
"""Test learning statistics endpoint."""
response = client.get("/api/v1/learning/statistics")
assert response.status_code == 200
data = response.json()
assert "total_nodes_generated" in data
assert "nodes_by_theme" in data
def test_generate_nodes_without_aoi(self, client):
"""Test node generation fails without valid AOI."""
request = {
"aoi_id": "nonexistent-aoi",
"theme": "topographie",
"difficulty": "mittel",
"node_count": 5,
}
response = client.post("/api/v1/learning/generate", json=request)
# Should return 404 (AOI not found) or 503 (Ollama not available)
assert response.status_code in [404, 503]