Add wildlife_bp with sightings, stats, frequency, and CSV export endpoints; Bootstrap 5 dark journal template with live-updating summary cards, species bars, time-of-day frequency chart, and paginated/filterable sightings table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
import pytest
|
|
from vigilar.config import VigilarConfig
|
|
from vigilar.storage.queries import insert_wildlife_sighting
|
|
from vigilar.web.app import create_app
|
|
|
|
@pytest.fixture
|
|
def wildlife_app(test_db):
|
|
cfg = VigilarConfig()
|
|
app = create_app(cfg)
|
|
app.config["TESTING"] = True
|
|
app.config["DB_ENGINE"] = test_db
|
|
for i in range(3):
|
|
insert_wildlife_sighting(test_db, species="deer", threat_level="PASSIVE",
|
|
camera_id="front", confidence=0.9)
|
|
insert_wildlife_sighting(test_db, species="bear", threat_level="PREDATOR",
|
|
camera_id="back", confidence=0.95)
|
|
return app
|
|
|
|
def test_wildlife_sightings_api(wildlife_app):
|
|
with wildlife_app.test_client() as c:
|
|
rv = c.get("/wildlife/api/sightings")
|
|
assert rv.status_code == 200
|
|
assert len(rv.get_json()["sightings"]) == 4
|
|
|
|
def test_wildlife_sightings_filter_species(wildlife_app):
|
|
with wildlife_app.test_client() as c:
|
|
rv = c.get("/wildlife/api/sightings?species=bear")
|
|
assert len(rv.get_json()["sightings"]) == 1
|
|
|
|
def test_wildlife_stats_api(wildlife_app):
|
|
with wildlife_app.test_client() as c:
|
|
rv = c.get("/wildlife/api/stats")
|
|
data = rv.get_json()
|
|
assert data["total"] == 4
|
|
assert data["per_species"]["deer"] == 3
|
|
|
|
def test_wildlife_frequency_api(wildlife_app):
|
|
with wildlife_app.test_client() as c:
|
|
rv = c.get("/wildlife/api/frequency")
|
|
assert rv.status_code == 200
|
|
assert len(rv.get_json()) == 6
|
|
|
|
def test_wildlife_export_csv(wildlife_app):
|
|
with wildlife_app.test_client() as c:
|
|
rv = c.get("/wildlife/api/export")
|
|
assert rv.status_code == 200
|
|
assert "text/csv" in rv.content_type
|
|
lines = rv.data.decode().strip().split("\n")
|
|
assert len(lines) == 5 # header + 4 rows
|