def test_invoice_numbers_unique_across_materialize_calls(self, db_engine): """Same campaign materialized twice (draft re-preview) — the collision set is per call, but DB uniqueness per campaign holds because rows are regenerated. Verified: two calls with the same recipient set produce distinct plans and both unique sets.""" from sqlalchemy.orm import Session with Session(db_engine, expire_on_commit=False) as db: f = _seed_fixture(db, n_recipients=8) recs = db.query(Recipient).filter_by(list_id=f["campaign"].recipient_list_id).all() res1 = _async_materialize(db_engine, f["campaign"], recs, preview=True) res2 = _async_materialize(db_engine, f["campaign"], recs, preview=True) invs1 = {r.generated_invoice_number for r in res1["rows"]} invs2 = {r.generated_invoice_number for r in res2["rows"]} assert len(invs1) == 8 and len(invs2) == 8 # each call unique internally assert len({p["invoice_number"] for p in res1["plan"]}) == 8 def test_preview_does_not_persist(self, db_engine): from sqlalchemy.orm import Session from app.models import CampaignRecipient with Session(db_engine, expire_on_commit=False) as db: f = _seed_fixture(db, n_recipients=10) recs = db.query(Recipient).filter_by(list_id=f["list"].id).all() res = _async_materialize(db_engine, f["campaign"], recs, preview=True, preview_size=3) # in-session count: nothing persisted from preview n_before = db.query(CampaignRecipient).filter_by( campaign_id=f["campaign"].id).count() assert res["total"] == 3 # preview_size respected assert n_before == 0 def test_preview_size_defaults_to_campaign_setting(self, db_engine): from sqlalchemy.orm import Session with Session(db_engine, expire_on_commit=False) as db: f = _seed_fixture(db, n_recipients=10, preview_sample_size=4) recs = db.query(Recipient).filter_by(list_id=f["list"].id).all() res = _async_materialize(db_engine, f["campaign"], recs, preview=True) assert res["total"] == 4 def test_no_accounts_marks_skipped(self, db_engine): from sqlalchemy.orm import Session with Session(db_engine, expire_on_commit=False) as db: f = _seed_fixture(db, n_recipients=3, account_status="expired") recs = db.query(Recipient).filter_by(list_id=f["list"].id).all() res = _async_materialize(db_engine, f["campaign"], recs) assert res["total"] == 3 assert res["queued"] == 0 assert all(r.status == "skipped" for r in res["rows"]) assert all(r.assigned_account_id is None for r in res["rows"]) assert all("No available sender account" in r.last_error for r in res["rows"])