tests/test_campaign_engine.py:18: TemplateSequencer, PhoneSelector, tests/test_security_rotation.py:17: PhoneSelector, tests/test_security_rotation.py:258:class TestPhoneSelector: tests/test_security_rotation.py:261: ps = PhoneSelector(phones, "round_robin") tests/test_security_rotation.py:267: assert PhoneSelector(phones, "fixed").next_phone() == "+15550001" tests/test_security_rotation.py:271: ps = PhoneSelector(phones, "round_robin") tests/test_security_rotation.py:275: assert PhoneSelector([], "round_robin").next_phone() == "" === class TestTemplateSequencer: def test_repeat_mode_cycles(self): tpls = [FakeTemplate(1, "T1"), FakeTemplate(2, "T2")] ts = TemplateSequencer(tpls, "repeat") got = [ts.next_template().id for _ in range(5)] assert got == [1, 2, 1, 2, 1] assert ts.stopped is False def test_stop_mode_halts(self): tpls = [FakeTemplate(1, "T1"), FakeTemplate(2, "T2")] ts = TemplateSequencer(tpls, "stop") assert ts.next_template().id == 1 assert ts.next_template().id == 2 assert ts.next_template() is None assert ts.stopped is True def test_random_mode(self): tpls = [FakeTemplate(i, f"T{i}") for i in range(1, 6)] ts = TemplateSequencer(tpls, "random") got = {ts.next_template().id for _ in range(50)} assert len(got) > 1 def test_empty(self): assert TemplateSequencer([], "repeat").next_template() is None class TestPhoneSelector: def test_round_robin(self): phones = [FakePhone(1, "+15550001"), FakePhone(2, "+15550002")] ps = PhoneSelector(phones, "round_robin") got = [ps.next_phone() for _ in range(4)] assert got == ["+15550001", "+15550002", "+15550001", "+15550002"] def test_fixed(self): phones = [FakePhone(1, "+15550001"), FakePhone(2, "+15550002")] assert PhoneSelector(phones, "fixed").next_phone() == "+15550001" def test_inactive_excluded(self): phones = [FakePhone(1, "+15550001", active=False), FakePhone(2, "+15550002")] ps = PhoneSelector(phones, "round_robin") assert all(p == "+15550002" for _ in range(3) for p in [ps.next_phone()]) def test_empty_returns_blank(self): assert PhoneSelector([], "round_robin").next_phone() == ""