Fix egg sale form: remove duplicate route, change price to euros
All checks were successful
Deploy / deploy (push) Successful in 2m50s
All checks were successful
Deploy / deploy (push) Successful in 2m50s
The egg sale form had two issues: - Duplicate POST /actions/product-sold route in products.py was overwriting the eggs.py handler, causing incomplete page responses (no tabs, no recent sales list) - Price input used cents while feed purchase uses euros, inconsistent UX Changes: - Remove duplicate handler from products.py (keep only redirect) - Change sell form price input from cents to euros (consistent with feed) - Parse euros in handler, convert to cents for storage - Add TestEggSale class with 4 tests for the fixed behavior Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -59,10 +59,10 @@ class TestProductSoldFormRendering:
|
||||
assert 'name="quantity"' in resp.text or 'id="quantity"' in resp.text
|
||||
|
||||
def test_sell_form_has_total_price_field(self, client):
|
||||
"""Form has total_price_cents input field."""
|
||||
"""Form has total_price_euros input field."""
|
||||
resp = client.get("/sell")
|
||||
assert resp.status_code == 200
|
||||
assert 'name="total_price_cents"' in resp.text or 'id="total_price_cents"' in resp.text
|
||||
assert 'name="total_price_euros"' in resp.text or 'id="total_price_euros"' in resp.text
|
||||
|
||||
def test_sell_form_has_buyer_field(self, client):
|
||||
"""Form has optional buyer input field."""
|
||||
@@ -89,7 +89,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "30",
|
||||
"total_price_cents": "1500",
|
||||
"total_price_euros": "15.00",
|
||||
"buyer": "Local Market",
|
||||
"notes": "Weekly sale",
|
||||
"nonce": "test-nonce-sold-1",
|
||||
@@ -113,7 +113,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "30",
|
||||
"total_price_cents": "1500",
|
||||
"total_price_euros": "15.00",
|
||||
"nonce": "test-nonce-sold-2",
|
||||
},
|
||||
)
|
||||
@@ -136,7 +136,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "3",
|
||||
"total_price_cents": "1000",
|
||||
"total_price_euros": "10.00",
|
||||
"nonce": "test-nonce-sold-3",
|
||||
},
|
||||
)
|
||||
@@ -158,7 +158,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "0",
|
||||
"total_price_cents": "1000",
|
||||
"total_price_euros": "10.00",
|
||||
"nonce": "test-nonce-sold-4",
|
||||
},
|
||||
)
|
||||
@@ -172,7 +172,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "-1",
|
||||
"total_price_cents": "1000",
|
||||
"total_price_euros": "10.00",
|
||||
"nonce": "test-nonce-sold-5",
|
||||
},
|
||||
)
|
||||
@@ -186,7 +186,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "10",
|
||||
"total_price_cents": "-100",
|
||||
"total_price_euros": "-1.00",
|
||||
"nonce": "test-nonce-sold-6",
|
||||
},
|
||||
)
|
||||
@@ -199,7 +199,7 @@ class TestProductSold:
|
||||
"/actions/product-sold",
|
||||
data={
|
||||
"quantity": "10",
|
||||
"total_price_cents": "1000",
|
||||
"total_price_euros": "10.00",
|
||||
"nonce": "test-nonce-sold-7",
|
||||
},
|
||||
)
|
||||
@@ -213,30 +213,29 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "invalid.product",
|
||||
"quantity": "10",
|
||||
"total_price_cents": "1000",
|
||||
"total_price_euros": "10.00",
|
||||
"nonce": "test-nonce-sold-8",
|
||||
},
|
||||
)
|
||||
|
||||
assert resp.status_code == 422
|
||||
|
||||
def test_product_sold_success_shows_toast(self, client):
|
||||
"""Successful sale returns response with toast trigger."""
|
||||
def test_product_sold_success_returns_full_page(self, client):
|
||||
"""Successful sale returns full eggs page with tabs."""
|
||||
resp = client.post(
|
||||
"/actions/product-sold",
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "12",
|
||||
"total_price_cents": "600",
|
||||
"total_price_euros": "6.00",
|
||||
"nonce": "test-nonce-sold-9",
|
||||
},
|
||||
)
|
||||
|
||||
assert resp.status_code == 200
|
||||
# Check for HX-Trigger header with showToast
|
||||
hx_trigger = resp.headers.get("HX-Trigger")
|
||||
assert hx_trigger is not None
|
||||
assert "showToast" in hx_trigger
|
||||
# Should return full eggs page with tabs (toast via session)
|
||||
assert "Harvest" in resp.text
|
||||
assert "Sell" in resp.text
|
||||
|
||||
def test_product_sold_optional_buyer(self, client, seeded_db):
|
||||
"""Buyer field is optional."""
|
||||
@@ -245,7 +244,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "10",
|
||||
"total_price_cents": "500",
|
||||
"total_price_euros": "5.00",
|
||||
"nonce": "test-nonce-sold-10",
|
||||
},
|
||||
)
|
||||
@@ -265,7 +264,7 @@ class TestProductSold:
|
||||
data={
|
||||
"product_code": "egg.duck",
|
||||
"quantity": "10",
|
||||
"total_price_cents": "500",
|
||||
"total_price_euros": "5.00",
|
||||
"buyer": "Test Buyer",
|
||||
"nonce": "test-nonce-sold-11",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user