Compare commits
2 commits
42d35d4e15
...
cd5aac5cc6
| Author | SHA1 | Date | |
|---|---|---|---|
| cd5aac5cc6 | |||
| 7c6417d6be |
2 changed files with 154 additions and 2 deletions
|
|
@ -102,7 +102,7 @@ def _extract_claim_slugs(description, branch=None):
|
||||||
if branch:
|
if branch:
|
||||||
parts = branch.split("/", 1)
|
parts = branch.split("/", 1)
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
return [parts[1][:120]]
|
return [parts[1]]
|
||||||
return []
|
return []
|
||||||
titles = [t.strip() for t in description.split("|") if t.strip()]
|
titles = [t.strip() for t in description.split("|") if t.strip()]
|
||||||
slugs = []
|
slugs = []
|
||||||
|
|
@ -111,7 +111,7 @@ def _extract_claim_slugs(description, branch=None):
|
||||||
slug = "".join(c if c.isalnum() or c in (" ", "-") else "" for c in slug)
|
slug = "".join(c if c.isalnum() or c in (" ", "-") else "" for c in slug)
|
||||||
slug = slug.replace(" ", "-").strip("-")
|
slug = slug.replace(" ", "-").strip("-")
|
||||||
if len(slug) > 10:
|
if len(slug) > 10:
|
||||||
slugs.append(slug[:120])
|
slugs.append(slug)
|
||||||
return slugs
|
return slugs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
152
tests/test_activity_classify.py
Normal file
152
tests/test_activity_classify.py
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
"""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"
|
||||||
Loading…
Reference in a new issue