diff --git a/openapi_spec_validator/validation/keywords.py b/openapi_spec_validator/validation/keywords.py index 6c4b751..df52f34 100644 --- a/openapi_spec_validator/validation/keywords.py +++ b/openapi_spec_validator/validation/keywords.py @@ -392,13 +392,20 @@ def __call__( if path_parameters is not None: names += list(self._get_path_param_names(path_parameters)) - all_params = list(set(names)) + all_params = set(names) + url_params = set(self._get_path_params_from_url(url)) - for path in self._get_path_params_from_url(url): + for path in sorted(url_params): if path not in all_params: yield UnresolvableParameterError( f"Path parameter '{path}' for '{name}' operation in '{url}' was not resolved" ) + + for path in sorted(all_params): + if path not in url_params: + yield UnresolvableParameterError( + f"Path parameter '{path}' for '{name}' operation in '{url}' was not resolved" + ) return def _get_path_param_names(self, params: SchemaPath) -> Iterator[str]: diff --git a/tests/integration/validation/test_exceptions.py b/tests/integration/validation/test_exceptions.py index 2d2aba1..5cfdd2e 100644 --- a/tests/integration/validation/test_exceptions.py +++ b/tests/integration/validation/test_exceptions.py @@ -268,6 +268,46 @@ def test_undocumented_parameter(self): "'/test/{param1}/{param2}' was not resolved" ) + def test_extra_path_parameter_not_present_in_path(self): + spec = { + "openapi": "3.0.0", + "info": { + "title": "Test Api", + "version": "0.0.1", + }, + "paths": { + "/test": { + "get": { + "responses": { + "default": { + "description": "default response", + }, + }, + "parameters": [ + { + "name": "param1", + "in": "path", + "required": True, + "schema": { + "type": "integer", + }, + }, + ], + }, + }, + }, + } + + errors = OpenAPIV30SpecValidator(spec).iter_errors() + + errors_list = list(errors) + assert len(errors_list) == 1 + assert errors_list[0].__class__ == UnresolvableParameterError + assert errors_list[0].message == ( + "Path parameter 'param1' for 'get' operation in '/test' " + "was not resolved" + ) + def test_default_value_wrong_type(self): spec = { "openapi": "3.0.0",