"""Tests for the OpenAPI spec parser module.""" import tempfile import yaml import pytest from openapi_mock.core.spec_parser import ( load_spec, extract_paths, extract_schemas, extract_path_params, get_operation_id, extract_security_schemes, get_response_schema, get_spec_version, is_openapi_3, SpecNotFoundError, SpecValidationError, ) class TestLoadSpec: """Tests for load_spec function.""" def test_load_valid_spec(self, temp_spec_file, sample_openapi_spec): """Test loading a valid OpenAPI specification.""" spec = load_spec(temp_spec_file) assert spec["info"]["title"] == "Test API" assert spec["info"]["version"] == "1.0.0" assert spec["openapi"] == "3.0.0" def test_load_nonexistent_file(self): """Test loading a non-existent file raises error.""" with pytest.raises(SpecNotFoundError): load_spec("/nonexistent/path/spec.yaml") def test_load_invalid_yaml(self, invalid_yaml_file): """Test loading invalid YAML raises error.""" with pytest.raises(Exception): # Could be various YAML errors load_spec(invalid_yaml_file) def test_load_swagger_2_spec(self, tmp_path): """Test loading a Swagger 2.0 specification.""" swagger_spec = { "swagger": "2.0", "info": {"title": "Test", "version": "1.0"}, "paths": {} } spec_path = tmp_path / "swagger.yaml" with open(spec_path, "w") as f: yaml.dump(swagger_spec, f) spec = load_spec(str(spec_path)) assert spec["swagger"] == "2.0" class TestExtractPaths: """Tests for extract_paths function.""" def test_extract_paths(self, sample_openapi_spec): """Test extracting paths from spec.""" paths = extract_paths(sample_openapi_spec) assert "/users" in paths assert "/users/{userId}" in paths def test_extract_paths_empty(self): """Test extracting paths from spec with no paths.""" spec = {"openapi": "3.0.0", "info": {"title": "Test", "version": "1.0"}, "paths": {}} paths = extract_paths(spec) assert paths == {} def test_extract_paths_missing(self): """Test extracting paths when paths key is missing.""" spec = {"openapi": "3.0.0", "info": {"title": "Test", "version": "1.0"}} paths = extract_paths(spec) assert paths == {} class TestExtractSchemas: """Tests for extract_schemas function.""" def test_extract_schemas(self, sample_openapi_spec): """Test extracting schemas from spec.""" schemas = extract_schemas(sample_openapi_spec) assert "User" in schemas assert schemas["User"]["type"] == "object" def test_extract_schemas_swagger(self, swagger_2_spec): """Test extracting schemas from Swagger 2.0 spec.""" schemas = extract_schemas(swagger_2_spec) assert "Pet" in schemas def test_extract_schemas_missing(self): """Test extracting schemas when components are missing.""" spec = {"openapi": "3.0.0", "info": {"title": "Test", "version": "1.0"}, "paths": {}} schemas = extract_schemas(spec) assert schemas == {} class TestExtractPathParams: """Tests for extract_path_params function.""" def test_extract_single_param(self): """Test extracting a single path parameter.""" params = extract_path_params("/users/{id}") assert params == ["id"] def test_extract_multiple_params(self): """Test extracting multiple path parameters.""" params = extract_path_params("/users/{userId}/posts/{postId}") assert params == ["userId", "postId"] def test_extract_no_params(self): """Test extracting parameters from path with none.""" params = extract_path_params("/users") assert params == [] def test_extract_nested_brace_in_pattern(self): """Test extracting parameters handles edge cases.""" params = extract_path_params("/api/{version}/users/{id}") assert params == ["version", "id"] class TestGetOperationId: """Tests for get_operation_id function.""" def test_get_operation_id_simple(self): """Test generating operation ID for simple path.""" op_id = get_operation_id("/users", "get") assert op_id == "get_users" def test_get_operation_id_with_params(self): """Test generating operation ID for path with parameters.""" op_id = get_operation_id("/users/{id}", "get") assert op_id == "get_users__id_" def test_get_operation_id_nested(self): """Test generating operation ID for nested path.""" op_id = get_operation_id("/api/v1/users", "post") assert op_id == "post_api_v1_users" class TestGetResponseSchema: """Tests for get_response_schema function.""" def test_get_response_schema(self, sample_openapi_spec): """Test getting response schema for an operation.""" schema = get_response_schema(sample_openapi_spec, "/users", "get") assert schema is not None assert schema["type"] == "array" assert schema["items"]["$ref"] == "#/components/schemas/User" def test_get_response_schema_missing(self): """Test getting response schema for non-existent operation.""" spec = {"openapi": "3.0.0", "info": {"title": "Test", "version": "1.0"}, "paths": {}} schema = get_response_schema(spec, "/nonexistent", "get") assert schema is None class TestSpecVersion: """Tests for version detection functions.""" def test_get_spec_version(self, sample_openapi_spec): """Test getting OpenAPI version.""" version = get_spec_version(sample_openapi_spec) assert version == "3.0.0" def test_is_openapi_3_true(self, sample_openapi_spec): """Test OpenAPI 3.x detection.""" assert is_openapi_3(sample_openapi_spec) is True def test_is_openapi_3_false(self, swagger_2_spec): """Test Swagger 2.0 detection.""" assert is_openapi_3(swagger_2_spec) is False