From d47f1d544eba4dbf681cdac6e51e91858df6b291 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Sat, 3 Oct 2015 13:27:19 -0700 Subject: [PATCH] Improved django GraphQL view testing --- graphene/contrib/django/views.py | 33 +++++++---- tests/contrib_django/test_urls.py | 34 +++++++++++ tests/contrib_django/test_views.py | 94 ++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 12 deletions(-) create mode 100644 tests/contrib_django/test_urls.py create mode 100644 tests/contrib_django/test_views.py diff --git a/graphene/contrib/django/views.py b/graphene/contrib/django/views.py index a2f813e1..b4482c62 100644 --- a/graphene/contrib/django/views.py +++ b/graphene/contrib/django/views.py @@ -24,13 +24,16 @@ class GraphQLView(View): return data + def response_errors(self, *errors): + return JsonResponse({ + "errors": [{ + "message": str(e) + } for e in errors] + }) + def execute_query(self, request, query): if not query: - data = { - "errors": [{ - "message": "Must provide query string." - }] - } + return self.response_errors(Exception("Must provide query string.")) else: try: result = self.schema.execute(query, root=object()) @@ -38,9 +41,7 @@ class GraphQLView(View): except Exception, e: if settings.DEBUG: raise e - data = { - "errors": [{"message": str(e)}] - } + return self.response_errors(e) return JsonResponse(data) @@ -48,11 +49,19 @@ class GraphQLView(View): query = request.GET.get('query') return self.execute_query(request, query or '') + @staticmethod + def get_content_type(request): + meta = request.META + return meta.get('CONTENT_TYPE', meta.get('HTTP_CONTENT_TYPE', '')) + def post(self, request, *args, **kwargs): - if request.body: - received_json_data = json.loads(request.body) - query = received_json_data.get('query') + content_type = self.get_content_type(request) + if content_type == 'application/json': + try: + received_json_data = json.loads(request.body) + query = received_json_data.get('query') + except ValueError, e: + return self.response_errors(ValueError("Malformed json body in the post data")) else: query = request.POST.get('query') or request.GET.get('query') - raise Exception(query) return self.execute_query(request, query or '') diff --git a/tests/contrib_django/test_urls.py b/tests/contrib_django/test_urls.py new file mode 100644 index 00000000..6d0bca57 --- /dev/null +++ b/tests/contrib_django/test_urls.py @@ -0,0 +1,34 @@ +from django.conf.urls import url + +from graphene.contrib.django.views import GraphQLView + +from graphene import Schema +from graphene.contrib.django.types import ( + DjangoNode, + DjangoInterface +) + +from .models import Reporter, Article + + +class Character(DjangoNode): + class Meta: + model = Reporter + + def get_node(self, id): + pass + + +class Human(DjangoNode): + class Meta: + model = Article + + def get_node(self, id): + pass + +schema = Schema(query=Human) + + +urlpatterns = [ + url(r'^graphql', GraphQLView.as_view(schema=schema)), +] diff --git a/tests/contrib_django/test_views.py b/tests/contrib_django/test_views.py new file mode 100644 index 00000000..bfd1efc3 --- /dev/null +++ b/tests/contrib_django/test_views.py @@ -0,0 +1,94 @@ +import json +import pytest +from py.test import raises +from collections import namedtuple +from pytest import raises +from graphene.core.fields import ( + Field, + StringField, +) +from graphql.core.type import ( + GraphQLObjectType, + GraphQLInterfaceType +) + +from graphene import Schema +from graphene.contrib.django.types import ( + DjangoNode, + DjangoInterface +) + + +def format_response(response): + return json.loads(response.content) + + +def test_client_get_no_query(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.get('/graphql') + json_response = format_response(response) + assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + + +def test_client_post_no_query(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.post('/graphql', {}) + print response.content + json_response = format_response(response) + assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + + +def test_client_post_malformed_json(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.post('/graphql', 'MALFORMED', 'application/json') + json_response = format_response(response) + assert json_response == {'errors': [{'message': 'Malformed json body in the post data'}]} + + +def test_client_post_empty_query(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.post('/graphql', json.dumps({'query': ''}), 'application/json') + json_response = format_response(response) + assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + + +def test_client_post_bad_query(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.post('/graphql', json.dumps({'query': '{ MALFORMED'}), 'application/json') + json_response = format_response(response) + assert 'errors' in json_response + assert len(json_response['errors']) == 1 + assert 'Syntax Error GraphQL' in json_response['errors'][0]['message'] + + +def test_client_get_good_query(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.get('/graphql', {'query': '{ headline }'}) + json_response = format_response(response) + expected_json = { + 'data': { + 'headline': None + } + } + assert json_response == expected_json + + +def test_client_post_good_query(settings, client): + settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' + response = client.post('/graphql', json.dumps({'query': '{ headline }'}), 'application/json') + json_response = format_response(response) + expected_json = { + 'data': { + 'headline': None + } + } + assert json_response == expected_json + + +# def test_client_get_bad_query(settings, client): +# settings.ROOT_URLCONF = 'tests.contrib_django.test_urls' +# response = client.get('/graphql') +# json_response = format_response(response) +# assert json_response == {'errors': [{'message': 'Must provide query string.'}]} + +