feat(review): #90 wood primary category + derived thickness band
This commit is contained in:
@@ -33,6 +33,23 @@ def _seed_taxonomy(conn):
|
||||
# tags
|
||||
conn.execute("INSERT OR REPLACE INTO woo_tags(id, name, slug, woo_id) VALUES (1, 'Fig Tag A', 'fig-tag-a', 50)")
|
||||
conn.execute("INSERT OR REPLACE INTO woo_tags(id, name, slug, woo_id) VALUES (2, 'Feat Tag A', 'feat-tag-a', 60)")
|
||||
# Thickness bands (METADATA-15 / QUALITY-95) — names exactly as synced from the
|
||||
# live Woo attribute, because the derivation parses them.
|
||||
conn.execute("INSERT OR REPLACE INTO woo_attributes(id, name, slug, woo_id) VALUES (2, 'Thickness', 'pa_thk', 31)")
|
||||
for tid, name, slug in [
|
||||
(347, 'Under 1/2"', 'xthin'),
|
||||
(348, '1/2" - 3/4"', '2-3qtr'),
|
||||
(349, '3/4" - 1"', '3-4qtr'),
|
||||
(350, '1"- 1 1/2"', '4-6qtr'),
|
||||
(351, '1 1/2" - 2"', '6-8qtr'),
|
||||
(352, '2" - 3"', '8-12qtr'),
|
||||
(353, 'Over 3"', '12qtr'),
|
||||
]:
|
||||
conn.execute(
|
||||
"INSERT OR REPLACE INTO woo_attribute_terms(id, attribute_id, name, slug, woo_id) "
|
||||
"VALUES (?, 2, ?, ?, ?)",
|
||||
(tid, name, slug, tid),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
@pytest.fixture
|
||||
@@ -103,6 +120,55 @@ def test_create_and_fetch(client, db):
|
||||
assert body[key] == payload[key]
|
||||
|
||||
|
||||
def test_create_derives_thickness_band(client, db):
|
||||
"""QUALITY-95: 1 in rounds up into the live synced band, not a hardcoded one.
|
||||
|
||||
The client-supplied thickness_term_id (1, an Edge Type term) must be ignored —
|
||||
the UI has no band control, so the server's derivation is authoritative.
|
||||
"""
|
||||
slab_id = str(uuid.uuid4())
|
||||
payload = {
|
||||
"id": slab_id, "sku": "SKU-BAND", "length_in": 10, "thickness_in": 1.0, "sqft": 20,
|
||||
"bdft": 5, "width_min_in": 1, "width_max_in": 2, "width_avg_in": 1.5,
|
||||
"thickness_term_id": 1,
|
||||
}
|
||||
resp = client.post("/api/v1/slabs", json=payload)
|
||||
assert resp.status_code == 201
|
||||
assert resp.json()["thickness_term_id"] == 350 # '1"- 1 1/2"', not the sent 1
|
||||
|
||||
|
||||
def test_update_rebands_when_thickness_changes(client, db):
|
||||
"""A thickness edit moves the slab to the band the new measurement rounds into."""
|
||||
slab_id = str(uuid.uuid4())
|
||||
create = client.post("/api/v1/slabs", json={
|
||||
"id": slab_id, "sku": "SKU-BAND2", "length_in": 10, "thickness_in": 0.5, "sqft": 20,
|
||||
"bdft": 5, "width_min_in": 1, "width_max_in": 2, "width_avg_in": 1.5,
|
||||
})
|
||||
assert create.status_code == 201
|
||||
assert create.json()["thickness_term_id"] == 348 # 1/2" - 3/4"
|
||||
put = client.put(f"/api/v1/slabs/{slab_id}", json={
|
||||
"client_rev": create.json()["server_rev"], "thickness_in": 2.75,
|
||||
})
|
||||
assert put.status_code == 200
|
||||
assert put.json()["thickness_term_id"] == 352 # 2" - 3"
|
||||
|
||||
|
||||
def test_update_ignores_client_supplied_band(client, db):
|
||||
"""A stale client band cannot pin the slab to the wrong band."""
|
||||
slab_id = str(uuid.uuid4())
|
||||
create = client.post("/api/v1/slabs", json={
|
||||
"id": slab_id, "sku": "SKU-BAND3", "length_in": 10, "thickness_in": 1.75, "sqft": 20,
|
||||
"bdft": 5, "width_min_in": 1, "width_max_in": 2, "width_avg_in": 1.5,
|
||||
})
|
||||
assert create.status_code == 201
|
||||
assert create.json()["thickness_term_id"] == 351 # 1 1/2" - 2"
|
||||
put = client.put(f"/api/v1/slabs/{slab_id}", json={
|
||||
"client_rev": create.json()["server_rev"], "thickness_term_id": 347,
|
||||
})
|
||||
assert put.status_code == 200
|
||||
assert put.json()["thickness_term_id"] == 351 # unchanged: still the derived band
|
||||
|
||||
|
||||
def test_duplicate_sku(client, db):
|
||||
slab_id = str(uuid.uuid4())
|
||||
payload = {"id": slab_id, "sku": "SKU001", "length_in":10,"thickness_in":2,"sqft":20,"bdft":5,"width_min_in":1,"width_max_in":2,"width_avg_in":1.5,"species_id":1,"wood_category_ids":json.dumps([2]),"edge_type_term_id":1,"figure_term_ids":json.dumps([1]),"grade_term_id":1,"thickness_term_id":1,"moisture_term_id":1,"fig_tag_ids":json.dumps([1]),"feat_tag_ids":json.dumps([2]),"price":100,"price_source":"recommendation","title":"Test","short_description":"short","description":"desc","content_source":"manual","species_confidence":0.9,"figure_confidence":0.8,"grade_confidence":0.7,"inference_status":"inferring","calibration_photo_id":None}
|
||||
|
||||
Reference in New Issue
Block a user