From 0fc421455c30b506067327be40d1eb0b25148012 Mon Sep 17 00:00:00 2001 From: Darragh Duffy Date: Wed, 23 Nov 2022 22:23:27 +0000 Subject: [PATCH] example of failing test on related_field --- poetry.lock | 89 ++++++---------------- pyproject.toml | 2 + test_project/api/views/teams.py | 6 ++ test_project/urls.py | 8 +- tests/schemas/manual_reference_schema.yaml | 14 ++++ tests/test_django_framework.py | 32 ++++++++ 6 files changed, 86 insertions(+), 65 deletions(-) create mode 100644 test_project/api/views/teams.py create mode 100644 tests/test_django_framework.py diff --git a/poetry.lock b/poetry.lock index 9e5fa445..c6c4c669 100644 --- a/poetry.lock +++ b/poetry.lock @@ -41,17 +41,6 @@ docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] -[[package]] -name = "backports.zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "certifi" version = "2022.9.24" @@ -171,34 +160,33 @@ argon2 = ["argon2-cffi (>=19.1.0)"] bcrypt = ["bcrypt"] [[package]] -name = "Django" -version = "4.1.3" -description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." +name = "djangorestframework" +version = "3.12.4" +description = "Web APIs for Django, made easy." category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.5" [package.dependencies] -asgiref = ">=3.5.2,<4" -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} -sqlparse = ">=0.2.2" -tzdata = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -argon2 = ["argon2-cffi (>=19.1.0)"] -bcrypt = ["bcrypt"] +django = ">=2.2" [[package]] -name = "djangorestframework" -version = "3.14.0" -description = "Web APIs for Django, made easy." +name = "djangorestframework-jsonapi" +version = "4.2.1" +description = "A Django REST framework API adapter for the JSON API spec." category = "main" -optional = false +optional = true python-versions = ">=3.6" [package.dependencies] -django = ">=3.0" -pytz = "*" +django = ">=2.2,<3.3" +djangorestframework = ">=3.12,<3.13" +inflection = ">=0.3.0" + +[package.extras] +django-filter = ["django-filter (>=2.0)"] +django-polymorphic = ["django-polymorphic (>=2.0)"] +openapi = ["pyyaml (>=5.3)", "uritemplate (>=3.0.1)"] [[package]] name = "drf-spectacular" @@ -793,14 +781,6 @@ category = "main" optional = false python-versions = ">=3.7" -[[package]] -name = "tzdata" -version = "2022.6" -description = "Provider of IANA time zone data" -category = "main" -optional = false -python-versions = ">=2" - [[package]] name = "uritemplate" version = "4.1.1" @@ -861,13 +841,14 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] +djangorestframework-jsonapi = ["djangorestframework-jsonapi"] drf-spectacular = ["drf-spectacular"] drf-yasg = ["drf-yasg"] [metadata] lock-version = "1.1" python-versions = "^3.7" -content-hash = "d7dd4650d62970ec2522137937cbd498795c2a2c4afc49625535600c994acf34" +content-hash = "9ed6a286b186f811ff4df4fd1bdfac1da5b5647a79e25632a10a38d35a03c3a5" [metadata.files] asgiref = [ @@ -882,24 +863,6 @@ attrs = [ {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, ] -"backports.zoneinfo" = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] certifi = [ {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, @@ -991,12 +954,14 @@ distlib = [ Django = [ {file = "Django-3.2.16-py3-none-any.whl", hash = "sha256:18ba8efa36b69cfcd4b670d0fa187c6fe7506596f0ababe580e16909bcdec121"}, {file = "Django-3.2.16.tar.gz", hash = "sha256:3adc285124244724a394fa9b9839cc8cd116faf7d159554c43ecdaa8cdf0b94d"}, - {file = "Django-4.1.3-py3-none-any.whl", hash = "sha256:6b1de6886cae14c7c44d188f580f8ba8da05750f544c80ae5ad43375ab293cd5"}, - {file = "Django-4.1.3.tar.gz", hash = "sha256:678bbfc8604eb246ed54e2063f0765f13b321a50526bdc8cb1f943eda7fa31f1"}, ] djangorestframework = [ - {file = "djangorestframework-3.14.0-py3-none-any.whl", hash = "sha256:eb63f58c9f218e1a7d064d17a70751f528ed4e1d35547fdade9aaf4cd103fd08"}, - {file = "djangorestframework-3.14.0.tar.gz", hash = "sha256:579a333e6256b09489cbe0a067e66abe55c6595d8926be6b99423786334350c8"}, + {file = "djangorestframework-3.12.4-py3-none-any.whl", hash = "sha256:6d1d59f623a5ad0509fe0d6bfe93cbdfe17b8116ebc8eda86d45f6e16e819aaf"}, + {file = "djangorestframework-3.12.4.tar.gz", hash = "sha256:f747949a8ddac876e879190df194b925c177cdeb725a099db1460872f7c0a7f2"}, +] +djangorestframework-jsonapi = [ + {file = "djangorestframework-jsonapi-4.2.1.tar.gz", hash = "sha256:dc08a81af9f0d3676cac47d45f5edd4e4b59ac7f9723c5ef99b2e1a8ac453da8"}, + {file = "djangorestframework_jsonapi-4.2.1-py2.py3-none-any.whl", hash = "sha256:0463d4bd74233a9e64813571abb8c55fa38ced1dc0ea7875e98861eeb5a857ad"}, ] drf-spectacular = [ {file = "drf-spectacular-0.24.2.tar.gz", hash = "sha256:be32417594080a52f996afd83fd47ea9c2b83cbf13f6d3fbf3de809a0dfa7ead"}, @@ -1356,10 +1321,6 @@ typing-extensions = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] -tzdata = [ - {file = "tzdata-2022.6-py2.py3-none-any.whl", hash = "sha256:04a680bdc5b15750c39c12a448885a51134a27ec9af83667663f0b3a1bf3f342"}, - {file = "tzdata-2022.6.tar.gz", hash = "sha256:91f11db4503385928c15598c98573e3af07e7229181bee5375bd30f1695ddcae"}, -] uritemplate = [ {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, diff --git a/pyproject.toml b/pyproject.toml index e4badfd1..ce969f17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -57,10 +57,12 @@ prance = "*" pyYAML = "*" drf-spectacular = { version = "*", optional = true } drf-yasg = { version = "*", optional = true } +djangorestframework-jsonapi = { version = "*", optional = true } [tool.poetry.extras] drf-yasg = ["drf-yasg"] drf-spectacular = ["drf-spectacular"] +djangorestframework-jsonapi = ["djangorestframework-jsonapi"] [tool.poetry.dev-dependencies] coverage = { extras = ["toml"], version = "^6" } diff --git a/test_project/api/views/teams.py b/test_project/api/views/teams.py new file mode 100644 index 00000000..47cc1a54 --- /dev/null +++ b/test_project/api/views/teams.py @@ -0,0 +1,6 @@ +from rest_framework_json_api.views import RelationshipView +from rest_framework.views import Response + +class TeamMembersRelationshipView(RelationshipView): + def post(self, request, *args, **kwargs): + return Response({}, 200) \ No newline at end of file diff --git a/test_project/urls.py b/test_project/urls.py index 22eeb89f..0dd56875 100644 --- a/test_project/urls.py +++ b/test_project/urls.py @@ -1,5 +1,5 @@ from django.conf.urls.i18n import i18n_patterns -from django.urls import include, path +from django.urls import include, path, re_path from drf_yasg import openapi from drf_yasg.views import get_schema_view from rest_framework import permissions, routers @@ -13,6 +13,7 @@ from test_project.api.views.names import EmptyNameViewSet, NamesRetrieveView, NameViewSet from test_project.api.views.products import Products from test_project.api.views.snake_cased_response import SnakeCasedResponse +from test_project.api.views.teams import TeamMembersRelationshipView from test_project.api.views.trucks import BadTrucks, GoodTrucks from test_project.api.views.vehicles import Vehicles @@ -34,6 +35,11 @@ path("api//snake-case/", SnakeCasedResponse.as_view()), # ^trailing slash is here on purpose path("api//router_generated/", include(router.urls)), + re_path( + r"api/(?Pv\d+)/team/(?P\d+)/relationships/(?P[-\w]+)", + TeamMembersRelationshipView.as_view(), + name="team-members-relation", + ), ] internationalised_urlpatterns = i18n_patterns( diff --git a/tests/schemas/manual_reference_schema.yaml b/tests/schemas/manual_reference_schema.yaml index 367b0e77..04a46278 100644 --- a/tests/schemas/manual_reference_schema.yaml +++ b/tests/schemas/manual_reference_schema.yaml @@ -263,3 +263,17 @@ paths: responses: '200': description: '' + /api/v1/teams/{pk}/relationships/members: + post: + operationId: addTeamMembers + description: '' + parameters: + - in: path + name: pk + schema: + type: integer + description: A unique value identifying this team. + required: true + responses: + '200': + description: '' diff --git a/tests/test_django_framework.py b/tests/test_django_framework.py new file mode 100644 index 00000000..1f63a369 --- /dev/null +++ b/tests/test_django_framework.py @@ -0,0 +1,32 @@ +from openapi_tester import SchemaTester +from django.urls import reverse +from rest_framework.test import APITestCase +from rest_framework.response import Response +from tests.utils import TEST_ROOT + +schema_tester = SchemaTester(schema_file_path=str(TEST_ROOT) + "/schemas/manual_reference_schema.yaml") + +class BaseAPITestCase(APITestCase): + """Base test class for api views including schema validation""" + + @staticmethod + def assertResponse(response: Response, **kwargs) -> None: + """helper to run validate_response and pass kwargs to it""" + schema_tester.validate_response(response=response, **kwargs) + +# @override_settings(USE_X_FORWARDED_HOST=True) +class TeamsAPITests(BaseAPITestCase): + def test_schema_using_assert_response(self): + response = self.client.post( + reverse( + "team-members-relation", + kwargs={ + "version": "v1", + "pk": 1, + "related_field": "members", + }, + ), + content_type="application/vnd.api+json", + ) + self.assertEqual(response.status_code, 200) + self.assertResponse(response) \ No newline at end of file