"""Unit tests for the spec parser module.""" import pytest import tempfile import json from pathlib import Path from api_testgen.core import SpecParser from api_testgen.core.exceptions import InvalidOpenAPISpecError, UnsupportedVersionError class TestSpecParser: """Tests for SpecParser class.""" def test_load_valid_openapi_30_spec(self, temp_spec_file): """Test loading a valid OpenAPI 3.0 specification.""" parser = SpecParser(temp_spec_file) spec = parser.load() assert spec is not None assert parser.version == "3.0.0" assert parser.base_path == "" assert len(parser.servers) == 1 def test_load_valid_json_spec(self, temp_json_spec_file): """Test loading a valid JSON OpenAPI specification.""" parser = SpecParser(temp_json_spec_file) spec = parser.load() assert spec is not None assert parser.version == "3.0.0" def test_get_info(self, temp_spec_file): """Test extracting API info from spec.""" parser = SpecParser(temp_spec_file) parser.load() info = parser.get_info() assert info["title"] == "Test Pet Store API" assert info["version"] == "1.0.0" assert "sample" in info["description"].lower() def test_get_paths(self, temp_spec_file): """Test extracting paths from spec.""" parser = SpecParser(temp_spec_file) parser.load() paths = parser.get_paths() assert "/pets" in paths assert "/pets/{petId}" in paths def test_get_endpoints(self, temp_spec_file): """Test extracting endpoints from spec.""" parser = SpecParser(temp_spec_file) parser.load() endpoints = parser.get_endpoints() assert len(endpoints) == 4 assert any(e["method"] == "get" and e["path"] == "/pets" for e in endpoints) assert any(e["method"] == "post" and e["path"] == "/pets" for e in endpoints) assert any(e["method"] == "get" and e["path"] == "/pets/{petId}" for e in endpoints) assert any(e["method"] == "delete" and e["path"] == "/pets/{petId}" for e in endpoints) def test_get_security_schemes(self, temp_spec_file): """Test extracting security schemes from spec.""" parser = SpecParser(temp_spec_file) parser.load() schemes = parser.get_security_schemes() assert "ApiKeyAuth" in schemes assert "BearerAuth" in schemes assert schemes["ApiKeyAuth"]["type"] == "apiKey" assert schemes["BearerAuth"]["type"] == "http" assert schemes["BearerAuth"]["scheme"] == "bearer" def test_get_definitions(self, temp_spec_file): """Test extracting schema definitions from spec.""" parser = SpecParser(temp_spec_file) parser.load() definitions = parser.get_definitions() assert "Pet" in definitions assert definitions["Pet"]["type"] == "object" def test_endpoint_with_parameters(self, temp_spec_file): """Test endpoint parameter extraction.""" parser = SpecParser(temp_spec_file) parser.load() endpoints = parser.get_endpoints() pets_endpoint = next(e for e in endpoints if e["path"] == "/pets" and e["method"] == "get") assert len(pets_endpoint["parameters"]) == 2 assert any(p["name"] == "limit" and p["in"] == "query" for p in pets_endpoint["parameters"]) assert any(p["name"] == "status" and p["in"] == "query" for p in pets_endpoint["parameters"]) def test_endpoint_with_path_parameters(self, temp_spec_file): """Test path parameter extraction.""" parser = SpecParser(temp_spec_file) parser.load() endpoints = parser.get_endpoints() pet_endpoint = next(e for e in endpoints if e["path"] == "/pets/{petId}" and e["method"] == "get") assert len(pet_endpoint["parameters"]) == 1 param = pet_endpoint["parameters"][0] assert param["name"] == "petId" assert param["in"] == "path" assert param["required"] is True def test_endpoint_with_request_body(self, temp_spec_file): """Test request body extraction for OpenAPI 3.0.""" parser = SpecParser(temp_spec_file) parser.load() endpoints = parser.get_endpoints() create_endpoint = next(e for e in endpoints if e["path"] == "/pets" and e["method"] == "post") assert create_endpoint["request_body"] is not None assert create_endpoint["request_body"]["required"] is True def test_endpoint_with_responses(self, temp_spec_file): """Test response extraction.""" parser = SpecParser(temp_spec_file) parser.load() endpoints = parser.get_endpoints() pets_endpoint = next(e for e in endpoints if e["path"] == "/pets" and e["method"] == "get") assert "200" in pets_endpoint["responses"] assert pets_endpoint["responses"]["200"]["description"] == "A list of pets" def test_to_dict(self, temp_spec_file): """Test dictionary representation of parsed spec.""" parser = SpecParser(temp_spec_file) parser.load() spec_dict = parser.to_dict() assert "version" in spec_dict assert "info" in spec_dict assert "paths" in spec_dict assert "endpoints" in spec_dict assert "security_schemes" in spec_dict assert "definitions" in spec_dict def test_nonexistent_file_raises_error(self): """Test that nonexistent file raises InvalidOpenAPISpecError.""" parser = SpecParser("/nonexistent/path/spec.yaml") with pytest.raises(InvalidOpenAPISpecError): parser.load() def test_invalid_yaml_raises_error(self): """Test that invalid YAML raises InvalidOpenAPISpecError.""" with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f: f.write("invalid: yaml: content: [[[") f.flush() parser = SpecParser(Path(f.name)) with pytest.raises(InvalidOpenAPISpecError): parser.load() Path(f.name).unlink()