130:def _async_materialize(db_engine, campaign, recipient_rows, **kw): 149: return asyncio.run(runner()) 155:class TestMaterializeCampaign: 156: def test_materializes_all_recipients_with_generated_values(self, db_engine): 174: def test_invoice_numbers_unique_per_campaign(self, db_engine): 186: def test_invoice_numbers_unique_across_materialize_calls(self, db_engine): 203: def test_preview_does_not_persist(self, db_engine): 217: def test_preview_size_defaults_to_campaign_setting(self, db_engine): 225: def test_no_accounts_marks_skipped(self, db_engine): 237: def test_template_stop_mode_marks_remaining_skipped(self, db_engine): 250: def test_subject_assignment_round_robin(self, db_engine): 260: def test_phone_assignment_round_robin(self, db_engine): 269: def test_account_rotation_sequential(self, db_engine): 278: def test_max_per_account_respected_in_plan(self, db_engine): 293: def test_account_in_cooldown_skipped(self, db_engine): 307: def test_amount_shipping_disabled_by_config(self, db_engine): 321: def test_dates_from_config(self, db_engine): 335: def test_persists_campaign_recipients(self, db_engine): 350: def test_only_valid_recipients_flow(self, db_engine): 367: def test_multiple_campaigns_independent_plans(self, db_engine): 382: def test_plan_warnings_for_skipped_rows(self, db_engine): 397:class TestGetCampaignEntities: 398: def test_loads_all_entities(self, db_engine): 410: subs, tpls, phones, accs = asyncio.run(runner()) 416: def test_drops_unauthorized_accounts_and_inactive_phones(self, db_engine): 442: subs2, tpls2, phones2, accs2 = asyncio.run(runner()) 446: def test_missing_ids_resolved_honestly(self, db_engine): 462: subs, tpls, _, _ = asyncio.run(runner())