refactor(sessions): resolve project ownership through _profiles_match
profile_scoped_project_ids() duplicated the body of the canonical
api/profiles.py::_profiles_match, whose docstring says it was relocated there
precisely so callers stop duplicating it. Call it instead.
Behaviour-identical: both spellings agree on all twelve None / '' / 'default' /
renamed-root / foreign-profile combinations, which the new parametrised test
asserts cell for cell against _profiles_match itself. It is a drift guard, not
a regression test — swapping the call back to a raw
`p.get('profile') == active` comparison reddens seven of its twelve cells.
This commit is contained in:
1 parent
b90d64d9cf
commit
e19c67adde
2 files changed
+57
-8
No files matched your search
+8
-8
@@ -7369,21 +7369,21 @@ def profile_scoped_project_ids() -> frozenset[str]:
|
||||
the row out of "Unassigned" and turn it into a ``default_hidden`` row with no
|
||||
project chip left to reveal it (#6659 review finding 3).
|
||||
|
||||
Profile/alias matching mirrors ``ensure_cron_project`` so the two never
|
||||
disagree about which profile owns a project. Read-only.
|
||||
Profile/alias matching is delegated to ``api.profiles._profiles_match``,
|
||||
the canonical helper every other profile-scoped read already uses, so this
|
||||
set cannot disagree with the rest of the app about which profile owns a
|
||||
project (renamed root, legacy ``'default'`` tag, and a missing ``profile``
|
||||
key are all its business, not ours). Read-only.
|
||||
"""
|
||||
from api.profiles import get_active_profile_name, _is_root_profile
|
||||
from api.profiles import get_active_profile_name, _profiles_match
|
||||
|
||||
active = get_active_profile_name() or 'default'
|
||||
active = get_active_profile_name()
|
||||
resolved: set[str] = set()
|
||||
for p in load_projects():
|
||||
project_id = str(p.get('project_id') or '').strip()
|
||||
if not project_id:
|
||||
continue
|
||||
row_profile = p.get('profile')
|
||||
if row_profile == active or (
|
||||
_is_root_profile(row_profile or 'default') and _is_root_profile(active)
|
||||
):
|
||||
if _profiles_match(p.get('profile'), active):
|
||||
resolved.add(project_id)
|
||||
return frozenset(resolved)
|
||||
|
||||
|
||||
@@ -531,6 +531,55 @@ def test_unresolvable_project_id_leaves_the_session_unassigned(
|
||||
assert by_id["old-live"]["project_id"] == "project-live"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"row_profile, active, expected",
|
||||
[
|
||||
(None, None, True),
|
||||
("", None, True),
|
||||
("default", None, True),
|
||||
(None, "default", True),
|
||||
("", "default", True),
|
||||
("default", "default", True),
|
||||
# Renamed root: the legacy 'default' tag and the display name are the
|
||||
# same profile, in both directions.
|
||||
("kinni", "default", True),
|
||||
("default", "kinni", True),
|
||||
(None, "kinni", True),
|
||||
# Genuinely different profiles never cross.
|
||||
("other", "default", False),
|
||||
("default", "other", False),
|
||||
("other", "other", True),
|
||||
],
|
||||
)
|
||||
def test_profile_scoped_project_ids_uses_the_canonical_profile_match(
|
||||
fake_hermes_home, tmp_path, monkeypatch, row_profile, active, expected
|
||||
):
|
||||
"""Ownership is decided by ``_profiles_match``, not by a local copy of it.
|
||||
|
||||
``api/profiles.py::_profiles_match`` documents that it exists so callers
|
||||
stop duplicating this None/''/'default'/renamed-root matrix. Each row asserts
|
||||
the catalog read agrees with the canonical helper cell for cell, so the two
|
||||
cannot drift apart the way the duplicated body could.
|
||||
"""
|
||||
import api.profiles as profiles
|
||||
|
||||
monkeypatch.setattr(profiles, "get_active_profile_name", lambda: active)
|
||||
monkeypatch.setattr(
|
||||
profiles, "_is_root_profile", lambda name: name in {"default", "kinni"}
|
||||
)
|
||||
(tmp_path / "projects.json").write_text(
|
||||
json.dumps([
|
||||
{"project_id": "p1", "name": "P1", "color": "#000",
|
||||
"profile": row_profile, "created_at": 1.0},
|
||||
]),
|
||||
encoding="utf-8",
|
||||
)
|
||||
models.clear_cli_sessions_cache()
|
||||
|
||||
assert profiles._profiles_match(row_profile, active) is expected
|
||||
assert ("p1" in models.profile_scoped_project_ids()) is expected
|
||||
|
||||
|
||||
def test_unresolvable_project_overflow_is_not_marked_hidden(fake_hermes_home, tmp_path):
|
||||
"""End of the same chain: routes must see None, so no orphan default_hidden."""
|
||||
_register_projects(tmp_path, "project-live")
|
||||
|
||||
Reference in new issue
Block a user