diff --git a/README.md b/README.md index 3aa069c..37fa459 100644 --- a/README.md +++ b/README.md @@ -184,3 +184,9 @@ json_asserter.HTTP_200(response, "is_active": False }]) ``` + +#### Mixin Usage + +If there is a class where every test may wish to use the `json_asserter`, than it may be easier to use to the `JsonAsserterMixin` found in `shipchain_common.test_utils`. +This will automatically add the `json_asserter` and set it as a class attribute before the tests are run. +This allows you to just call `self.json_asserter`, allowing for cleaner unit tests imports. diff --git a/src/shipchain_common/test_utils/__init__.py b/src/shipchain_common/test_utils/__init__.py index 9144db7..62e9efd 100644 --- a/src/shipchain_common/test_utils/__init__.py +++ b/src/shipchain_common/test_utils/__init__.py @@ -17,7 +17,8 @@ from .json_asserter import \ json_asserter, \ - AssertionHelper + AssertionHelper, \ + JsonAsserterMixin from .helpers import\ create_form_content, \ diff --git a/src/shipchain_common/test_utils/json_asserter.py b/src/shipchain_common/test_utils/json_asserter.py index 35bf287..38872da 100644 --- a/src/shipchain_common/test_utils/json_asserter.py +++ b/src/shipchain_common/test_utils/json_asserter.py @@ -341,3 +341,9 @@ class AssertionHelper: @pytest.fixture(scope='session') def json_asserter(): return AssertionHelper + + +class JsonAsserterMixin: + @pytest.fixture(autouse=True) + def set_json_asserter(self, json_asserter): + self.json_asserter = json_asserter diff --git a/tests/test_json_asserter.py b/tests/test_json_asserter.py index d3e2e56..9bd91ea 100644 --- a/tests/test_json_asserter.py +++ b/tests/test_json_asserter.py @@ -3,7 +3,7 @@ import pytest from rest_framework import status -from shipchain_common.test_utils import AssertionHelper +from shipchain_common.test_utils import AssertionHelper, JsonAsserterMixin EXAMPLE_PLAIN = { 'id': '07b374c3-ed9b-4811-901a-d0c5d746f16a', @@ -77,6 +77,122 @@ } +@pytest.fixture +def vnd_single(): + return { + 'data': { + 'type': EXAMPLE_RESOURCE['type'], + 'id': EXAMPLE_RESOURCE['id'], + 'attributes': EXAMPLE_RESOURCE['attributes'], + 'relationships': { + 'owner': { + 'data': { + 'type': EXAMPLE_USER['type'], + 'id': EXAMPLE_USER['id'] + } + }, + 'children': { + 'meta': { + 'count': 2 + }, + 'data': [ + { + 'type': EXAMPLE_RESOURCE_2['type'], + 'id': EXAMPLE_RESOURCE_2['id'] + }, + { + 'type': EXAMPLE_RESOURCE_4['type'], + 'id': EXAMPLE_RESOURCE_4['id'] + } + ] + } + } + }, + 'included': [ + EXAMPLE_USER, + EXAMPLE_RESOURCE_2, + EXAMPLE_RESOURCE_4 + ] + } + + +@pytest.fixture +def vnd_list(): + return { + 'data': [ + { + 'type': EXAMPLE_RESOURCE['type'], + 'id': EXAMPLE_RESOURCE['id'], + 'attributes': EXAMPLE_RESOURCE['attributes'], + 'relationships': { + 'owner': { + 'data': { + 'type': EXAMPLE_USER['type'], + 'id': EXAMPLE_USER['id'] + } + }, + 'children': { + 'meta': { + 'count': 1 + }, + 'data': [ + { + 'type': EXAMPLE_RESOURCE_2['type'], + 'id': EXAMPLE_RESOURCE_2['id'] + } + ] + } + } + }, + { + 'type': EXAMPLE_RESOURCE_3['type'], + 'id': EXAMPLE_RESOURCE_3['id'], + 'attributes': EXAMPLE_RESOURCE_3['attributes'], + 'relationships': { + 'owner': { + 'data': { + 'type': EXAMPLE_USER['type'], + 'id': EXAMPLE_USER['id'] + } + }, + 'children': { + 'meta': { + 'count': 1 + }, + 'data': [ + { + 'type': EXAMPLE_RESOURCE_2['type'], + 'id': EXAMPLE_RESOURCE_2['id'] + } + ] + } + } + }, + ], + 'included': [ + EXAMPLE_USER, + EXAMPLE_RESOURCE_2 + ] + } + + +@pytest.fixture +def vnd_error(): + return { + 'errors': [ + { + 'detail': '' + } + ] + } + + +@pytest.fixture +def vnd_error_400(vnd_error): + vnd_error['errors'][0]['detail'] = 'generic 400 error' + return vnd_error + + class TestAssertionHelper: @pytest.fixture(scope='session') @@ -89,118 +205,6 @@ def _build_response(data, status_code=status.HTTP_200_OK): return Mock(status_code=status_code, json=lambda: data) self.build_response = _build_response - @pytest.fixture - def vnd_single(self): - return { - 'data': { - 'type': EXAMPLE_RESOURCE['type'], - 'id': EXAMPLE_RESOURCE['id'], - 'attributes': EXAMPLE_RESOURCE['attributes'], - 'relationships': { - 'owner': { - 'data': { - 'type': EXAMPLE_USER['type'], - 'id': EXAMPLE_USER['id'] - } - }, - 'children': { - 'meta': { - 'count': 2 - }, - 'data': [ - { - 'type': EXAMPLE_RESOURCE_2['type'], - 'id': EXAMPLE_RESOURCE_2['id'] - }, - { - 'type': EXAMPLE_RESOURCE_4['type'], - 'id': EXAMPLE_RESOURCE_4['id'] - } - ] - } - } - }, - 'included': [ - EXAMPLE_USER, - EXAMPLE_RESOURCE_2, - EXAMPLE_RESOURCE_4 - ] - } - - @pytest.fixture - def vnd_list(self): - return { - 'data': [ - { - 'type': EXAMPLE_RESOURCE['type'], - 'id': EXAMPLE_RESOURCE['id'], - 'attributes': EXAMPLE_RESOURCE['attributes'], - 'relationships': { - 'owner': { - 'data': { - 'type': EXAMPLE_USER['type'], - 'id': EXAMPLE_USER['id'] - } - }, - 'children': { - 'meta': { - 'count': 1 - }, - 'data': [ - { - 'type': EXAMPLE_RESOURCE_2['type'], - 'id': EXAMPLE_RESOURCE_2['id'] - } - ] - } - } - }, - { - 'type': EXAMPLE_RESOURCE_3['type'], - 'id': EXAMPLE_RESOURCE_3['id'], - 'attributes': EXAMPLE_RESOURCE_3['attributes'], - 'relationships': { - 'owner': { - 'data': { - 'type': EXAMPLE_USER['type'], - 'id': EXAMPLE_USER['id'] - } - }, - 'children': { - 'meta': { - 'count': 1 - }, - 'data': [ - { - 'type': EXAMPLE_RESOURCE_2['type'], - 'id': EXAMPLE_RESOURCE_2['id'] - } - ] - } - } - }, - ], - 'included': [ - EXAMPLE_USER, - EXAMPLE_RESOURCE_2 - ] - } - - @pytest.fixture - def vnd_error(self): - return { - 'errors': [ - { - 'detail': '' - } - ] - } - - @pytest.fixture - def vnd_error_400(self, vnd_error): - vnd_error['errors'][0]['detail'] = 'generic 400 error' - return vnd_error - @pytest.fixture def vnd_error_401(self, vnd_error): vnd_error['errors'][0]['detail'] = 'Authentication credentials were not provided' @@ -837,3 +841,23 @@ def test_plain_json_attributes_list_nested_mismatch(self, json_asserter): with pytest.raises(AssertionError) as err: json_asserter.HTTP_200(response, vnd=False, is_list=True, attributes=invalid_attributes) assert f'{invalid_attributes} NOT IN ' in str(err.value) + + +class TestJsonAsserterMixin(JsonAsserterMixin): + def test_has_asserter(self): + assert hasattr(self, 'json_asserter') + + @pytest.fixture(autouse=True) + def make_build_response(self): + def _build_response(data, status_code=status.HTTP_200_OK): + return Mock(status_code=status_code, json=lambda: data) + self.build_response = _build_response + + def test_status_200(self, vnd_single, vnd_error_400): + response = self.build_response(vnd_single) + self.json_asserter.HTTP_200(response) + + with pytest.raises(AssertionError) as err: + response = self.build_response(vnd_error_400, status_code=status.HTTP_400_BAD_REQUEST) + self.json_asserter.HTTP_200(response) + assert 'status_code 400 != 200' in str(err.value)