Add unit tests for station service and enhance documentation
Some checks failed
Backend CI / lint-and-test (push) Failing after 37s
Some checks failed
Backend CI / lint-and-test (push) Failing after 37s
- Introduced unit tests for the station service, covering creation, updating, and archiving of stations. - Added detailed building block view documentation outlining the architecture of the Rail Game system. - Created runtime view documentation illustrating key user interactions and system behavior. - Developed concepts documentation detailing domain models, architectural patterns, and security considerations. - Updated architecture documentation to reference new detailed sections for building block and runtime views.
This commit is contained in:
137
backend/tests/test_stations_api.py
Normal file
137
backend/tests/test_stations_api.py
Normal file
@@ -0,0 +1,137 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from backend.app.api import stations as stations_api
|
||||
from backend.app.main import app
|
||||
from backend.app.models import StationCreate, StationModel, StationUpdate
|
||||
|
||||
AUTH_CREDENTIALS = {"username": "demo", "password": "railgame123"}
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def _authenticate() -> str:
|
||||
response = client.post("/api/auth/login", json=AUTH_CREDENTIALS)
|
||||
assert response.status_code == 200
|
||||
return response.json()["accessToken"]
|
||||
|
||||
|
||||
def _station_payload(**overrides: Any) -> dict[str, Any]:
|
||||
payload = {
|
||||
"name": "Central",
|
||||
"latitude": 52.52,
|
||||
"longitude": 13.405,
|
||||
"osmId": "123",
|
||||
"code": "BER",
|
||||
"elevationM": 34.5,
|
||||
"isActive": True,
|
||||
}
|
||||
payload.update(overrides)
|
||||
return payload
|
||||
|
||||
|
||||
def _station_model(**overrides: Any) -> StationModel:
|
||||
now = datetime.now(timezone.utc)
|
||||
base = StationModel(
|
||||
id=str(uuid4()),
|
||||
name="Central",
|
||||
latitude=52.52,
|
||||
longitude=13.405,
|
||||
code="BER",
|
||||
osm_id="123",
|
||||
elevation_m=34.5,
|
||||
is_active=True,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
)
|
||||
return base.model_copy(update=overrides)
|
||||
|
||||
|
||||
def test_list_stations_requires_authentication() -> None:
|
||||
response = client.get("/api/stations")
|
||||
assert response.status_code == 401
|
||||
|
||||
|
||||
def test_list_stations_returns_payload(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
token = _authenticate()
|
||||
|
||||
def fake_list_stations(db, include_inactive: bool) -> list[StationModel]:
|
||||
assert include_inactive is True
|
||||
return [_station_model()]
|
||||
|
||||
monkeypatch.setattr(stations_api, "list_stations", fake_list_stations)
|
||||
|
||||
response = client.get(
|
||||
"/api/stations",
|
||||
params={"include_inactive": "true"},
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
payload = response.json()
|
||||
assert len(payload) == 1
|
||||
assert payload[0]["name"] == "Central"
|
||||
|
||||
|
||||
def test_create_station_delegates_to_service(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
token = _authenticate()
|
||||
seen: dict[str, StationCreate] = {}
|
||||
|
||||
def fake_create_station(db, payload: StationCreate) -> StationModel:
|
||||
seen["payload"] = payload
|
||||
return _station_model()
|
||||
|
||||
monkeypatch.setattr(stations_api, "create_station", fake_create_station)
|
||||
|
||||
response = client.post(
|
||||
"/api/stations",
|
||||
json=_station_payload(),
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
assert response.json()["name"] == "Central"
|
||||
assert seen["payload"].name == "Central"
|
||||
|
||||
|
||||
def test_update_station_not_found_returns_404(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
token = _authenticate()
|
||||
|
||||
def fake_update_station(
|
||||
db, station_id: str, payload: StationUpdate
|
||||
) -> StationModel:
|
||||
raise LookupError("Station not found")
|
||||
|
||||
monkeypatch.setattr(stations_api, "update_station", fake_update_station)
|
||||
|
||||
response = client.put(
|
||||
"/api/stations/123e4567-e89b-12d3-a456-426614174000",
|
||||
json={"name": "New Name"},
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
assert response.json()["detail"] == "Station not found"
|
||||
|
||||
|
||||
def test_archive_station_returns_updated_model(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
token = _authenticate()
|
||||
|
||||
def fake_archive_station(db, station_id: str) -> StationModel:
|
||||
return _station_model(is_active=False)
|
||||
|
||||
monkeypatch.setattr(stations_api, "archive_station", fake_archive_station)
|
||||
|
||||
response = client.post(
|
||||
"/api/stations/123e4567-e89b-12d3-a456-426614174000/archive",
|
||||
headers={"Authorization": f"Bearer {token}"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json()["isActive"] is False
|
||||
Reference in New Issue
Block a user