import pytest import json import yaml from json_to_openapi.schema_generator import OpenAPIGenerator, EndpointInfo from json_to_openapi.analyzer import JsonAnalyzer class TestOpenAPIGenerator: """Test cases for OpenAPIGenerator.""" def test_generate_simple_spec(self): generator = OpenAPIGenerator(title="Test API", version="1.0.0") data = {"name": "John", "age": 30} spec = generator.generate(data) assert spec["openapi"] == "3.0.3" assert spec["info"]["title"] == "Test API" assert spec["info"]["version"] == "1.0.0" assert "/" in spec["paths"] assert "get" in spec["paths"]["/"] def test_generate_with_endpoint(self): generator = OpenAPIGenerator(title="Users API", version="1.0.0") data = {"users": [{"id": 1, "name": "Alice"}]} endpoint = EndpointInfo( path="/users", method="get", summary="Get all users", description="Retrieve a list of all users", tags=["users"] ) spec = generator.generate(data, endpoint=endpoint) assert "/users" in spec["paths"] assert "get" in spec["paths"]["/users"] assert spec["paths"]["/users"]["get"]["summary"] == "Get all users" assert spec["paths"]["/users"]["get"]["description"] == "Retrieve a list of all users" assert spec["paths"]["/users"]["get"]["tags"] == ["users"] def test_generate_with_description(self): generator = OpenAPIGenerator(title="Test API", version="1.0.0") data = {"message": "Hello"} spec = generator.generate(data, description="A test API description") assert spec["info"]["description"] == "A test API description" def test_schema_type_string(self): generator = OpenAPIGenerator() data = "hello" spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "string" def test_schema_type_integer(self): generator = OpenAPIGenerator() data = 42 spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "integer" def test_schema_type_number(self): generator = OpenAPIGenerator() data = 3.14 spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "number" def test_schema_type_boolean(self): generator = OpenAPIGenerator() data = True spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "boolean" def test_schema_type_object(self): generator = OpenAPIGenerator() data = {"name": "John", "age": 30} spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "object" assert "properties" in schema assert schema["properties"]["name"]["type"] == "string" assert schema["properties"]["age"]["type"] == "integer" def test_schema_type_array(self): generator = OpenAPIGenerator() data = [1, 2, 3] spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "array" assert schema["items"]["type"] == "integer" def test_schema_format_date(self): generator = OpenAPIGenerator() data = "2024-01-15" spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "string" assert schema["format"] == "date" def test_schema_format_datetime(self): generator = OpenAPIGenerator() data = "2024-01-15T10:30:00Z" spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "string" assert schema["format"] == "date-time" def test_schema_nested_object(self): generator = OpenAPIGenerator() data = {"user": {"address": {"city": "Boston"}}} spec = generator.generate(data) schema = spec["paths"]["/"]["get"]["responses"]["200"]["content"]["application/json"]["schema"] assert schema["type"] == "object" assert schema["properties"]["user"]["type"] == "object" assert schema["properties"]["user"]["properties"]["address"]["type"] == "object" assert schema["properties"]["user"]["properties"]["address"]["properties"]["city"]["type"] == "string" class TestOpenAPIGeneratorBatch: """Test cases for batch processing.""" def test_generate_batch_individual(self, temp_json_dir): generator = OpenAPIGenerator(title="Batch API", version="1.0.0") files = list(temp_json_dir.glob("*.json")) result = generator.generate_batch(files, output_dir=str(temp_json_dir), combined=False) assert "individual" in result assert len(result["individual"]) == 2 def test_generate_batch_combined(self, temp_json_dir): generator = OpenAPIGenerator(title="Combined API", version="1.0.0") files = list(temp_json_dir.glob("*.json")) result = generator.generate_batch(files, output_dir=str(temp_json_dir), combined=True) assert "combined" in result assert "individual" in result assert len(result["individual"]) == 2 assert "paths" in result["combined"] class TestOpenAPIGeneratorOutput: """Test cases for output formatting.""" def test_to_yaml(self): generator = OpenAPIGenerator() data = {"name": "Test"} spec = generator.generate(data) yaml_output = generator.to_yaml(spec) assert isinstance(yaml_output, str) assert "openapi: 3.0.3" in yaml_output def test_to_json(self): generator = OpenAPIGenerator() data = {"name": "Test"} spec = generator.generate(data) json_output = generator.to_json(spec) parsed = json.loads(json_output) assert parsed["openapi"] == "3.0.3" def test_save_yaml(self, tmp_path): generator = OpenAPIGenerator() data = {"name": "Test"} spec = generator.generate(data) output_path = tmp_path / "output.yaml" generator.save_spec(spec, str(output_path), format="yaml") assert output_path.exists() content = output_path.read_text() assert "openapi: 3.0.3" in content def test_save_json(self, tmp_path): generator = OpenAPIGenerator() data = {"name": "Test"} spec = generator.generate(data) output_path = tmp_path / "output.json" generator.save_spec(spec, str(output_path), format="json") assert output_path.exists() content = output_path.read_text() parsed = json.loads(content) assert parsed["openapi"] == "3.0.3" def test_save_yaml_adds_extension(self, tmp_path): generator = OpenAPIGenerator() data = {"name": "Test"} spec = generator.generate(data) output_path = tmp_path / "output" generator.save_spec(spec, str(output_path), format="yaml") assert (tmp_path / "output.yaml").exists() def test_save_json_adds_extension(self, tmp_path): generator = OpenAPIGenerator() data = {"name": "Test"} spec = generator.generate(data) output_path = tmp_path / "output" generator.save_spec(spec, str(output_path), format="json") assert (tmp_path / "output.json").exists() class TestEndpointInfo: """Test cases for EndpointInfo dataclass.""" def test_default_endpoint(self): endpoint = EndpointInfo() assert endpoint.path == "/" assert endpoint.method == "get" assert endpoint.summary == "" assert endpoint.description == "" assert endpoint.tags == [] def test_custom_endpoint(self): endpoint = EndpointInfo( path="/api/users", method="post", summary="Create User", description="Create a new user", tags=["users", "admin"], operation_id="createUser" ) assert endpoint.path == "/api/users" assert endpoint.method == "post" assert endpoint.summary == "Create User" assert "users" in endpoint.tags assert endpoint.operation_id == "createUser"