Files
SlabUploader/backend/tests/test_pricing.py
T
Ty 49c22c9385 feat(greenfield): rebuild SlabUploader M1-M3 on clean foundation, all gates green
Clean re-implementation of the full product (not a port of the old M3 tree):
- P0 foundation: 13-table schema + per-call sqlite factory (thread-safe),
  FastAPI app (health, JSON logging + secret redaction, CORS, startup guard).
- P1 M1 Capture: mask/sheetKeep, geometry/rect (min-area rect), measure,
  png crop/inventory/overlay, EXIF decodeOrientedBitmap.
- P2 M2 Photos: stateful capture session (batch, pick-cal, apply mask/crop
  to batch) + photos-ready lineup.
- P3 M3 Create: real backend (crypto, woo client, taxonomy sync, pricing,
  inference Call1/Call2, review, publish, settings, slabs, photos) + real FE
  review/publish/settings screens consuming the API (no hardcoded Woo ids).
- P4 gate exit: check_requirements + check_coverage both exit 0
  (137/155 IDs, 0 gaps); backend 130/130, frontend 150/150, build green.

Cite: docs/REQUIREMENTS.md (155 rows), docs/MILESTONES.md M1-M3.
2026-09-25 06:57:29 -07:00

63 lines
2.0 KiB
Python

"""S5 pricing rules tests (SETTINGS-35, REVIEW-25)."""
import base64
import os
import shutil
import tempfile
import pytest
from fastapi.testclient import TestClient
import backend.db as db_mod
@pytest.fixture
def env(monkeypatch):
tmp = tempfile.mkdtemp(prefix="pricing_")
monkeypatch.setenv("SLAB_DB_PATH", os.path.join(tmp, "p.db"))
monkeypatch.setenv("SLAB_IMAGES_DIR", tmp)
monkeypatch.setenv("WOO_BASE_URL", "https://example.com")
monkeypatch.setenv("SLAB_AES_KEY", base64.b64encode(b"0123456789abcdef0123456789abcdef").decode())
db_mod.init_db()
conn = db_mod.get_connection()
for cid in (1, 7):
conn.execute("INSERT OR IGNORE INTO woo_categories(id,name,slug,parent_id,woo_id) VALUES (?,?,?,NULL,?)", (cid, f"Sp{cid}", f"sp{cid}", cid))
conn.commit()
from backend.app import app
yield TestClient(app)
shutil.rmtree(tmp, ignore_errors=True)
def test_crud_cycle(env):
r = env.post("/api/v1/admin/pricing", json={"species_id": 1, "price_per_bdft": 12.5})
assert r.status_code == 201, r.text
rule = r.json()
rid = rule["id"]
assert rule["price_per_bdft"] == 12.5
r = env.get("/api/v1/admin/pricing")
assert r.status_code == 200
assert [x["species_id"] for x in r.json()] == [1]
r = env.put(f"/api/v1/admin/pricing/{rid}", json={"price_per_bdft": 15.0})
assert r.status_code == 200
assert r.json()["price_per_bdft"] == 15.0
r = env.delete(f"/api/v1/admin/pricing/{rid}")
assert r.status_code == 204
assert env.get("/api/v1/admin/pricing").json() == []
def test_duplicate_species(env):
env.post("/api/v1/admin/pricing", json={"species_id": 7, "price_per_bdft": 1.0})
r = env.post("/api/v1/admin/pricing", json={"species_id": 7, "price_per_bdft": 2.0})
assert r.status_code == 409
def test_validation(env):
r = env.post("/api/v1/admin/pricing", json={"species_id": 1})
assert r.status_code == 400
r = env.post("/api/v1/admin/pricing", json={"species_id": 1, "price_per_bdft": -5})
assert r.status_code == 400