Skip to content

Commit

Permalink
[python-experimental] Adds response body tests for json content type (#…
Browse files Browse the repository at this point in the history
…12988)

* Tags renamed

* Spec updated to add response bodies

* Adds correct tag to response body routes

* Adds response body autogen tests

* Adds pos test cases, removes dead code

* Adds and uses api_test_partial

* Samples regenerated
  • Loading branch information
spacether committed Jul 24, 2022
1 parent 96b7d35 commit 30f1f11
Show file tree
Hide file tree
Showing 545 changed files with 122,756 additions and 37,045 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class ApiTestMixin:
url: str,
method: str = 'POST',
body: typing.Optional[bytes] = None,
content_type: typing.Optional[str] = 'application/json',
accept_content_type: typing.Optional[str] = 'application/json',
content_type: typing.Optional[str] = None,
accept_content_type: typing.Optional[str] = None,
stream: bool = False,
):
headers = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,56 @@ class {{#with operations}}Test{{classname}}(ApiTestMixin, unittest.TestCase):
"""
from {{packageName}}.{{apiPackage}}.{{classFilename}}_endpoints import {{operationId}} as endpoint_module
{{#each responses}}
{{#if @first}}
{{#if @first}}
response_status = {{code}}
{{#if content}}
{{#each content}}
# TODO get response content working
accept_content_type = '{{{@key}}}'

{{#if this.testCases}}

{{#each testCases}}
{{#with this }}
# test_{{@key}}_{{#if valid}}passes{{else}}fails{{/if}}
# {{description}}
with patch.object(urllib3.PoolManager, 'request') as mock_request:
payload = (
{{#with data}}
{{> model_templates/payload_renderer endChar='' }}
{{/with}}
)
mock_request.return_value = self.response(
self.json_bytes(payload),
status=response_status
)
{{#if valid}}
{{> api_test_partial }}

assert isinstance(api_response.response, urllib3.HTTPResponse)
assert isinstance(api_response.body, endpoint_module.{{schema.baseName}})
deserialized_response_body = endpoint_module.{{schema.baseName}}._from_openapi_data(
payload,
_configuration=self._configuration
)
assert api_response.body == deserialized_response_body
{{else}}
with self.assertRaises(({{packageName}}.ApiValueError, {{packageName}}.ApiTypeError)):
self.api.{{operationId}}(
accept_content_types=(accept_content_type,)
)
self.assert_pool_manager_request_called_with(
mock_request,
self._configuration.host + '{{{path}}}',
method='{{httpMethod}}',
content_type=None,
accept_content_type=accept_content_type,
)
{{/if}}
{{/with}}

{{/each}}

{{/if}}
{{/each}}
{{else}}
response_body = ''
Expand All @@ -58,46 +103,28 @@ class {{#with operations}}Test{{classname}}(ApiTestMixin, unittest.TestCase):
# test_{{@key}}_{{#if valid}}passes{{else}}fails{{/if}}
# {{description}}
with patch.object(urllib3.PoolManager, 'request') as mock_request:
request_payload = (
payload = (
{{#with data}}
{{> model_templates/payload_renderer endChar='' }}
{{/with}}
)
{{#if valid}}
body = endpoint_module.{{schema.baseName}}._from_openapi_data(
{{#with data}}
request_payload,
{{/with}}
payload,
_configuration=self._configuration
)
mock_request.return_value = self.response(
self.json_bytes(response_body),
status=response_status
)
api_response = self.api.{{operationId}}(
body=body,
content_type=content_type
)
self.assert_pool_manager_request_called_with(
mock_request,
self._configuration.host + '{{{path}}}',
method='{{httpMethod}}',
body=self.json_bytes(request_payload),
content_type=content_type,
{{#unless produces}}
accept_content_type=None,
{{/unless}}
)
{{> api_test_partial }}

assert isinstance(api_response.response, urllib3.HTTPResponse)
# TODO if response body is unset check that it is unset here
assert isinstance(api_response.body, schemas.Unset)
{{else}}
with self.assertRaises(({{packageName}}.ApiValueError, {{packageName}}.ApiTypeError)):
body = endpoint_module.{{schema.baseName}}._from_openapi_data(
{{#with data}}
{{> model_templates/payload_renderer endChar=',' }}
{{/with}}
payload,
_configuration=self._configuration
)
self.api.{{operationId}}(body=body)
Expand All @@ -112,7 +139,7 @@ class {{#with operations}}Test{{classname}}(ApiTestMixin, unittest.TestCase):
{{/with}}
{{else}}
pass
{{/if}}
{{/if}}

{{/each}}
{{/with}}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
api_response = self.api.{{operationId}}(
{{#if bodyParam}}
body=body,
content_type=content_type
{{/if}}
{{#if produces}}
accept_content_types=(accept_content_type,)
{{/if}}
)
self.assert_pool_manager_request_called_with(
mock_request,
self._configuration.host + '{{{path}}}',
method='{{httpMethod}}',
{{#if bodyParam}}
body=self.json_bytes(payload),
content_type=content_type,
{{/if}}
{{#if produces}}
accept_content_type=accept_content_type,
{{/if}}
)
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,6 @@ class DictBase(Discriminable):
ApiValueError: when a string can't be converted into a date or datetime and it must be one of those classes
ApiTypeError: when the input type is not in the list of allowed spec types
"""
if isinstance(arg, cls):
# an instance of the correct type was passed in
return {}
_path_to_schemas = super()._validate(arg, validation_metadata=validation_metadata)
if not isinstance(arg, frozendict):
return _path_to_schemas
Expand Down Expand Up @@ -1655,18 +1652,6 @@ class ComposedBase(Discriminable):
ApiValueError: when a string can't be converted into a date or datetime and it must be one of those classes
ApiTypeError: when the input type is not in the list of allowed spec types
"""
if isinstance(arg, Schema) and validation_metadata.from_server is False:
if isinstance(arg, cls):
# an instance of the correct type was passed in
return {}
raise ApiTypeError(
'Incorrect type passed in, required type was {} and passed type was {} at {}'.format(
cls,
type(arg),
validation_metadata.path_to_item
)
)

# validation checking on types, validations, and enums
path_to_schemas = super()._validate(arg, validation_metadata=validation_metadata)

Expand Down Expand Up @@ -2098,43 +2083,6 @@ class DictSchema(
schema_type_classes = set([NoneSchema, DictSchema, ListSchema, NumberSchema, StrSchema, BoolSchema])


def deserialize_file(response_data, configuration, content_disposition=None):
"""Deserializes body to file

Saves response body into a file in a temporary folder,
using the filename from the `Content-Disposition` header if provided.

Args:
param response_data (str): the file data to write
configuration (Configuration): the instance to use to convert files

Keyword Args:
content_disposition (str): the value of the Content-Disposition
header

Returns:
(file_type): the deserialized file which is open
The user is responsible for closing and reading the file
"""
fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path)
os.close(fd)
os.remove(path)

if content_disposition:
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?',
content_disposition).group(1)
path = os.path.join(os.path.dirname(path), filename)

with open(path, "wb") as f:
if isinstance(response_data, str):
# change str to bytes so we can write it
response_data = response_data.encode('utf-8')
f.write(response_data)

f = open(path, "rb")
return f


@functools.cache
def get_new_class(
class_name: str,
Expand Down
Loading

0 comments on commit 30f1f11

Please sign in to comment.