"""Unit tests for the deterministic half of referral_service: code generation, normalisation, and lookup helpers. DB-backed linkage logic is exercised manually via the dev container.""" from __future__ import annotations import pytest from app.services.referral_service import ( _ALPHABET, _CODE_LEN, generate_code, normalise_code, ) # --------------------------------------------------------------------------- # Code generation # --------------------------------------------------------------------------- def test_generate_code_length(): code = generate_code() assert len(code) == _CODE_LEN def test_generate_code_alphabet(): """Every character must come from the unambiguous alphabet.""" for _ in range(50): code = generate_code() for ch in code: assert ch in _ALPHABET, f"unexpected char {ch!r} in {code!r}" def test_generate_code_no_ambiguous_chars(): """0, O, 1, I, L are excluded to avoid dictation errors.""" for _ in range(200): code = generate_code() assert not (set(code) & set("01IOL")) def test_generate_code_diversity(): """Two consecutive generations should almost never collide (sanity check on the RNG).""" a, b = generate_code(), generate_code() assert a != b # --------------------------------------------------------------------------- # normalise_code # --------------------------------------------------------------------------- def test_normalise_uppercases(): assert normalise_code("abcdefgh") == "ABCDEFGH" def test_normalise_strips_disallowed_chars(): """Users may paste with spaces / dashes / quotes — strip those.""" assert normalise_code(" ABCD-EFGH ") == "ABCDEFGH" assert normalise_code('"ABCDEFGH"') == "ABCDEFGH" def test_normalise_rejects_wrong_length(): """If too short / too long after cleaning, return None — bogus.""" assert normalise_code("ABC") is None assert normalise_code("ABCDEFGHX") is None # Long enough but ambiguous chars stripped → still wrong length: assert normalise_code("ABCDEFG0") is None # 0 stripped → 7 chars def test_normalise_rejects_none_and_empty(): assert normalise_code(None) is None assert normalise_code("") is None assert normalise_code(" ") is None def test_normalise_preserves_valid_code(): """A code that's already canonical should pass through unchanged.""" code = generate_code() assert normalise_code(code) == code