mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 23:13:25 +00:00
openapi: Use serialized response codes instead of descriptive ones.
Openapi had descriptive response codes for endpoints with multiple responses for same response code. But this does not fall in line with openapi specifications. So change descriptive response codes like "400_auth" and "400_anauth" to "400_0" and "400_1" for all such endpoints. Also make the necessary changes in openapi.py so as to be able to read the schema in such cases and generate example in such cases.
This commit is contained in:
@@ -84,20 +84,20 @@ the `principals` argument, like so:
|
|||||||
|
|
||||||
A typical successful JSON response may look like:
|
A typical successful JSON response may look like:
|
||||||
|
|
||||||
{generate_code_example|/users/me/subscriptions:post|fixture(200_without_principals)}
|
{generate_code_example|/users/me/subscriptions:post|fixture(200_0)}
|
||||||
|
|
||||||
A typical successful JSON response when the user is already subscribed to
|
A typical successful JSON response when the user is already subscribed to
|
||||||
the streams specified:
|
the streams specified:
|
||||||
|
|
||||||
{generate_code_example|/users/me/subscriptions:post|fixture(200_already_subscribed)}
|
{generate_code_example|/users/me/subscriptions:post|fixture(200_1)}
|
||||||
|
|
||||||
A typical response for when the requesting user does not have access to
|
A typical response for when the requesting user does not have access to
|
||||||
a private stream and `authorization_errors_fatal` is `True`:
|
a private stream and `authorization_errors_fatal` is `True`:
|
||||||
|
|
||||||
{generate_code_example|/users/me/subscriptions:post|fixture(400_unauthorized_errors_fatal_true)}
|
{generate_code_example|/users/me/subscriptions:post|fixture(400_0)}
|
||||||
|
|
||||||
|
|
||||||
A typical response for when the requesting user does not have access to
|
A typical response for when the requesting user does not have access to
|
||||||
a private stream and `authorization_errors_fatal` is `False`:
|
a private stream and `authorization_errors_fatal` is `False`:
|
||||||
|
|
||||||
{generate_code_example|/users/me/subscriptions:post|fixture(400_unauthorized_errors_fatal_false)}
|
{generate_code_example|/users/me/subscriptions:post|fixture(400_1)}
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ A typical successful JSON response may look like:
|
|||||||
|
|
||||||
An example JSON response for when the specified message does not exist:
|
An example JSON response for when the specified message does not exist:
|
||||||
|
|
||||||
{generate_code_example|/messages/{message_id}:delete|fixture(400_invalid_message)}
|
{generate_code_example|/messages/{message_id}:delete|fixture(400_0)}
|
||||||
|
|
||||||
An example JSON response for when the user making the query does not
|
An example JSON response for when the user making the query does not
|
||||||
have permission to delete the message:
|
have permission to delete the message:
|
||||||
|
|
||||||
{generate_code_example|/messages/{message_id}:delete|fixture(400_not_admin)}
|
{generate_code_example|/messages/{message_id}:delete|fixture(400_1)}
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ A typical successful JSON response may look like:
|
|||||||
An example JSON response for when an `add` operation is requested for a topic
|
An example JSON response for when an `add` operation is requested for a topic
|
||||||
that has already been muted:
|
that has already been muted:
|
||||||
|
|
||||||
{generate_code_example|/users/me/subscriptions/muted_topics:patch|fixture(400_topic_already_muted)}
|
{generate_code_example|/users/me/subscriptions/muted_topics:patch|fixture(400_0)}
|
||||||
|
|
||||||
An example JSON response for when a `remove` operation is requested for a
|
An example JSON response for when a `remove` operation is requested for a
|
||||||
topic that had not been previously muted:
|
topic that had not been previously muted:
|
||||||
|
|
||||||
{generate_code_example|/users/me/subscriptions/muted_topics:patch|fixture(400_topic_not_muted)}
|
{generate_code_example|/users/me/subscriptions/muted_topics:patch|fixture(400_1)}
|
||||||
|
|||||||
@@ -21,18 +21,18 @@ errors common to many endpoints:
|
|||||||
|
|
||||||
A typical failed JSON response for when the API key is invalid:
|
A typical failed JSON response for when the API key is invalid:
|
||||||
|
|
||||||
{generate_code_example|/rest-error-handling:post|fixture(400_invalid_api_key)}
|
{generate_code_example|/rest-error-handling:post|fixture(400_0)}
|
||||||
|
|
||||||
## Missing request argument(s)
|
## Missing request argument(s)
|
||||||
|
|
||||||
A typical failed JSON response for when a required request argument
|
A typical failed JSON response for when a required request argument
|
||||||
is not supplied:
|
is not supplied:
|
||||||
|
|
||||||
{generate_code_example|/rest-error-handling:post|fixture(400_missing_request_argument_error)}
|
{generate_code_example|/rest-error-handling:post|fixture(400_1)}
|
||||||
|
|
||||||
## User not authorized for query
|
## User not authorized for query
|
||||||
|
|
||||||
A typical failed JSON response for when the user is not authorized
|
A typical failed JSON response for when the user is not authorized
|
||||||
for a query:
|
for a query:
|
||||||
|
|
||||||
{generate_code_example|/rest-error-handling:post|fixture(400_user_not_authorized_error)}
|
{generate_code_example|/rest-error-handling:post|fixture(400_2)}
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ A typical successful JSON response may look like:
|
|||||||
A typical failed JSON response for when a stream message is sent to a stream
|
A typical failed JSON response for when a stream message is sent to a stream
|
||||||
that does not exist:
|
that does not exist:
|
||||||
|
|
||||||
{generate_code_example|/messages:post|fixture(400_non_existing_stream)}
|
{generate_code_example|/messages:post|fixture(400_0)}
|
||||||
|
|
||||||
A typical failed JSON response for when a private message is sent to a user
|
A typical failed JSON response for when a private message is sent to a user
|
||||||
that does not exist:
|
that does not exist:
|
||||||
|
|
||||||
{generate_code_example|/messages:post|fixture(400_non_existing_user)}
|
{generate_code_example|/messages:post|fixture(400_1)}
|
||||||
|
|||||||
@@ -59,13 +59,25 @@ class SchemaError(Exception):
|
|||||||
|
|
||||||
openapi_spec = OpenAPISpec(OPENAPI_SPEC_PATH)
|
openapi_spec = OpenAPISpec(OPENAPI_SPEC_PATH)
|
||||||
|
|
||||||
|
def get_schema(endpoint: str, method: str, response: str) -> Dict[str, Any]:
|
||||||
|
if len(response) == 3:
|
||||||
|
schema = (openapi_spec.spec()['paths'][endpoint][method.lower()]['responses']
|
||||||
|
[response]['content']['application/json']['schema'])
|
||||||
|
return schema
|
||||||
|
else:
|
||||||
|
resp_code = int(response[4])
|
||||||
|
response = response[0:3]
|
||||||
|
schema = (openapi_spec.spec()['paths'][endpoint][method.lower()]['responses']
|
||||||
|
[response]['content']['application/json']['schema']["oneOf"][resp_code])
|
||||||
|
return schema
|
||||||
|
|
||||||
def get_openapi_fixture(endpoint: str, method: str,
|
def get_openapi_fixture(endpoint: str, method: str,
|
||||||
response: Optional[str]='200') -> Dict[str, Any]:
|
response: Optional[str]='200') -> Dict[str, Any]:
|
||||||
"""Fetch a fixture from the full spec object.
|
"""Fetch a fixture from the full spec object.
|
||||||
"""
|
"""
|
||||||
return (openapi_spec.spec()['paths'][endpoint][method.lower()]['responses']
|
if response is None:
|
||||||
[response]['content']['application/json']['schema']
|
response = '200'
|
||||||
['example'])
|
return (get_schema(endpoint, method, response)['example'])
|
||||||
|
|
||||||
def get_openapi_paths() -> Set[str]:
|
def get_openapi_paths() -> Set[str]:
|
||||||
return set(openapi_spec.spec()['paths'].keys())
|
return set(openapi_spec.spec()['paths'].keys())
|
||||||
@@ -88,8 +100,7 @@ def validate_against_openapi_schema(content: Dict[str, Any], endpoint: str,
|
|||||||
"""Compare a "content" dict with the defined schema for a specific method
|
"""Compare a "content" dict with the defined schema for a specific method
|
||||||
in an endpoint.
|
in an endpoint.
|
||||||
"""
|
"""
|
||||||
schema = (openapi_spec.spec()['paths'][endpoint][method.lower()]['responses']
|
schema = get_schema(endpoint, method, response)
|
||||||
[response]['content']['application/json']['schema'])
|
|
||||||
|
|
||||||
exclusion_list = (EXCLUDE_PROPERTIES.get(endpoint, {}).get(method, {})
|
exclusion_list = (EXCLUDE_PROPERTIES.get(endpoint, {}).get(method, {})
|
||||||
.get(response, []))
|
.get(response, []))
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ def add_subscriptions(client):
|
|||||||
# {code_example|end}
|
# {code_example|end}
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
||||||
'200_without_principals')
|
'200_0')
|
||||||
|
|
||||||
# {code_example|start}
|
# {code_example|start}
|
||||||
# To subscribe another user to a stream, you may pass in
|
# To subscribe another user to a stream, you may pass in
|
||||||
@@ -87,7 +87,7 @@ def test_add_subscriptions_already_subscribed(client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
||||||
'200_already_subscribed')
|
'200_1')
|
||||||
|
|
||||||
def test_authorization_errors_fatal(client, nonadmin_client):
|
def test_authorization_errors_fatal(client, nonadmin_client):
|
||||||
# type: (Client, Client) -> None
|
# type: (Client, Client) -> None
|
||||||
@@ -112,7 +112,7 @@ def test_authorization_errors_fatal(client, nonadmin_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
||||||
'400_unauthorized_errors_fatal_false')
|
'400_0')
|
||||||
|
|
||||||
result = nonadmin_client.add_subscriptions(
|
result = nonadmin_client.add_subscriptions(
|
||||||
streams=[
|
streams=[
|
||||||
@@ -122,7 +122,7 @@ def test_authorization_errors_fatal(client, nonadmin_client):
|
|||||||
)
|
)
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
validate_against_openapi_schema(result, '/users/me/subscriptions', 'post',
|
||||||
'400_unauthorized_errors_fatal_true')
|
'400_1')
|
||||||
|
|
||||||
@openapi_test_function("/users/{email}/presence:get")
|
@openapi_test_function("/users/{email}/presence:get")
|
||||||
def get_user_presence(client):
|
def get_user_presence(client):
|
||||||
@@ -413,7 +413,7 @@ def test_user_not_authorized_error(nonadmin_client):
|
|||||||
# type: (Client) -> None
|
# type: (Client) -> None
|
||||||
result = nonadmin_client.get_streams(include_all_active=True)
|
result = nonadmin_client.get_streams(include_all_active=True)
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/rest-error-handling', 'post', '400_user_not_authorized_error')
|
validate_against_openapi_schema(result, '/rest-error-handling', 'post', '400_2')
|
||||||
|
|
||||||
def get_subscribers(client):
|
def get_subscribers(client):
|
||||||
# type: (Client) -> None
|
# type: (Client) -> None
|
||||||
@@ -718,7 +718,7 @@ def test_nonexistent_stream_error(client):
|
|||||||
result = client.send_message(request)
|
result = client.send_message(request)
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/messages', 'post',
|
validate_against_openapi_schema(result, '/messages', 'post',
|
||||||
'400_non_existing_stream')
|
'400_0')
|
||||||
|
|
||||||
def test_private_message_invalid_recipient(client):
|
def test_private_message_invalid_recipient(client):
|
||||||
# type: (Client) -> None
|
# type: (Client) -> None
|
||||||
@@ -730,7 +730,7 @@ def test_private_message_invalid_recipient(client):
|
|||||||
result = client.send_message(request)
|
result = client.send_message(request)
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/messages', 'post',
|
validate_against_openapi_schema(result, '/messages', 'post',
|
||||||
'400_non_existing_user')
|
'400_1')
|
||||||
|
|
||||||
@openapi_test_function("/messages/{message_id}:patch")
|
@openapi_test_function("/messages/{message_id}:patch")
|
||||||
def update_message(client, message_id):
|
def update_message(client, message_id):
|
||||||
@@ -804,7 +804,7 @@ def test_delete_message_edit_permission_error(client, nonadmin_client):
|
|||||||
result = nonadmin_client.delete_message(result['id'])
|
result = nonadmin_client.delete_message(result['id'])
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/messages/{message_id}', 'delete',
|
validate_against_openapi_schema(result, '/messages/{message_id}', 'delete',
|
||||||
'400_not_admin')
|
'400_1')
|
||||||
|
|
||||||
@openapi_test_function("/messages/{message_id}/history:get")
|
@openapi_test_function("/messages/{message_id}/history:get")
|
||||||
def get_message_history(client, message_id):
|
def get_message_history(client, message_id):
|
||||||
@@ -1098,13 +1098,13 @@ def update_user_group_members(client, group_id):
|
|||||||
def test_invalid_api_key(client_with_invalid_key):
|
def test_invalid_api_key(client_with_invalid_key):
|
||||||
# type: (Client) -> None
|
# type: (Client) -> None
|
||||||
result = client_with_invalid_key.list_subscriptions()
|
result = client_with_invalid_key.list_subscriptions()
|
||||||
validate_against_openapi_schema(result, '/rest-error-handling', 'post', '400_invalid_api_key')
|
validate_against_openapi_schema(result, '/rest-error-handling', 'post', '400_0')
|
||||||
|
|
||||||
def test_missing_request_argument(client):
|
def test_missing_request_argument(client):
|
||||||
# type: (Client) -> None
|
# type: (Client) -> None
|
||||||
result = client.render_message({})
|
result = client.render_message({})
|
||||||
|
|
||||||
validate_against_openapi_schema(result, '/rest-error-handling', 'post', '400_missing_request_argument_error')
|
validate_against_openapi_schema(result, '/rest-error-handling', 'post', '400_1')
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_stream_error(client):
|
def test_invalid_stream_error(client):
|
||||||
|
|||||||
Reference in New Issue
Block a user