Skip to content

Commit 317e1f0

Browse files
committed
fix(typing): add missing types to tests and resolve ruff errors
1 parent 989f1d5 commit 317e1f0

7 files changed

Lines changed: 36 additions & 26 deletions

tests/test_api.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Any
12
from unittest.mock import patch
23

34
from fastapi.testclient import TestClient
@@ -8,11 +9,11 @@
89

910

1011
class FailingExternalService:
11-
def run(self, envelope) -> str:
12+
def run(self: "Any", envelope: "Any") -> str:
1213
raise WorkflowAgentServiceError("sensitive provider detail")
1314

1415

15-
def test_workflow_api_emits_canonical_events(envelope) -> None:
16+
def test_workflow_api_emits_canonical_events(envelope: "Any") -> None:
1617
client = TestClient(create_app(Settings()))
1718

1819
response = client.post("/api/v1/workflows", json=envelope.model_dump(mode="json"))
@@ -56,7 +57,7 @@ def test_invalid_foundry_endpoint_is_not_ready() -> None:
5657
assert client.get("/health/ready").status_code == 503
5758

5859

59-
def test_workflow_api_sanitizes_external_service_failures(envelope) -> None:
60+
def test_workflow_api_sanitizes_external_service_failures(envelope: "Any") -> None:
6061
with patch(
6162
"cas_reference_product.app.build_workflow_agent_service",
6263
return_value=FailingExternalService(),

tests/test_contract_registry.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212

1313

1414
def load_json(path: Path) -> dict[str, Any]:
15-
return json.loads(path.read_text(encoding="utf-8"))
15+
from typing import cast
16+
return cast(dict[str, Any], json.loads(path.read_text(encoding="utf-8")))
1617

1718

1819
def contract_registry() -> Registry[Any]:
@@ -37,11 +38,11 @@ def test_vendored_contract_release_matches_manifest_hashes() -> None:
3738
assert hashlib.sha256(content).hexdigest() == entry["sha256"]
3839

3940

40-
def test_prompt_envelope_serialization_conforms_to_v010_registry(envelope) -> None:
41+
def test_prompt_envelope_serialization_conforms_to_v010_registry(envelope: "Any") -> None:
4142
assert_valid("prompt-envelope.schema.json", envelope.model_dump(mode="json"))
4243

4344

44-
def test_run_event_serialization_conforms_to_v010_registry(envelope) -> None:
45+
def test_run_event_serialization_conforms_to_v010_registry(envelope: "Any") -> None:
4546
result = WorkflowOrchestrator(LocalWorkflowAgentService(), envelope.repo).execute(envelope)
4647

4748
for event in result.events:

tests/test_function_boundary.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
from typing import Any
12
import json
23

34
import pytest
45

56
from cas_reference_product.ingress import InvalidIngressRequest, create_worker_message
67

78

8-
def test_ingress_validates_and_serializes_canonical_envelope(envelope) -> None:
9+
def test_ingress_validates_and_serializes_canonical_envelope(envelope: "Any") -> None:
910
message = create_worker_message(envelope.model_dump_json().encode())
1011

1112
assert json.loads(message)["runId"] == envelope.runId

tests/test_models.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1+
from typing import Any
12
import pytest
23
from pydantic import ValidationError
34

45
from cas_reference_product.models import Actor, PromptEnvelope, RunEvent, TraceContext
56

67

7-
def test_prompt_envelope_rejects_extra_properties(envelope) -> None:
8+
def test_prompt_envelope_rejects_extra_properties(envelope: "Any") -> None:
89
payload = envelope.model_dump()
910
payload["secret"] = "not-allowed"
1011

1112
with pytest.raises(ValidationError):
1213
PromptEnvelope.model_validate(payload)
1314

1415

15-
def test_prompt_envelope_matches_cas_contract_metadata(envelope) -> None:
16+
def test_prompt_envelope_matches_cas_contract_metadata(envelope: "Any") -> None:
1617
payload = envelope.model_dump(mode="json")
1718

1819
assert payload["kind"] == "PromptEnvelope"
@@ -28,7 +29,7 @@ def test_prompt_envelope_matches_cas_contract_metadata(envelope) -> None:
2829
["No secrets", "No secrets"],
2930
],
3031
)
31-
def test_prompt_envelope_enforces_cas_contract_constraints(envelope, constraints) -> None:
32+
def test_prompt_envelope_enforces_cas_contract_constraints(envelope: "Any", constraints: "Any") -> None:
3233
payload = envelope.model_dump()
3334
payload["constraints"] = constraints
3435

@@ -67,6 +68,6 @@ def test_prompt_envelope_enforces_cas_contract_constraints(envelope, constraints
6768
),
6869
],
6970
)
70-
def test_contract_models_reject_explicit_null_optional_fields(model, payload) -> None:
71+
def test_contract_models_reject_explicit_null_optional_fields(model: "Any", payload: "Any") -> None:
7172
with pytest.raises(ValidationError):
7273
model.model_validate(payload)

tests/test_service_factory.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Any
12
from unittest.mock import patch
23

34
import pytest
@@ -39,7 +40,7 @@ def test_foundry_service_rejects_invalid_project_endpoint() -> None:
3940
FoundryWorkflowAgentService(settings)
4041

4142

42-
def test_foundry_service_uses_next_gen_agent_reference(envelope) -> None:
43+
def test_foundry_service_uses_next_gen_agent_reference(envelope: "Any") -> None:
4344
settings = Settings(
4445
environment="prod",
4546
workflow_backend="foundry",
@@ -71,7 +72,7 @@ def test_foundry_service_uses_next_gen_agent_reference(envelope) -> None:
7172
assert result == "Foundry result"
7273

7374

74-
def test_foundry_service_sanitizes_sdk_failure(envelope) -> None:
75+
def test_foundry_service_sanitizes_sdk_failure(envelope: "Any") -> None:
7576
settings = Settings(
7677
environment="prod",
7778
workflow_backend="foundry",

tests/test_telemetry.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Any
12
"""Tests for Phase 2 — Telemetry Hardening (TEL-01 through TEL-04)."""
23

34
from unittest.mock import MagicMock, patch
@@ -110,12 +111,13 @@ def test_all_loop_stages_share_one_trace_without_prompt_or_output_attributes() -
110111
pass
111112

112113
spans = exporter.get_finished_spans()
113-
assert {span.attributes["cas.stage"] for span in spans} == {stage.value for stage in LoopStage}
114+
stage_values = {stage.value for stage in LoopStage}
115+
assert {span.attributes["cas.stage"] for span in spans if span.attributes} == stage_values
114116
assert len({span.context.trace_id for span in spans}) == 1
115117
assert all(
116118
"prompt" not in key and "output" not in key
117119
for span in spans
118-
for key in span.attributes
120+
for key in (span.attributes or {})
119121
)
120122

121123

@@ -140,7 +142,7 @@ def test_install_propagator_sets_w3c_propagator() -> None:
140142
# ---------------------------------------------------------------------------
141143

142144

143-
def test_workflow_endpoint_creates_span(in_memory_exporter: InMemorySpanExporter, envelope) -> None:
145+
def test_workflow_endpoint_creates_span(in_memory_exporter: InMemorySpanExporter, envelope: "Any") -> None:
144146
client = TestClient(create_app(Settings()))
145147
response = client.post("/api/v1/workflows", json=envelope.model_dump(mode="json"))
146148

@@ -157,12 +159,13 @@ def test_workflow_endpoint_creates_span(in_memory_exporter: InMemorySpanExporter
157159
# ---------------------------------------------------------------------------
158160

159161

160-
def test_workflow_span_attributes(in_memory_exporter: InMemorySpanExporter, envelope) -> None:
162+
def test_workflow_span_attributes(in_memory_exporter: InMemorySpanExporter, envelope: "Any") -> None:
161163
client = TestClient(create_app(Settings()))
162164
client.post("/api/v1/workflows", json=envelope.model_dump(mode="json"))
163165

164166
spans = in_memory_exporter.get_finished_spans()
165167
api_span = next(s for s in spans if s.name == "cas.api.workflows.execute")
168+
assert api_span.attributes
166169
assert api_span.attributes.get("cas.correlation_id") == envelope.correlationId
167170
assert api_span.attributes.get("cas.run_id") == envelope.runId
168171
assert api_span.attributes.get("cas.intent") == envelope.intent
@@ -174,7 +177,7 @@ def test_workflow_span_attributes(in_memory_exporter: InMemorySpanExporter, enve
174177

175178

176179
def test_workflow_span_events_started_and_completed(
177-
in_memory_exporter: InMemorySpanExporter, envelope
180+
in_memory_exporter: InMemorySpanExporter, envelope: "Any"
178181
) -> None:
179182
client = TestClient(create_app(Settings()))
180183
client.post("/api/v1/workflows", json=envelope.model_dump(mode="json"))
@@ -188,12 +191,12 @@ def test_workflow_span_events_started_and_completed(
188191

189192

190193
def test_workflow_span_events_started_and_failed(
191-
in_memory_exporter: InMemorySpanExporter, envelope
194+
in_memory_exporter: InMemorySpanExporter, envelope: "Any"
192195
) -> None:
193196
from cas_reference_product.workflow import WorkflowAgentServiceError
194197

195198
class FailingService:
196-
def run(self, _env) -> str:
199+
def run(self: "Any", _env: "Any") -> str:
197200
raise WorkflowAgentServiceError("backend down")
198201

199202
with patch(
@@ -213,14 +216,15 @@ def run(self, _env) -> str:
213216

214217

215218
def test_span_event_carries_correlation_id(
216-
in_memory_exporter: InMemorySpanExporter, envelope
219+
in_memory_exporter: InMemorySpanExporter, envelope: "Any"
217220
) -> None:
218221
client = TestClient(create_app(Settings()))
219222
client.post("/api/v1/workflows", json=envelope.model_dump(mode="json"))
220223

221224
spans = in_memory_exporter.get_finished_spans()
222225
api_span = next(s for s in spans if s.name == "cas.api.workflows.execute")
223226
started_event = next(e for e in api_span.events if e.name == "workflow.started")
227+
assert started_event.attributes
224228
assert started_event.attributes.get("cas.correlation_id") == envelope.correlationId
225229
assert started_event.attributes.get("cas.run_id") == envelope.runId
226230

@@ -231,7 +235,7 @@ def test_span_event_carries_correlation_id(
231235

232236

233237
def test_w3c_traceparent_propagated_inbound(
234-
in_memory_exporter: InMemorySpanExporter, envelope
238+
in_memory_exporter: InMemorySpanExporter, envelope: "Any"
235239
) -> None:
236240
"""Request with a W3C traceparent header links the API span as a child."""
237241
incoming_traceparent = "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"

tests/test_workflow.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from typing import Any
12
from datetime import UTC, datetime
23
from unittest.mock import patch
34

@@ -7,16 +8,16 @@
78

89

910
class SuccessfulService:
10-
def run(self, envelope) -> str:
11+
def run(self: "Any", envelope: "Any") -> str:
1112
return f"processed:{envelope.promptId}"
1213

1314

1415
class FailingService:
15-
def run(self, envelope) -> str:
16+
def run(self: "Any", envelope: "Any") -> str:
1617
raise RuntimeError("expected")
1718

1819

19-
def test_orchestrator_returns_traceable_events(envelope) -> None:
20+
def test_orchestrator_returns_traceable_events(envelope: "Any") -> None:
2021
fixed = datetime(2026, 6, 11, 10, 0, tzinfo=UTC)
2122
# Patch current_traceparent so this unit test is provider-independent.
2223
with patch(
@@ -36,6 +37,6 @@ def test_orchestrator_returns_traceable_events(envelope) -> None:
3637
assert all(event.traceContext == envelope.traceContext for event in result.events)
3738

3839

39-
def test_orchestrator_propagates_failure(envelope) -> None:
40+
def test_orchestrator_propagates_failure(envelope: "Any") -> None:
4041
with pytest.raises(RuntimeError, match="expected"):
4142
WorkflowOrchestrator(FailingService(), envelope.repo).execute(envelope)

0 commit comments

Comments
 (0)