"""The business rules, with no database — each test is one sentence a business person would agree to."""
from decimal import Decimal
import pytest
from brick_example.domain.quote import ACCEPTED, SENT, Quote, RuleBroken
def draft() -> Quote:
return Quote(quote_id="Q-1", customer="Acme", owner="alice@shop.example")
def test_the_total_is_exact():
q = draft()
q.add_line("Banner", 3, Decimal("33.33"))
q.add_line("Print", 1, Decimal("0.01"))
assert q.total == Decimal("100.00")
def test_an_empty_quote_cannot_be_sent():
with pytest.raises(RuleBroken, match="empty"):
draft().send()
def test_a_sent_quote_cannot_change():
q = draft()
q.add_line("Banner", 1, Decimal("10"))
q.send()
with pytest.raises(RuleBroken, match="sent quote cannot be changed"):
q.add_line("More", 1, Decimal("1"))
def test_only_a_sent_quote_can_be_accepted():
with pytest.raises(RuleBroken, match="only a sent quote"):
draft().accept()
def test_accepting_twice_changes_nothing():
q = draft()
q.add_line("Banner", 1, Decimal("10"))
q.send()
q.accept()
q.accept()
assert q.status == ACCEPTED
def test_line_numbers_are_never_reused():
q = draft()
q.add_line("A", 1, Decimal("1"))
q.add_line("B", 1, Decimal("1"))
q.remove_line(2)
assert q.add_line("C", 1, Decimal("1")).line_no == 2 and q.status != SENT
def test_a_unique_race_lost_at_commit_is_409_and_any_other_integrity_error_is_not(tmp_path):
"""_on_engine: on DataK3 a racer's duplicate key can surface at COMMIT, after the use case returned. It is the
retry-safe 409, never a 500; a NOT NULL or other integrity failure still raises as itself."""
import pytest
from sqlalchemy import create_engine, text
from sqlalchemy.exc import IntegrityError
from erp_platform.bricks import Refused
from brick_example.application.use_cases import _on_engine
e = create_engine(f"sqlite:///{tmp_path / 'race.db'}")
with e.begin() as c:
c.execute(text("CREATE TABLE claim (k TEXT PRIMARY KEY, v TEXT NOT NULL)"))
c.execute(text("INSERT INTO claim VALUES ('a', 'x')"))
with pytest.raises(Refused) as lost:
with _on_engine(e) as repo:
repo.conn.execute(text("INSERT INTO claim VALUES ('a', 'y')"))
assert lost.value.status == 409
with pytest.raises(IntegrityError):
with _on_engine(e) as repo:
repo.conn.execute(text("INSERT INTO claim VALUES ('b', NULL)"))