Add pets web blueprint with API endpoints
Implements all /pets/* routes (register, status, sightings, wildlife, unlabeled crops, label, upload, update, delete, train, training-status, highlights), registers the blueprint in app.py, adds a placeholder dashboard template, and covers the API with 11 passing unit tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
109
tests/unit/test_pets_api.py
Normal file
109
tests/unit/test_pets_api.py
Normal file
@@ -0,0 +1,109 @@
|
||||
"""Tests for pets web blueprint API endpoints."""
|
||||
|
||||
import pytest
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
from vigilar.config import VigilarConfig
|
||||
from vigilar.storage.schema import metadata
|
||||
from vigilar.web.app import create_app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(tmp_path):
|
||||
"""Flask test client wired to an in-memory test DB."""
|
||||
db_path = tmp_path / "pets_test.db"
|
||||
engine = create_engine(f"sqlite:///{db_path}", echo=False)
|
||||
metadata.create_all(engine)
|
||||
|
||||
cfg = VigilarConfig()
|
||||
app = create_app(cfg)
|
||||
app.config["DB_ENGINE"] = engine
|
||||
app.config["TESTING"] = True
|
||||
|
||||
with app.test_client() as c:
|
||||
yield c
|
||||
|
||||
|
||||
class TestPetsAPI:
|
||||
def test_register_pet(self, client):
|
||||
resp = client.post("/pets/register", json={
|
||||
"name": "Angel", "species": "cat", "breed": "DSH",
|
||||
"color_description": "black",
|
||||
})
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert data["name"] == "Angel"
|
||||
assert "id" in data
|
||||
|
||||
def test_get_pet_status(self, client):
|
||||
client.post("/pets/register", json={"name": "Angel", "species": "cat"})
|
||||
resp = client.get("/pets/api/status")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert len(data["pets"]) == 1
|
||||
assert data["pets"][0]["name"] == "Angel"
|
||||
|
||||
def test_get_sightings_empty(self, client):
|
||||
resp = client.get("/pets/api/sightings")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert data["sightings"] == []
|
||||
|
||||
def test_get_wildlife_empty(self, client):
|
||||
resp = client.get("/pets/api/wildlife")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert data["sightings"] == []
|
||||
|
||||
def test_get_unlabeled_empty(self, client):
|
||||
resp = client.get("/pets/api/unlabeled")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert data["crops"] == []
|
||||
|
||||
def test_pets_dashboard_loads(self, client):
|
||||
resp = client.get("/pets/")
|
||||
assert resp.status_code == 200
|
||||
|
||||
def test_register_pet_missing_fields(self, client):
|
||||
resp = client.post("/pets/register", json={"name": "Buddy"})
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_label_crop(self, client):
|
||||
# Register a pet first
|
||||
reg = client.post("/pets/register", json={"name": "Angel", "species": "cat"})
|
||||
pet_id = reg.get_json()["id"]
|
||||
|
||||
# Insert an unlabeled sighting directly via DB
|
||||
|
||||
from vigilar.storage.queries import insert_pet_sighting
|
||||
app_engine = client.application.config["DB_ENGINE"]
|
||||
sighting_id = insert_pet_sighting(app_engine, species="cat", camera_id="cam1",
|
||||
confidence=0.9)
|
||||
|
||||
resp = client.post(f"/pets/{sighting_id}/label", json={"pet_id": pet_id})
|
||||
assert resp.status_code == 200
|
||||
assert resp.get_json()["ok"] is True
|
||||
|
||||
def test_delete_pet(self, client):
|
||||
reg = client.post("/pets/register", json={"name": "Ghost", "species": "cat"})
|
||||
pet_id = reg.get_json()["id"]
|
||||
|
||||
resp = client.delete(f"/pets/{pet_id}/delete")
|
||||
assert resp.status_code == 200
|
||||
assert resp.get_json()["ok"] is True
|
||||
|
||||
status = client.get("/pets/api/status").get_json()
|
||||
assert len(status["pets"]) == 0
|
||||
|
||||
def test_training_status(self, client):
|
||||
resp = client.get("/pets/api/training-status")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert "status" in data
|
||||
|
||||
def test_highlights(self, client):
|
||||
resp = client.get("/pets/api/highlights")
|
||||
assert resp.status_code == 200
|
||||
data = resp.get_json()
|
||||
assert "highlights" in data
|
||||
Reference in New Issue
Block a user