164 lines
5.0 KiB
Python
164 lines
5.0 KiB
Python
"""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
|