"""The canonical-slug matcher — the line between what maps mechanically and what a human is asked to confirm (milestone 307, note 3026). These cases are the real drift found across the author's own instance: one area carrying three spellings, and two areas that LOOK alike and are not the same. Getting the boundary wrong in either direction is a silent failure — a missed mapping nobody thinks to make again, or a cross-project record surfacing in the wrong project. """ import pytest from scribe.services.canonical_systems import canonical_slug @pytest.mark.parametrize("name", ["CI & Release", "CI and Release", "CI & release", " ci and release "]) def test_spelling_variants_of_one_area_collapse_to_one_key(name): """Case, spacing, punctuation and "&" vs "and" are not real differences. All three of the first spellings were live in different projects at once.""" assert canonical_slug(name) == "ci-and-release" @pytest.mark.parametrize("name,expected", [ ("Auth & Access", "auth-and-access"), ("Data Model & Storage", "data-model-and-storage"), ("UI & Design", "ui-and-design"), ("Background Jobs", "background-jobs"), ("Observability", "observability"), ]) def test_the_seeded_vocabulary_slugs_match_the_migration(name, expected): """Migration 0087 writes these slugs literally. If the function and the migration disagree, every seeded entry becomes unreachable by exact match and every mapping silently degrades to a proposal.""" assert canonical_slug(name) == expected @pytest.mark.parametrize("a,b", [ ("CI & Release", "CI & runners"), ("Auth & Access", "Auth & Accounts"), ("UI & Design", "Frontend (Vue app)"), ("UI & Design", "Web Shell and Theme"), ]) def test_genuinely_different_names_do_not_collapse(a, b): """These pairs may or may not be the same area — that is a judgment call, so they must NOT map automatically. They reach the operator as proposals.""" assert canonical_slug(a) != canonical_slug(b) def test_a_nameless_system_yields_no_key(): """An empty slug is the one value callers must special-case: two unnameable Systems must not map onto each other. Both propose_mappings and find_by_name bail on a falsy slug for this reason.""" assert canonical_slug("") == "" assert canonical_slug(" ") == "" assert canonical_slug("---") == "" def test_a_punctuation_separator_is_not_read_as_the_word_and(): """"CI/Release" is a real spelling and it does NOT collapse onto "CI & Release" — only "&" carries that meaning. It still reaches the operator through the overlap path, where both words match; what it must not do is map itself silently.""" assert canonical_slug("CI/Release") == "ci-release" assert canonical_slug("CI/Release") != canonical_slug("CI & Release")