189 lines
5.3 KiB
Python
189 lines
5.3 KiB
Python
import json
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
from sqlmodel import SQLModel, create_engine, Session
|
|
from sqlalchemy.pool import StaticPool
|
|
from app.main import app
|
|
from app.database import get_session
|
|
from app.models import Dataset, Feature, FeatureVersion, MapSettings # noqa: F401
|
|
|
|
# SQLite in-memory avec StaticPool pour garder la même connexion
|
|
engine = create_engine(
|
|
"sqlite://",
|
|
connect_args={"check_same_thread": False},
|
|
poolclass=StaticPool,
|
|
)
|
|
|
|
|
|
def override_get_session():
|
|
with Session(engine) as session:
|
|
yield session
|
|
|
|
|
|
app.dependency_overrides[get_session] = override_get_session
|
|
client = TestClient(app)
|
|
|
|
SAMPLE_GEOJSON = {
|
|
"type": "FeatureCollection",
|
|
"features": [
|
|
{
|
|
"type": "Feature",
|
|
"geometry": {"type": "Point", "coordinates": [2.35, 48.85]},
|
|
"properties": {"name": "Paris", "description": "Capitale de la France"},
|
|
},
|
|
{
|
|
"type": "Feature",
|
|
"geometry": {"type": "Point", "coordinates": [5.37, 43.30]},
|
|
"properties": {"name": "Marseille"},
|
|
},
|
|
],
|
|
}
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def setup_db():
|
|
SQLModel.metadata.create_all(engine)
|
|
yield
|
|
SQLModel.metadata.drop_all(engine)
|
|
|
|
|
|
def test_health():
|
|
r = client.get("/api/health")
|
|
assert r.status_code == 200
|
|
assert r.json() == {"status": "ok"}
|
|
|
|
|
|
def test_list_datasets_empty():
|
|
r = client.get("/api/datasets")
|
|
assert r.status_code == 200
|
|
assert r.json() == []
|
|
|
|
|
|
def test_import_geojson():
|
|
geojson_str = json.dumps(SAMPLE_GEOJSON)
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": geojson_str},
|
|
files={"file": ("test.geojson", geojson_str.encode(), "application/json")},
|
|
)
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["name"] == "test"
|
|
assert data["feature_count"] == 2
|
|
assert data["id"] is not None
|
|
|
|
|
|
def test_import_invalid_geojson():
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": '{"type": "Point"}'},
|
|
files={"file": ("bad.geojson", b'{"type": "Point"}', "application/json")},
|
|
)
|
|
assert r.status_code == 400
|
|
|
|
|
|
def test_get_dataset():
|
|
geojson_str = json.dumps(SAMPLE_GEOJSON)
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": geojson_str},
|
|
files={"file": ("villes.geojson", geojson_str.encode(), "application/json")},
|
|
)
|
|
ds_id = r.json()["id"]
|
|
|
|
r = client.get(f"/api/datasets/{ds_id}")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["name"] == "villes"
|
|
assert len(data["features"]) == 2
|
|
assert data["features"][0]["properties"]["name"] == "Paris"
|
|
|
|
|
|
def test_update_feature():
|
|
geojson_str = json.dumps(SAMPLE_GEOJSON)
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": geojson_str},
|
|
files={"file": ("test.geojson", geojson_str.encode(), "application/json")},
|
|
)
|
|
ds_id = r.json()["id"]
|
|
|
|
r = client.get(f"/api/datasets/{ds_id}")
|
|
feature_id = r.json()["features"][0]["id"]
|
|
|
|
r = client.put(
|
|
f"/api/features/{feature_id}",
|
|
json={"properties": {"name": "Paris modifié", "description": "Mis à jour"}},
|
|
)
|
|
assert r.status_code == 200
|
|
assert r.json()["version"] == 1
|
|
|
|
r = client.get(f"/api/datasets/{ds_id}")
|
|
f = next(f for f in r.json()["features"] if f["id"] == feature_id)
|
|
assert f["properties"]["name"] == "Paris modifié"
|
|
|
|
|
|
def test_export_dataset():
|
|
geojson_str = json.dumps(SAMPLE_GEOJSON)
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": geojson_str},
|
|
files={"file": ("test.geojson", geojson_str.encode(), "application/json")},
|
|
)
|
|
ds_id = r.json()["id"]
|
|
|
|
r = client.post(f"/api/datasets/{ds_id}/export?format=geojson")
|
|
assert r.status_code == 200
|
|
fc = r.json()
|
|
assert fc["type"] == "FeatureCollection"
|
|
assert len(fc["features"]) == 2
|
|
|
|
|
|
def test_dataset_not_found():
|
|
r = client.get("/api/datasets/9999")
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_feature_not_found():
|
|
r = client.put("/api/features/9999", json={"properties": {"name": "x"}})
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_delete_feature():
|
|
geojson_str = json.dumps(SAMPLE_GEOJSON)
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": geojson_str},
|
|
files={"file": ("test.geojson", geojson_str.encode(), "application/json")},
|
|
)
|
|
ds_id = r.json()["id"]
|
|
r = client.get(f"/api/datasets/{ds_id}")
|
|
feature_id = r.json()["features"][0]["id"]
|
|
|
|
r = client.delete(f"/api/features/{feature_id}")
|
|
assert r.status_code == 200
|
|
assert r.json()["ok"] is True
|
|
|
|
# Vérifier que la feature n'existe plus
|
|
r = client.get(f"/api/datasets/{ds_id}")
|
|
assert len(r.json()["features"]) == 1
|
|
assert r.json()["feature_count"] == 1
|
|
|
|
|
|
def test_delete_dataset():
|
|
geojson_str = json.dumps(SAMPLE_GEOJSON)
|
|
r = client.post(
|
|
"/api/datasets/import",
|
|
data={"geojson": geojson_str},
|
|
files={"file": ("test.geojson", geojson_str.encode(), "application/json")},
|
|
)
|
|
ds_id = r.json()["id"]
|
|
|
|
r = client.delete(f"/api/datasets/{ds_id}")
|
|
assert r.status_code == 200
|
|
assert r.json()["ok"] is True
|
|
|
|
# Vérifier que le dataset n'existe plus
|
|
r = client.get(f"/api/datasets/{ds_id}")
|
|
assert r.status_code == 404
|