"""Tests for OpenAPI generator.""" import pytest from datetime import datetime from http_log_explorer.generators import OpenAPIGenerator from http_log_explorer.models import HTTPEntry, Request, Response def make_entry( method: str = "GET", url: str = "https://api.example.com/test", status: int = 200, req_body: str | None = None, resp_body: str | None = None, content_type: str = "application/json", ) -> HTTPEntry: """Create a test HTTPEntry.""" return HTTPEntry( id=f"entry-{method}-{status}", request=Request( method=method, url=url, headers={"Content-Type": content_type}, body=req_body, ), response=Response( status=status, status_text="OK", headers={"Content-Type": content_type}, body=resp_body, content_type=content_type, ), timestamp=datetime.now(), ) @pytest.fixture def sample_entries(): """Create sample entries for OpenAPI generation.""" return [ make_entry( "GET", "https://api.example.com/users", 200, resp_body='[{"id": 1, "name": "Alice"}]', ), make_entry( "POST", "https://api.example.com/users", 201, req_body='{"name": "Bob"}', resp_body='{"id": 2, "name": "Bob"}', ), make_entry( "GET", "https://api.example.com/users/1", 200, resp_body='{"id": 1, "name": "Alice", "email": "alice@example.com"}', ), make_entry( "PUT", "https://api.example.com/users/1", 200, req_body='{"name": "Alice Smith"}', resp_body='{"id": 1, "name": "Alice Smith"}', ), make_entry( "DELETE", "https://api.example.com/users/1", 204, ), ] class TestOpenAPIGenerator: """Tests for OpenAPIGenerator.""" def test_generate_spec_structure(self, sample_entries): """Test that generated spec has correct structure.""" generator = OpenAPIGenerator(sample_entries) spec = generator.generate(title="Test API", version="1.0.0") assert spec["openapi"] == "3.0.3" assert spec["info"]["title"] == "Test API" assert spec["info"]["version"] == "1.0.0" assert "paths" in spec assert "components" in spec def test_paths_inferred(self, sample_entries): """Test that paths are correctly inferred.""" generator = OpenAPIGenerator(sample_entries) spec = generator.generate() assert "/users" in spec["paths"] assert "/users/{id}" in spec["paths"] def test_methods_inferred(self, sample_entries): """Test that HTTP methods are correctly inferred.""" generator = OpenAPIGenerator(sample_entries) spec = generator.generate() users_path = spec["paths"]["/users"] assert "get" in users_path assert "post" in users_path def test_schemas_extracted(self, sample_entries): """Test that JSON schemas are extracted from bodies.""" generator = OpenAPIGenerator(sample_entries) spec = generator.generate() assert "components" in spec assert "schemas" in spec["components"] assert len(spec["components"]["schemas"]) > 0 def test_responses_included(self, sample_entries): """Test that responses are included in spec.""" generator = OpenAPIGenerator(sample_entries) spec = generator.generate() users_get = spec["paths"]["/users"]["get"] assert "responses" in users_get assert "200" in users_get["responses"] def test_to_json(self, sample_entries): """Test JSON serialization.""" generator = OpenAPIGenerator(sample_entries) spec = generator.generate() json_str = generator.to_json(spec) assert '"openapi"' in json_str assert '"paths"' in json_str def test_generate_empty_entries(self): """Test generating spec from empty entries.""" generator = OpenAPIGenerator([]) spec = generator.generate() assert spec["paths"] == {} assert spec["components"]["schemas"] == {} def test_query_parameters_inferred(self): """Test that query parameters are inferred.""" entries = [ make_entry( "GET", "https://api.example.com/users", 200, resp_body='[{"id": 1}]', ), ] entries[0].request.query_params["page"] = "1" entries[0].request.query_params["limit"] = "10" generator = OpenAPIGenerator(entries) spec = generator.generate() assert "/users" in spec["paths"] users_get = spec["paths"]["/users"]["get"] if "parameters" in users_get: param_names = [p["name"] for p in users_get["parameters"]] assert "page" in param_names assert "limit" in param_names