test_api_provider_k11.py file-level

at sha256:a · View file ↗ · Intel ↗

History
1 files
1 commits
0 hotspots
0 🧊 dead
0 💥 blast risk
sha256:6 fix(ISR): default require_independent_second_reviewer to require Opera… · aaronrene · Sep 2, 2026
1 """Unit tests for K11 headless API freeze provider."""
2
3 from __future__ import annotations
4
5 import json
6 from pathlib import Path
7
8 import pytest
9
10 from cli.kit_root import kit_root
11 from tools.freeze_reviewer.providers.api_client import ReviewApiClient
12 from tools.freeze_reviewer.providers.api_prompt import (
13 ARTIFACT_BEGIN,
14 ARTIFACT_END,
15 build_delimited_artifact,
16 build_review_request_body,
17 )
18 from tools.freeze_reviewer.providers.api_response import ProviderReviewError, parse_review_response
19 from tools.freeze_reviewer.providers.model_hint import resolve_model_hint
20 from tools.freeze_reviewer.types import ChecklistItem, ReviewerSettings
21 from tests.support import FakeHttpTransport
22
23
24 def test_missing_api_key_unreachable(monkeypatch) -> None:
25 monkeypatch.delenv("OVERSEER_REVIEW_API_KEY", raising=False)
26 monkeypatch.delenv("OVERSEER_REVIEW_API_URL", raising=False)
27 ok, cause = ReviewApiClient().reachable()
28 assert ok is False
29 assert cause == "missing API credentials"
30
31
32 def test_missing_api_url_unreachable(monkeypatch) -> None:
33 monkeypatch.setenv("OVERSEER_REVIEW_API_KEY", "test-key")
34 monkeypatch.delenv("OVERSEER_REVIEW_API_URL", raising=False)
35 ok, cause = ReviewApiClient().reachable()
36 assert ok is False
37 assert cause == "missing API base URL"
38
39
40 def test_health_probe_success(monkeypatch) -> None:
41 monkeypatch.setenv("OVERSEER_REVIEW_API_KEY", "test-key")
42 monkeypatch.setenv("OVERSEER_REVIEW_API_URL", "https://review.example.com/v1")
43 transport = FakeHttpTransport()
44 ok, cause = ReviewApiClient(transport=transport).reachable()
45 assert ok is True
46 assert cause is None
47 assert transport.calls[0]["method"] == "GET"
48 assert transport.calls[0]["url"].endswith("/health")
49 assert "artifact" not in (transport.calls[0]["body"] or b"").decode("utf-8", errors="ignore").lower()
50
51
52 def test_model_hint_resolution() -> None:
53 hint = resolve_model_hint("thinking-high", kit_root=kit_root())
54 assert "thinking" in hint.lower() or "opus" in hint.lower()
55
56
57 def test_delimited_artifact_wraps_data() -> None:
58 wrapped = build_delimited_artifact("phase: K1")
59 assert ARTIFACT_BEGIN in wrapped
60 assert ARTIFACT_END in wrapped
61 assert "phase: K1" in wrapped
62
63
64 def test_review_request_includes_checklist() -> None:
65 body = build_review_request_body(
66 artifact_text="frozen: true",
67 artifact_path="docs/FREEZE.md",
68 checklist=[ChecklistItem("C1", "Ground-truth edge", "MAJOR")],
69 model_label="thinking-high",
70 model_hint="extended thinking",
71 )
72 assert body["schema_version"] == 1
73 assert body["checklist"][0]["id"] == "C1"
74 assert ARTIFACT_BEGIN in body["artifact_text"]
75
76
77 def test_parse_valid_findings() -> None:
78 payload = json.dumps(
79 {
80 "findings": [
81 {
82 "check": "C2",
83 "severity": "MAJOR",
84 "category": "completeness",
85 "path": "docs/FREEZE.md",
86 "line": 3,
87 "message": "Missing matrix.",
88 }
89 ]
90 }
91 ).encode("utf-8")
92 findings = parse_review_response(payload, default_path="docs/FREEZE.md")
93 assert len(findings) == 1
94 assert findings[0].citation == "docs/FREEZE.md:3"
95
96
97 def test_parse_invalid_json_raises() -> None:
98 with pytest.raises(ProviderReviewError):
99 parse_review_response(b"not-json", default_path="docs/FREEZE.md")
100
101
102 def test_review_api_non_2xx_raises(monkeypatch) -> None:
103 monkeypatch.setenv("OVERSEER_REVIEW_API_KEY", "test-key")
104 monkeypatch.setenv("OVERSEER_REVIEW_API_URL", "https://review.example.com/v1")
105 transport = FakeHttpTransport(review_status=500, review_body=b'{"error":"backend down"}')
106 client = ReviewApiClient(transport=transport)
107 with pytest.raises(ProviderReviewError, match="status 500"):
108 client.review(
109 artifact_text="frozen: true",
110 artifact_path="docs/FREEZE.md",
111 checklist=[ChecklistItem("C1", "Ground-truth edge", "MAJOR")],
112 reviewer=ReviewerSettings(
113 mode="agent",
114 model="thinking-high",
115 provider="api",
116 fallback="human",
117 ),
118 )