Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
211 changes: 138 additions & 73 deletions src/shipchain_common/test_utils/json_asserter.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,43 @@ def __str__(self):
f'attributes: {self.attributes}; relationships: {self.relationships}'


def response_has_error(response, error, pointer=None):
if error is not None:
response_json = response.json()
assert 'errors' in response_json, f'Malformed error response: {response_json}'
assert isinstance(response_json['errors'], list), f'Error response not a list: {response_json}'
def _vnd_has_error(response_json, error, pointer=None):
assert 'errors' in response_json, f'Malformed error response: {response_json}'
errors = response_json['errors']
assert isinstance(errors, list), f'Error response not a list: {errors}'
error_found = False

error_found = False
for single_error in errors:
if error in single_error['detail']:
error_found = True
if pointer:
found_pointer = single_error['source']['pointer']
assert pointer in found_pointer, f'Error `{pointer}` not found in {found_pointer}'

for single_error in response_json['errors']:
if error in single_error['detail']:
error_found = True
if pointer:
found_pointer = single_error['source']['pointer']
assert pointer in found_pointer, f'Error `{pointer}` not found in {found_pointer}'
if not error_found:
assert False, f'Error `{error}` not found in {errors}'

if not error_found:
assert False, f'Error `{error}` not found in {response_json}'

def _json_has_error(errors, error):
assert isinstance(errors, dict), f'Error response not a dict: {errors}'
assert 'detail' in errors, f'Malformed error response: {errors}'

assert errors['detail'] == error, f'Error {error} not found in {errors["detail"]}'


def response_has_error(response, error, pointer=None, vnd=True):
if error is None:
return

response_json = response.json()

# application/vnd.api+json
if vnd:
_vnd_has_error(response_json, error, pointer)

# application/json
else:
_json_has_error(response_json, error)


def _vnd_assert_attributes(response_data, attributes):
Expand Down Expand Up @@ -198,78 +218,114 @@ def _plain_assert_attributes_in_list(response_list, attributes):
assert found_include, f'{attributes} NOT IN {response_list}'


def response_has_data(response, vnd=True, entity_refs=None, included=None, is_list=False,
resource=None, pk=None, attributes=None, relationships=None):
response = response.json()

# application/vnd.api+json
if vnd:
assert 'data' in response, f'response does not contain `data` property: {response}'
def _test_vnd_json(response, entity_refs=None, included=None, is_list=False, count=None, resource=None, pk=None,
attributes=None, relationships=None, check_ordering=False):
assert 'data' in response, f'response does not contain `data` property: {response}'

# if (attributes or relationships or resource or pk) and entity_refs:
assert not ((attributes or relationships or resource or pk) and entity_refs), \
'Use Only `entity_refs` or explicit `attributes`, `relationships`, `resource`, and `pk` but not both'
# if (attributes or relationships or resource or pk) and entity_refs:
assert not ((attributes or relationships or resource or pk) and entity_refs), \
'Use Only `entity_refs` or explicit `attributes`, `relationships`, `resource`, and `pk` but not both'

if (attributes or relationships or resource or pk) and not entity_refs:
entity_refs = EntityReferenceClass(resource=resource,
pk=pk,
attributes=attributes,
relationships=relationships)
if (attributes or relationships or resource or pk) and not entity_refs:
entity_refs = EntityReferenceClass(resource=resource,
pk=pk,
attributes=attributes,
relationships=relationships)

response_data = response['data']
response_data = response['data']

if is_list:
assert isinstance(response_data, list), f'Response should be a list'
if is_list:
assert isinstance(response_data, list), f'Response should be a list'

# Included resources are outside of the list response
if included:
_vnd_assert_include(response, included)
# Included resources are outside of the list response
if included:
_vnd_assert_include(response, included)

# Assertion for only included and not entities is valid
if entity_refs:
if not isinstance(entity_refs, list):
entity_refs = [entity_refs]
# Assertion for only included and not entities is valid
if entity_refs:
if not isinstance(entity_refs, list):
entity_refs = [entity_refs]

if not check_ordering:
for entity_ref in entity_refs:
_vnd_assert_entity_ref_in_list(response_data, entity_ref)
else:
assert len(entity_refs) <= len(response_data), \
f'Error: more entity refs supplied than available in response data. ' \
f'{len(response_data)} found asserted {len(entity_refs)}'
for iteration, entity_ref in enumerate(entity_refs):
_vnd_assertions(response_data[iteration], entity_ref)

else:
assert not isinstance(response_data, list), f'Response should not be a list'
assert not (entity_refs and isinstance(entity_refs, list)), \
f'entity_refs should not be a list for a non-list response'
if count is not None:
assert len(response_data) == count, \
f'Difference in count of response_data, got {len(response_data)} expected {count}'

# Included resources are outside of the list response
if included:
_vnd_assert_include(response, included)
else:
assert not isinstance(response_data, list), f'Response should not be a list'
assert not (entity_refs and isinstance(entity_refs, list)), \
f'entity_refs should not be a list for a non-list response'

# Assertion for only status is valid
if entity_refs:
_vnd_assertions(response_data, entity_refs)
assert (count is None), 'Count is only checked when response is list'
assert not check_ordering, 'Ordering is only checked when response is list'

# application/json
else:
assert not relationships, f'relationships not valid when vnd=False'
assert not entity_refs, f'entity_refs not valid when vnd=False'
assert not included, f'included not valid when vnd=False'
assert attributes, f'attributes must be provided when vnd=False'
# Included resources are outside of the list response
if included:
_vnd_assert_include(response, included)

# Assertion for only status is valid
if entity_refs:
_vnd_assertions(response_data, entity_refs)

if is_list:
assert isinstance(response, list), f'Response should be a list'

if not isinstance(attributes, list):
attributes = [attributes]
def _test_regular_json(response, entity_refs=None, included=None, is_list=False, count=None, attributes=None,
relationships=None, check_ordering=False):
assert not relationships, f'relationships not valid when vnd=False'
assert not entity_refs, f'entity_refs not valid when vnd=False'
assert not included, f'included not valid when vnd=False'
assert attributes, f'attributes must be provided when vnd=False'

if is_list:
assert isinstance(response, list), f'Response should be a list'

if not isinstance(attributes, list):
attributes = [attributes]

if not check_ordering:
for attribute in attributes:
_plain_assert_attributes_in_list(response, attribute)

else:
assert not isinstance(response, list), f'Response should not be a list'
assert not (attributes and isinstance(attributes, list)), \
f'attributes should not be a list for a non-list response'
assert len(attributes) <= len(response), \
f'Error: more attributes supplied than available in response. ' \
f'{len(attributes)} found asserted {len(response)}'
for iteration, attribute in enumerate(attributes):
_plain_assert_attributes_in_response(response[iteration], attribute)
if count is not None:
assert len(response) == count,\
f'Difference in count of response_data, got {len(response)} expected {count}'
else:
assert not isinstance(response, list), f'Response should not be a list'
assert not (attributes and isinstance(attributes, list)), \
f'attributes should not be a list for a non-list response'

_plain_assert_attributes_in_response(response, attributes)

_plain_assert_attributes_in_response(response, attributes)

def response_has_data(response, vnd=True, entity_refs=None, included=None, is_list=False, count=None,
resource=None, pk=None, attributes=None, relationships=None, check_ordering=False):
response = response.json()

def assert_200(response, vnd=True, entity_refs=None, included=None, is_list=False,
# application/vnd.api+json
if vnd:
_test_vnd_json(response, entity_refs, included, is_list, count, resource, pk, attributes, relationships,
check_ordering)

# application/json
else:
_test_regular_json(response, entity_refs, included, is_list, count, attributes, relationships, check_ordering)


def assert_200(response, vnd=True, entity_refs=None, included=None, is_list=False, count=None, check_ordering=False,
resource=None, pk=None, attributes=None, relationships=None):
assert response is not None
assert response.status_code == status.HTTP_200_OK, f'status_code {response.status_code} != 200'
Expand All @@ -281,7 +337,9 @@ def assert_200(response, vnd=True, entity_refs=None, included=None, is_list=Fals
vnd=vnd,
resource=resource,
pk=pk,
entity_refs=entity_refs)
entity_refs=entity_refs,
count=count,
check_ordering=check_ordering)


def assert_201(response, vnd=True, entity_refs=None, included=None, is_list=False,
Expand Down Expand Up @@ -319,28 +377,34 @@ def assert_204(response):
assert response.status_code == status.HTTP_204_NO_CONTENT, f'status_code {response.status_code} != 204'


def assert_400(response, error=None, pointer=None):
def assert_400(response, error=None, pointer=None, vnd=True):
assert response is not None
assert response.status_code == status.HTTP_400_BAD_REQUEST, f'status_code {response.status_code} != 400'
response_has_error(response, error, pointer)
response_has_error(response, error, pointer, vnd)


def assert_401(response, error='Authentication credentials were not provided'):
def assert_401(response, error='Authentication credentials were not provided', vnd=True):
assert response is not None
assert response.status_code == status.HTTP_401_UNAUTHORIZED, f'status_code {response.status_code} != 401'
response_has_error(response, error)
response_has_error(response, error, vnd=vnd)


def assert_403(response, error='You do not have permission to perform this action'):
def assert_403(response, error='You do not have permission to perform this action', vnd=True):
assert response is not None
assert response.status_code == status.HTTP_403_FORBIDDEN, f'status_code {response.status_code} != 403'
response_has_error(response, error)
response_has_error(response, error, vnd=vnd)


def assert_404(response, error='Not found', pointer=None):
def assert_404(response, error='Not found', pointer=None, vnd=True):
assert response is not None
assert response.status_code == status.HTTP_404_NOT_FOUND, f'status_code {response.status_code} != 404'
response_has_error(response, error, pointer)
response_has_error(response, error, pointer, vnd)


def assert_405(response, error='Method not allowed', pointer=None, vnd=True):
assert response is not None
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED, f'status_code {response.status_code} != 405'
response_has_error(response, error, pointer, vnd)


def assert_500(response, error='A server error occurred.', pointer=None):
Expand All @@ -367,6 +431,7 @@ class AssertionHelper:
HTTP_401 = assert_401
HTTP_403 = assert_403
HTTP_404 = assert_404
HTTP_405 = assert_405

HTTP_500 = assert_500
HTTP_503 = assert_503
Expand Down
Loading