Move tests from /tmp into the proper test suite. 22 cases covering:
- Leo gotcha: extract/* + commit_type=enrich/challenge classifies by
commit_type, not branch prefix (same pattern as the contributor-role
wiring fix)
- Reweave priority: branch.startswith('reweave/') wins over
_MAINTENANCE_COMMIT_TYPES — nightly reweave PRs classify as enrich,
not infra. Locks in the bifurcation against future priority refactors
- Full NON_MERGED_STATUS_TO_OPERATION coverage: open, approved, closed,
conflict, validating, reviewing, merging, zombie
- Knowledge-producing commit_types (research, entity) → new
- Maintenance commit_types (fix, pipeline) → infra
- Defensive: null inputs, unknown status
aiohttp imported at module load — file uses pytest.importorskip so it
runs cleanly in any environment with aiohttp installed and skips gracefully
otherwise. sys.path inject for diagnostics/ since it isn't packaged.
Reviewed-by: Ganymede
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
152 lines
5.3 KiB
Python
152 lines
5.3 KiB
Python
"""Tests for diagnostics/activity_endpoint.py classify_pr_operation.
|
|
|
|
Covers the Leo gotcha — extract/* branches with commit_type=enrich or
|
|
challenge classify by commit_type, not branch prefix. Same class of bug
|
|
as the contributor-role wiring fix.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
# diagnostics/ isn't on sys.path by default; add it for these tests.
|
|
_DIAG = Path(__file__).resolve().parents[1] / "diagnostics"
|
|
if str(_DIAG) not in sys.path:
|
|
sys.path.insert(0, str(_DIAG))
|
|
|
|
# aiohttp is imported at module load time; skip cleanly if not installed.
|
|
pytest.importorskip("aiohttp")
|
|
|
|
from activity_endpoint import classify_pr_operation # noqa: E402
|
|
|
|
|
|
# ─── Merged PRs: commit_type wins over branch prefix ───────────────────────
|
|
|
|
|
|
def test_extract_branch_legacy_knowledge_classifies_new():
|
|
assert classify_pr_operation("merged", "knowledge", "extract/foo", None) == "new"
|
|
|
|
|
|
def test_extract_branch_with_enrich_commit_type_classifies_enrich():
|
|
"""Leo gotcha: extract/* + commit_type=enrich → enrich, not new."""
|
|
assert classify_pr_operation("merged", "enrich", "extract/foo", None) == "enrich"
|
|
|
|
|
|
def test_extract_branch_with_challenge_commit_type_classifies_challenge():
|
|
"""Leo gotcha: extract/* + commit_type=challenge → challenge, not new."""
|
|
assert classify_pr_operation("merged", "challenge", "extract/foo", None) == "challenge"
|
|
|
|
|
|
def test_challenged_by_in_description_classifies_challenge():
|
|
assert (
|
|
classify_pr_operation(
|
|
"merged", "knowledge", "extract/foo", "evidence for challenged_by claim"
|
|
)
|
|
== "challenge"
|
|
)
|
|
|
|
|
|
# ─── Branch prefix fallback (when commit_type is generic) ──────────────────
|
|
|
|
|
|
def test_reweave_branch_classifies_enrich():
|
|
assert classify_pr_operation("merged", "knowledge", "reweave/batch-1", None) == "enrich"
|
|
|
|
|
|
def test_challenge_branch_classifies_challenge():
|
|
assert (
|
|
classify_pr_operation("merged", "knowledge", "challenge/nuclear-moloch", None)
|
|
== "challenge"
|
|
)
|
|
|
|
|
|
# ─── Maintenance commit_types → infra ──────────────────────────────────────
|
|
|
|
|
|
def test_fix_commit_type_classifies_infra():
|
|
assert classify_pr_operation("merged", "fix", "fix/deploy-bug", None) == "infra"
|
|
|
|
|
|
def test_pipeline_commit_type_classifies_infra():
|
|
assert (
|
|
classify_pr_operation("merged", "pipeline", "epimetheus/migration-v14", None)
|
|
== "infra"
|
|
)
|
|
|
|
|
|
# ─── Knowledge-producing commit_types → new ────────────────────────────────
|
|
|
|
|
|
def test_research_commit_type_classifies_new():
|
|
assert (
|
|
classify_pr_operation("merged", "research", "theseus/cornelius-batch-2", None)
|
|
== "new"
|
|
)
|
|
|
|
|
|
def test_entity_commit_type_classifies_new():
|
|
assert classify_pr_operation("merged", "entity", "leo/entities-update", None) == "new"
|
|
|
|
|
|
# ─── Non-merged statuses route through NON_MERGED_STATUS_TO_OPERATION ──────
|
|
|
|
|
|
def test_open_pr_classifies_extract():
|
|
assert classify_pr_operation("open", None, "extract/foo", None) == "extract"
|
|
|
|
|
|
def test_approved_pr_classifies_new():
|
|
assert classify_pr_operation("approved", None, "extract/foo", None) == "new"
|
|
|
|
|
|
def test_closed_pr_classifies_infra():
|
|
assert classify_pr_operation("closed", None, "extract/foo", None) == "infra"
|
|
|
|
|
|
def test_conflict_pr_classifies_challenge():
|
|
assert classify_pr_operation("conflict", None, "extract/foo", None) == "challenge"
|
|
|
|
|
|
def test_validating_pr_classifies_extract():
|
|
assert classify_pr_operation("validating", None, "extract/foo", None) == "extract"
|
|
|
|
|
|
def test_reviewing_pr_classifies_extract():
|
|
assert classify_pr_operation("reviewing", None, "extract/foo", None) == "extract"
|
|
|
|
|
|
def test_merging_pr_classifies_new():
|
|
assert classify_pr_operation("merging", None, "extract/foo", None) == "new"
|
|
|
|
|
|
def test_zombie_pr_classifies_infra():
|
|
assert classify_pr_operation("zombie", None, "extract/foo", None) == "infra"
|
|
|
|
|
|
# ─── Priority order: reweave commit_type vs reweave/ branch ─────────────────
|
|
# Reweave commit_type is in _MAINTENANCE_COMMIT_TYPES (→ infra), but
|
|
# branch.startswith('reweave/') is checked first (→ enrich). The bifurcation
|
|
# is real spec behavior — nightly reweave PRs must classify as enrich, not
|
|
# infra. Locking this in prevents a silent flip on future priority refactors.
|
|
|
|
|
|
def test_reweave_commit_type_with_reweave_branch_classifies_enrich():
|
|
"""Branch prefix wins over maintenance — reweave PRs are enrich, not infra."""
|
|
assert classify_pr_operation("merged", "reweave", "reweave/batch-1", None) == "enrich"
|
|
|
|
|
|
def test_reweave_commit_type_without_reweave_branch_classifies_infra():
|
|
"""Without reweave/ prefix, reweave commit_type falls to maintenance → infra."""
|
|
assert classify_pr_operation("merged", "reweave", "epimetheus/foo", None) == "infra"
|
|
|
|
|
|
# ─── Defensive cases — null/empty inputs shouldn't crash ───────────────────
|
|
|
|
|
|
def test_null_commit_type_and_branch_classifies_new():
|
|
assert classify_pr_operation("merged", None, None, None) == "new"
|
|
|
|
|
|
def test_unknown_status_falls_back_to_infra():
|
|
assert classify_pr_operation("nonsense", None, None, None) == "infra"
|