bookmark/tests/test_api.py

83 lines
2.6 KiB
Python

import numpy as np
from fastapi.testclient import TestClient
from bookmark.capture_strategies.manual_button import ManualButtonStrategy
from bookmark.catalogue import Catalogue
from bookmark.main import create_app
from bookmark.session import IntakeSession
from bookmark.sizing import MarkerRegion
def make_reference(size=100, color=200):
return np.full((size, size, 3), color, dtype=np.uint8)
def make_book_frame(size=100, ref_color=200, book_color=50, box=(20, 20, 40, 40)):
frame = np.full((size, size, 3), ref_color, dtype=np.uint8)
x, y, w, h = box
frame[y:y + h, x:x + w] = book_color
return frame
class FakeCamera:
def __init__(self, frame: np.ndarray) -> None:
self.frame = frame
def read_frame(self) -> np.ndarray:
return self.frame
def make_client(tmp_path):
catalogue = Catalogue(tmp_path / "catalogue.csv")
strategy = ManualButtonStrategy()
reference = make_reference()
markers = [MarkerRegion(name="small_boundary", bucket="small", x=0, y=0, width=10, height=10)]
session = IntakeSession(
catalogue=catalogue,
strategy=strategy,
reference_frame=reference,
markers=markers,
captures_dir=tmp_path / "captures",
)
camera = FakeCamera(reference)
app = create_app(session, camera)
return TestClient(app), session, camera
def test_session_state_starts_waiting_front(tmp_path):
client, _, _ = make_client(tmp_path)
response = client.get("/api/session-state")
assert response.status_code == 200
assert response.json()["state"] == "waiting_front"
def test_observe_without_trigger_does_not_fire(tmp_path):
client, _, _ = make_client(tmp_path)
response = client.post("/api/observe")
assert response.status_code == 200
assert response.json()["fired"] is False
def test_manual_trigger_then_observe_captures_front(tmp_path):
client, _, camera = make_client(tmp_path)
camera.frame = make_book_frame()
client.post("/api/manual-trigger")
response = client.post("/api/observe")
body = response.json()
assert body["fired"] is True
assert body["state"] == "waiting_back"
assert body["book_id"] is not None
def test_preview_returns_404_before_any_observe(tmp_path):
client, _, _ = make_client(tmp_path)
response = client.get("/api/preview.jpg")
assert response.status_code == 404
def test_preview_returns_jpeg_after_observe(tmp_path):
client, _, _ = make_client(tmp_path)
client.post("/api/observe")
response = client.get("/api/preview.jpg")
assert response.status_code == 200
assert response.headers["content-type"] == "image/jpeg"