Files
AIPass/src/commons/tests/test_identity.py
T
f19f7ac12d feat: system-wide compliance push + 896 tests across 10 branches (#124)
* feat(seedgo): deep nesting bypasses, dead code cleanup, json structure compliance

Co-Authored-By: @seedgo <seedgo@aipass>

* feat(memory): seedgo certification: introspection fixes, subprocess bypasses, silent catch cleanup

Co-Authored-By: @memory <memory@aipass>

* feat(api): seedgo certification: 94%→97%, 31/33 standards at 100%

Co-Authored-By: @api <api@aipass>

* feat(seedgo): deep nesting 100%, limit 3→4, checker refactors, @ validation, bypass cleanup

Co-Authored-By: @seedgo <seedgo@aipass>

* feat: seedgo cert sprint — 10 branches dispatched, drone introspection rebuilt, system-wide compliance push

Session 49-50 cert sprint results:
- drone: introspection rebuilt (proper auto-discovery), silent_catch 92%→100%, overall 97%
- api: 94%→97%, json_handler fixed, PR #116
- backup: 93%→94%, json_handler load_template→inline
- memory: 88%→91%, introspection 79%→100%, 10 bypasses for subprocess files
- skills: 97%, json_structure→100%, introspection→100%
- spawn: 97%→99%, 32/34 standards at 100%
- ai_mail: 95%→97%, 12 unused functions removed, 32/34 at 100%
- seedgo: checker improvements (deep_nesting threshold 3→4, various fixes)
- drone: removed from _MODULE_REGISTRY (DPLAN-0053 consensus)
- commons: introspection bypasses (22 entries), python3→drone refs fixed
- trigger/cli/prax/daemon/flow/backup: various cert fixes

New DPLANs: 0053 (drone audit), 0054 (bypass tracker), 0055 (persistent git branches)
New FPLAN: 0134 (persistent citizen git branches — drone build)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(seedgo): audit display dynamic rendering, 176 unit tests, test coverage 6→93%

Co-Authored-By: @seedgo <seedgo@aipass>

* feat(memory): seedgo compliance: 92% → 96%, fixes + 70 bypasses

Co-Authored-By: @memory <memory@aipass>

* feat: night shift — compliance push, drone persistent branches + module routing, dead code cleanup

Autonomous night shift (DPLAN-0057). System avg 93% → 96%, all 14 branches 95%+.

Drone: persistent citizen/{name} branches (FPLAN-0134), module routing fix (FPLAN-0136),
19 logger.info→console.print across 6 modules, @ enforcement hints.

Compliance: backup 94→95%, daemon 94→95%, flow 93→96%, prax 94→96%, trigger 93→96%.
Prax: 27 dead functions removed, monitoring cleanup. Flow: dead code removal, bypass.json.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat(memory): unit tests: 194 tests, 7 test files, 43% module coverage

Co-Authored-By: @memory <memory@aipass>

* feat(api): unit tests: 117 tests, 5 test files, 40% module coverage (3-round audit)

Co-Authored-By: @api <api@aipass>

* feat: system-wide compliance push + 896 tests across 10 branches

S51-S52 accumulated work:
- Stale cleanup: flow dead code removed (write_plan_outputs.py, 139 lines from process.py), trimmed command_parser/display/registry_ops
- Daemon refactor: scheduler_cron.py split (920→388 lines), new action_processor + plugin_processor handlers
- Seedgo checker fixes: architecture_check, json_structure_check, silent_catch_check, unused_function_check improved
- Seedgo cleanup: mock_standard_1 removed, bypass.py removed, bypass_handler trimmed
- Compliance: bypass.json updates across 8 branches, pytest.ini + conftest.py standardized
- Test dispatch: 46 new test files across ai_mail(4), backup(11), cli(4), daemon(4), flow(6), prax(6), trigger(4), commons(6)
- Small fixes: drone lock_handler, json_handlers, prax operations/event_queue, commons writers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: @seedgo <seedgo@aipass>
Co-authored-by: @memory <memory@aipass>
Co-authored-by: @api <api@aipass>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 21:57:54 -07:00

221 lines
7.6 KiB
Python

# ===================AIPASS====================
# META DATA HEADER
# Name: test_identity.py - Identity Module Unit Tests
# Date: 2026-03-24
# Version: 1.0.0
# Category: commons/tests
#
# CHANGELOG (Max 5 entries):
# - v1.0.0 (2026-03-24): Initial creation — 14 unit tests
#
# CODE STANDARDS:
# - Pytest function style (no unittest classes)
# - Mock heavy deps (prax logger, database)
# - Tests extract_mentions, find_branch_root, resolve_display_name
# =============================================
"""
Unit tests for the commons identity module and identity_ops handler.
Tests extract_mentions (pure regex), find_branch_root (filesystem walk),
resolve_display_name, and DB-backed mention validation.
"""
import sqlite3
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
# Mock the prax logger before importing the modules under test
import sys
_mock_logger = MagicMock()
_mock_logger_module = MagicMock()
_mock_logger_module.system_logger = _mock_logger
try:
from aipass.prax.apps.modules.logger import system_logger # noqa: F401
except ImportError:
sys.modules.setdefault("aipass.prax", MagicMock())
sys.modules.setdefault("aipass.prax.apps", MagicMock())
sys.modules.setdefault("aipass.prax.apps.modules", MagicMock())
sys.modules.setdefault("aipass.prax.apps.modules.logger", _mock_logger_module)
# Mock CLI console too — commons_identity imports it
try:
from aipass.cli.apps.modules import console # noqa: F401
except ImportError:
_mock_cli = MagicMock()
sys.modules.setdefault("aipass.cli", _mock_cli)
sys.modules.setdefault("aipass.cli.apps", MagicMock())
sys.modules.setdefault("aipass.cli.apps.modules", MagicMock())
from commons.apps.modules.commons_identity import extract_mentions
from commons.apps.handlers.identity.identity_ops import (
find_branch_root,
resolve_display_name,
)
import commons.apps.handlers.identity.identity_ops as identity_ops_mod
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
@pytest.fixture(autouse=True)
def _patch_db_for_mentions(initialized_db: sqlite3.Connection):
"""
Patch get_db/close_db in the database module so that
extract_mentions (which does a lazy import) uses the test database.
"""
with patch(
"commons.apps.handlers.database.db.get_db",
return_value=initialized_db,
), patch(
"commons.apps.handlers.database.db.close_db",
):
yield
# ===========================================================================
# extract_mentions — regex extraction + DB validation
# ===========================================================================
def test_extract_mentions_empty_string(initialized_db: sqlite3.Connection):
"""Empty string returns empty list."""
result = extract_mentions("")
assert result == []
def test_extract_mentions_no_mentions(initialized_db: sqlite3.Connection):
"""Text without @mentions returns empty list."""
result = extract_mentions("Hello world, no mentions here")
assert result == []
def test_extract_mentions_single(initialized_db: sqlite3.Connection):
"""Single @mention of a registered agent is returned."""
initialized_db.execute(
"INSERT OR IGNORE INTO agents (branch_name, display_name) VALUES (?, ?)",
("drone", "Drone"),
)
initialized_db.commit()
result = extract_mentions("Hey @drone check this out")
assert result == ["drone"]
def test_extract_mentions_multiple(initialized_db: sqlite3.Connection):
"""Multiple @mentions of registered agents are all returned."""
for name, display in [("flow", "Flow"), ("seed", "Seed")]:
initialized_db.execute(
"INSERT OR IGNORE INTO agents (branch_name, display_name) VALUES (?, ?)",
(name, display),
)
initialized_db.commit()
result = extract_mentions("@flow and @seed please review")
assert result == ["flow", "seed"]
def test_extract_mentions_unregistered_filtered(initialized_db: sqlite3.Connection):
"""Mentions of agents not in the DB are filtered out."""
result = extract_mentions("@nonexistent_branch please help")
assert result == []
def test_extract_mentions_case_insensitive(initialized_db: sqlite3.Connection):
"""Mentions are lowercased for DB lookup."""
initialized_db.execute(
"INSERT OR IGNORE INTO agents (branch_name, display_name) VALUES (?, ?)",
("prax", "Prax"),
)
initialized_db.commit()
result = extract_mentions("Hey @PRAX look at this")
assert result == ["prax"]
def test_extract_mentions_with_underscores(initialized_db: sqlite3.Connection):
"""Mentions with underscores (e.g., @seed_cortex) are matched."""
initialized_db.execute(
"INSERT OR IGNORE INTO agents (branch_name, display_name) VALUES (?, ?)",
("seed_cortex", "Seed Cortex"),
)
initialized_db.commit()
result = extract_mentions("Asking @seed_cortex for analysis")
assert result == ["seed_cortex"]
# ===========================================================================
# find_branch_root — filesystem walk
# ===========================================================================
def test_find_branch_root_with_trinity(tmp_path: Path):
"""Finds root when .trinity/passport.json exists."""
trinity_dir = tmp_path / ".trinity"
trinity_dir.mkdir()
(trinity_dir / "passport.json").write_text("{}", encoding="utf-8")
sub = tmp_path / "apps" / "handlers"
sub.mkdir(parents=True)
result = find_branch_root(sub)
assert result is not None
assert result == tmp_path.resolve()
def test_find_branch_root_no_trinity(tmp_path: Path):
"""Returns None when no .trinity directory exists in ancestry."""
sub = tmp_path / "deep" / "nested" / "dir"
sub.mkdir(parents=True)
result = find_branch_root(sub)
assert result is None
def test_find_branch_root_at_start(tmp_path: Path):
"""Finds root when start_path IS the branch root."""
trinity_dir = tmp_path / ".trinity"
trinity_dir.mkdir()
(trinity_dir / "passport.json").write_text("{}", encoding="utf-8")
result = find_branch_root(tmp_path)
assert result is not None
assert result == tmp_path.resolve()
# ===========================================================================
# resolve_display_name
# ===========================================================================
def test_resolve_display_name_no_alias(monkeypatch: pytest.MonkeyPatch):
"""Falls back to branch_name when no alias is cached."""
# Reset the alias cache to a known state
monkeypatch.setattr(identity_ops_mod, "_alias_cache", {})
result = resolve_display_name("UNKNOWN_BRANCH")
assert result == "UNKNOWN_BRANCH"
def test_resolve_display_name_with_alias(monkeypatch: pytest.MonkeyPatch):
"""Returns 'Alias (SYSTEM_NAME)' format when alias exists."""
monkeypatch.setattr(identity_ops_mod, "_alias_cache", {"TEAM_1": "Alpha Team"})
result = resolve_display_name("TEAM_1")
assert result == "Alpha Team (TEAM_1)"
def test_resolve_display_name_compact(monkeypatch: pytest.MonkeyPatch):
"""Compact mode returns alias only, no parenthesized system name."""
monkeypatch.setattr(identity_ops_mod, "_alias_cache", {"TEAM_1": "Alpha Team"})
result = resolve_display_name("TEAM_1", compact=True)
assert result == "Alpha Team"
def test_resolve_display_name_compact_no_alias(monkeypatch: pytest.MonkeyPatch):
"""Compact mode without alias still falls back to branch_name."""
monkeypatch.setattr(identity_ops_mod, "_alias_cache", {})
result = resolve_display_name("RAW_NAME", compact=True)
assert result == "RAW_NAME"