feat(Q3): wildlife journal blueprint with API routes and template
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>
This commit is contained in:
49
tests/unit/test_wildlife_api.py
Normal file
49
tests/unit/test_wildlife_api.py
Normal file
@@ -0,0 +1,49 @@
|
||||
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
|
||||
Reference in New Issue
Block a user