"""Validate owned fields without tightening or rewriting upstream payloads.""" import pytest from fastapi.responses import JSONResponse from pydantic import ValidationError from s2s_client.api.responses import validated_json_response from s2s_client.models.requests import ApipilotExecuteRequest, QueueEndPayload, SearchRequest from s2s_client.models.responses import ( AllocationResponse, QueueCancellationResponse, ReasoningResponse, ReportsResponse, SearchResponse, ToolExecutionResponse, UserProfileResponse, ) @pytest.mark.parametrize( ("model", "payload"), [ (AllocationResponse, {}), (AllocationResponse, {"state": [1, None], "connectUrl": "wss://host", "future": {"x": 1.0}}), (ToolExecutionResponse, {"success": True, "unknown": {"nested": [None, 1.0, False]}}), (ToolExecutionResponse, {"success": False, "data": 42, "error": "loose error", "future": []}), (ReasoningResponse, {"answer": "รก", "usage": [1, None], "debug": False, "future": True}), (SearchResponse, {"query": "q", "answer": {"x": 2}, "results": [{"title": [], "snippet": 7, "url": None}]}), ( ReportsResponse, {"count": 1, "wrappedLen": 2, "hints": [], "entries": [{"sourceScheduleLabel": 42, "date": None}]}, ), *[(UserProfileResponse, payload) for payload in [{}, [], 42, False, None, "profile"]], ], ) def test_upstream_values_and_missing_fields_keep_exact_wire_bytes(model, payload): original = JSONResponse(payload, status_code=202) validated = validated_json_response(payload, model, status_code=202) assert validated.body == original.body assert validated.raw_headers == original.raw_headers assert validated.status_code == original.status_code @pytest.mark.parametrize("payload", [{}, {"ok": "true"}, {"ok": 1}, {"ok": None}]) def test_owned_response_fields_are_actually_validated(payload): with pytest.raises(ValidationError): validated_json_response(payload, QueueCancellationResponse) def test_request_models_keep_legacy_extra_field_and_argument_behavior(): assert SearchRequest.model_validate({"query": "q", "future": True}).model_dump() == {"query": "q", "key": None} arguments = {"arbitrary": {"nested": [1, None]}, "unknown": True} assert ApipilotExecuteRequest.model_validate({"name": "tool", "arguments": arguments}).arguments == arguments for value in [None, "id", 42, False, [], {}, {"future": True}]: assert QueueEndPayload.model_validate({"queueId": value, "future": 1}).queueId == value assert QueueEndPayload.model_validate({}).queueId == "" def test_http_routes_publish_response_schemas(): # Import the app only after the compatibility suite's isolated configuration. from s2s_client.main import app spec = app.openapi() for path, operations in spec["paths"].items(): if path.startswith("/api/"): for operation in operations.values(): schema = operation["responses"]["200"]["content"]["application/json"]["schema"] assert "$ref" in schema, path allocation = spec["components"]["schemas"]["AllocationResponse"] assert not allocation.get("required") assert allocation["additionalProperties"] is True