import sys import pytest from six import b from openapi_core.contrib.django import ( DjangoOpenAPIRequest, DjangoOpenAPIResponse, ) from openapi_core.shortcuts import create_spec from openapi_core.validation.request.datatypes import RequestParameters from openapi_core.validation.request.validators import RequestValidator from openapi_core.validation.response.validators import ResponseValidator @pytest.mark.skipif(sys.version_info < (3, 0), reason="requires python3") class BaseTestDjango(object): @pytest.fixture(autouse=True, scope='module') def django_settings(self): import django from django.conf import settings from django.contrib import admin from django.urls import path if settings.configured: return settings.configure( ALLOWED_HOSTS=[ 'testserver', ], INSTALLED_APPS=[ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.messages', 'django.contrib.sessions', ], MIDDLEWARE=[ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', ] ) django.setup() settings.ROOT_URLCONF = ( path('admin/', admin.site.urls), ) @pytest.fixture def request_factory(self): from django.test.client import RequestFactory return RequestFactory() @pytest.fixture def response_factory(self): from django.http import HttpResponse def create(content=b(''), status_code=None): return HttpResponse(content, status=status_code) return create class TestDjangoOpenAPIRequest(BaseTestDjango): def test_no_resolver(self, request_factory): request = request_factory.get('/admin/') openapi_request = DjangoOpenAPIRequest(request) path = {} query = {} headers = { 'Cookie': '', } cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) assert openapi_request.host_url == request._current_scheme_host assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() assert openapi_request.path_pattern == request.path assert openapi_request.body == request.body assert openapi_request.mimetype == request.content_type def test_simple(self, request_factory): from django.urls import resolve request = request_factory.get('/admin/') request.resolver_match = resolve('/admin/') openapi_request = DjangoOpenAPIRequest(request) path = {} query = {} headers = { 'Cookie': '', } cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) assert openapi_request.host_url == request._current_scheme_host assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() assert openapi_request.path_pattern == request.path assert openapi_request.body == request.body assert openapi_request.mimetype == request.content_type def test_url_rule(self, request_factory): from django.urls import resolve request = request_factory.get('/admin/auth/group/1/') request.resolver_match = resolve('/admin/auth/group/1/') openapi_request = DjangoOpenAPIRequest(request) path = { 'object_id': '1', } query = {} headers = { 'Cookie': '', } cookies = {} assert openapi_request.parameters == RequestParameters( path=path, query=query, header=headers, cookie=cookies, ) assert openapi_request.host_url == request._current_scheme_host assert openapi_request.path == request.path assert openapi_request.method == request.method.lower() assert openapi_request.path_pattern == \ "/admin/auth/group/{object_id}/" assert openapi_request.body == request.body assert openapi_request.mimetype == request.content_type class TestDjangoOpenAPIResponse(BaseTestDjango): def test_stream_response(self, response_factory): response = response_factory() response.writelines(['foo\n', 'bar\n', 'baz\n']) openapi_response = DjangoOpenAPIResponse(response) assert openapi_response.data == b('foo\nbar\nbaz\n') assert openapi_response.status_code == response.status_code assert openapi_response.mimetype == response["Content-Type"] def test_redirect_response(self, response_factory): response = response_factory('/redirected/', status_code=302) openapi_response = DjangoOpenAPIResponse(response) assert openapi_response.data == response.content assert openapi_response.status_code == response.status_code assert openapi_response.mimetype == response["Content-Type"] class TestDjangoOpenAPIValidation(BaseTestDjango): @pytest.fixture def django_spec(self, factory): specfile = 'data/v3.0/django_factory.yaml' return create_spec(factory.spec_from_file(specfile)) def test_response_validator_path_pattern( self, django_spec, request_factory, response_factory): from django.urls import resolve validator = ResponseValidator(django_spec) request = request_factory.get('/admin/auth/group/1/') request.resolver_match = resolve('/admin/auth/group/1/') openapi_request = DjangoOpenAPIRequest(request) response = response_factory(b('Some item')) openapi_response = DjangoOpenAPIResponse(response) result = validator.validate(openapi_request, openapi_response) assert not result.errors def test_request_validator_path_pattern( self, django_spec, request_factory): from django.urls import resolve validator = RequestValidator(django_spec) request = request_factory.get('/admin/auth/group/1/') request.resolver_match = resolve('/admin/auth/group/1/') openapi_request = DjangoOpenAPIRequest(request) result = validator.validate(openapi_request) assert not result.errors