"""Tests for the catalog data model.""" from __future__ import annotations import json from typing import Any import pytest from aegis_gitea_mcp.catalog import Operation, Parameter def sample_dict() -> dict[str, Any]: return { "tool_name": "gitea_issue_create", "domain": "issue", "operation_id": "issueCreateIssue", "method": "POST", "path": "/repos/{owner}/{repo}/issues", "summary": "Create an issue", "description": "", "parameters": [ { "name": "owner", "arg_name": "owner", "location": "path", "required": True, "schema": {"type": "string"}, "is_file": False, }, { "name": "body", "arg_name": "body", "location": "body", "required": False, "schema": {"type": "object"}, }, ], "input_schema": {"type": "object", "additionalProperties": False}, "consumes": ["application/json"], "produces": ["application/json"], "read_only": False, "destructive": False, "idempotent": False, "paginated": False, } def test_operation_round_trip_through_json() -> None: data = sample_dict() operation = Operation.from_dict(data) assert operation.method == "POST" assert isinstance(operation.parameters, tuple) assert isinstance(operation.consumes, tuple) assert operation.parameters[0].location == "path" assert operation.parameters[1].is_file is False rebuilt = Operation.from_dict(json.loads(json.dumps(operation.to_dict()))) assert rebuilt == operation def test_to_dict_uses_lists_and_is_json_serializable() -> None: dumped = Operation.from_dict(sample_dict()).to_dict() assert isinstance(dumped["parameters"], list) assert isinstance(dumped["consumes"], list) json.dumps(dumped) def test_method_is_upper_cased() -> None: data = sample_dict() data["method"] = "post" assert Operation.from_dict(data).method == "POST" def test_optional_fields_default() -> None: data = sample_dict() del data["summary"], data["description"], data["consumes"], data["produces"] operation = Operation.from_dict(data) assert operation.summary == "" assert operation.consumes == () assert operation.produces == () def test_invalid_location_rejected() -> None: with pytest.raises(ValueError, match="location"): Parameter.from_dict( {"name": "x", "arg_name": "x", "location": "header", "required": True, "schema": {}} ) def test_missing_required_key_raises() -> None: data = sample_dict() del data["tool_name"] with pytest.raises(KeyError): Operation.from_dict(data) def test_operation_is_frozen() -> None: operation = Operation.from_dict(sample_dict()) with pytest.raises(AttributeError): operation.method = "GET" # type: ignore[misc] def test_file_parameter() -> None: parameter = Parameter.from_dict( { "name": "attachment", "arg_name": "attachment", "location": "formData", "required": True, "schema": {"type": "string", "contentEncoding": "base64"}, "is_file": True, } ) assert parameter.is_file is True assert parameter.to_dict()["location"] == "formData"