Model/tests/domain/abri/test_phone_selection.py
Daniel Roth 06354a166e Phone-number selection policy lives in the domain layer 🟪
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:47:37 +00:00

140 lines
3.5 KiB
Python

from typing import Optional
from domain.abri.phone_selection import (
PhoneEntry,
SelectedPhoneNumbers,
select_phone_numbers,
)
def _mobile(number: str, priority: Optional[str] = None) -> PhoneEntry:
return PhoneEntry(kind="mobile", number=number, priority=priority)
def _telephone(number: str, priority: Optional[str] = None) -> PhoneEntry:
return PhoneEntry(kind="telephone", number=number, priority=priority)
def test_no_entries_selects_nothing() -> None:
assert select_phone_numbers([]) == SelectedPhoneNumbers(
mobile=None, telephone=None, secondary=None
)
def test_lowest_numeric_priority_wins_within_a_kind() -> None:
# Arrange
entries = [
_mobile("07700900020", priority="20"),
_mobile("07700900005", priority="5"),
_mobile("07700900010", priority="10"),
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected.mobile == "07700900005"
def test_entries_without_a_usable_priority_sort_last() -> None:
# Arrange
entries = [
_mobile("07700900001"), # missing priority
_mobile("07700900002", priority="abc"), # non-numeric priority
_mobile("07700900003", priority="99"),
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected.mobile == "07700900003"
def test_priority_ties_break_by_document_order() -> None:
# Arrange
entries = [
_telephone("01632960001", priority="7"),
_telephone("01632960002", priority="7"),
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected.telephone == "01632960001"
def test_blank_numbers_are_ignored_even_at_best_priority() -> None:
# Arrange
entries = [
_mobile(" ", priority="1"),
_mobile("07700900002", priority="2"),
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected == SelectedPhoneNumbers(
mobile="07700900002", telephone=None, secondary=None
)
def test_secondary_is_the_best_of_the_pooled_leftovers_of_both_kinds() -> None:
# Arrange
entries = [
_mobile("07700900005", priority="5"), # best mobile
_mobile("07700900020", priority="20"), # leftover
_telephone("01632960003", priority="3"), # best landline
_telephone("01632960007", priority="7"), # best leftover: wins secondary
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected == SelectedPhoneNumbers(
mobile="07700900005", telephone="01632960003", secondary="01632960007"
)
def test_no_secondary_when_the_best_picks_use_every_number() -> None:
# Arrange
entries = [
_mobile("07700900005", priority="5"),
_telephone("01632960003", priority="3"),
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected.secondary is None
def test_a_single_kind_still_yields_a_secondary_from_its_own_leftovers() -> None:
# Arrange
entries = [
_telephone("01632960001", priority="1"),
_telephone("01632960002", priority="2"),
]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected == SelectedPhoneNumbers(
mobile=None, telephone="01632960001", secondary="01632960002"
)
def test_selected_numbers_are_stripped_of_surrounding_whitespace() -> None:
# Arrange
entries = [_mobile(" 07700900123 ", priority="1")]
# Act
selected = select_phone_numbers(entries)
# Assert
assert selected.mobile == "07700900123"