openapi_py: Change condition for invalid requests.

Change the condition for allowing failed validation to the condition
that `if the test fails, response status code begins with 4`. Also
add `intentionally_undocumented` argument in `validate_request` for
allowing passing of tests which return `200` responses but fail
validation due to some intentionally undocumented feature in
OpenAPI specification.
This commit is contained in:
orientor
2020-07-25 20:54:21 +05:30
committed by Tim Abbott
parent 8b8cfb2e73
commit c91c106cfb
2 changed files with 23 additions and 17 deletions

View File

@@ -306,7 +306,7 @@ SKIP_JSON = {'/fetch_api_key:post'}
def validate_request(url: str, method: str, data: Dict[str, Any],
http_headers: Dict[str, Any], json_url: bool,
uses_invalid_parameters: bool) -> None:
status_code: str, intentionally_undocumented: bool=False) -> None:
# Some JSON endpoints have different parameters compared to
# their `/api/v1` counterparts.
if json_url and url + ':' + method in SKIP_JSON:
@@ -322,12 +322,15 @@ def validate_request(url: str, method: str, data: Dict[str, Any],
mock_request = MockRequest('http://localhost:9991/', method, '/api/v1' + url,
headers=http_headers, args=data)
result = openapi_spec.core_validator().validate(mock_request)
if uses_invalid_parameters:
# This assertion helps us avoid unnecessary use of the
# uses_invalid_parameters argument.
assert(len(result.errors) != 0)
return
if len(result.errors) != 0:
# Requests that do not validate against the OpenAPI spec must either:
# * Have returned a 400 (bad request) error
# * Have returned a 200 (success) with this request marked as intentionally
# undocumented behavior.
if status_code.startswith('4'):
return
if status_code.startswith('2') and intentionally_undocumented:
return
# If no errors are raised, then validation is successful
if len(result.errors) == 0:
@@ -341,8 +344,8 @@ with the parameters passed in this HTTP request. Consider:
* Updating the OpenAPI schema defined in zerver/openapi/zulip.yaml
* Adjusting the test to pass valid parameters. If the test
deliberately passes invalid parameters, you need to pass
`uses_invalid_parameters=True` to self.client_{method.lower()} or
fails due to intentionally_undocumented features, you need to pass
`intentionally_undocumented=True` to self.client_{method.lower()} or
self.api_{method.lower()} to document your intent.
See https://zulip.readthedocs.io/en/latest/documentation/api.html for help.

View File

@@ -1078,12 +1078,15 @@ class OpenAPIRequestValidatorTest(ZulipTestCase):
"""
# `/users/me/subscriptions` doesn't require any parameters
validate_request('/users/me/subscriptions', 'get', {}, {}, False,
uses_invalid_parameters=False)
with self.assertRaises(AssertionError):
validate_request('/users/me/subscriptions', 'get', {}, {},
False, uses_invalid_parameters=True)
validate_request('/dev_fetch_api_key', 'post', {}, {}, False,
uses_invalid_parameters=True)
'200')
with self.assertRaises(SchemaError):
validate_request('/dev_fetch_api_key', 'post', {}, {},
False, uses_invalid_parameters=False)
# `/messages` POST does not work on an empty response
validate_request('/messages', 'post', {}, {},
False, '200')
# 400 responses are allowed to fail validation.
validate_request('/messages', 'post', {}, {},
False, '400')
# `intentionally_undocumented` allows validation errors on
# 200 responses.
validate_request('/dev_fetch_api_key', 'post', {}, {},
False, '200', intentionally_undocumented=True)