From 9544e6f7c1f0c0585bc8841498afc27fad0774c1 Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Fri, 31 Jul 2020 15:24:42 +0200 Subject: [PATCH] Extract query function from GraphQLTestCase Making it possible to use in a pytest fixture --- graphene_django/tests/test_utils.py | 13 +++++ graphene_django/utils/testing.py | 90 +++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 23 deletions(-) diff --git a/graphene_django/tests/test_utils.py b/graphene_django/tests/test_utils.py index c0d376b..9707272 100644 --- a/graphene_django/tests/test_utils.py +++ b/graphene_django/tests/test_utils.py @@ -6,6 +6,7 @@ from mock import patch from ..utils import camelize, get_model_fields, GraphQLTestCase from .models import Film, Reporter +from ..utils.testing import graphql_query def test_get_model_fields_no_duplication(): @@ -58,3 +59,15 @@ def test_graphql_test_case_op_name(post_mock): "operationName", "QueryName", ) in body.items(), "Field 'operationName' is not present in the final request." + + +@pytest.mark.django_db +@patch("graphene_django.utils.testing.Client.post") +def test_graphql_query_case_op_name(post_mock): + graphql_query("query { }", op_name="QueryName") + body = json.loads(post_mock.call_args.args[1]) + # `operationName` field from https://graphql.org/learn/serving-over-http/#post-request + assert ( + "operationName", + "QueryName", + ) in body.items(), "Field 'operationName' is not present in the final request." diff --git a/graphene_django/utils/testing.py b/graphene_django/utils/testing.py index 0f68a51..3783c35 100644 --- a/graphene_django/utils/testing.py +++ b/graphene_django/utils/testing.py @@ -2,6 +2,63 @@ import json from django.test import TestCase, Client +DEFAULT_GRAPHQL_URL = "/graphql/" + + +def graphql_query( + query, + op_name=None, + input_data=None, + variables=None, + headers=None, + client=None, + graphql_url=None, +): + """ + Args: + query (string) - GraphQL query to run + op_name (string) - If the query is a mutation or named query, you must + supply the op_name. For annon queries ("{ ... }"), + should be None (default). + input_data (dict) - If provided, the $input variable in GraphQL will be set + to this value. If both ``input_data`` and ``variables``, + are provided, the ``input`` field in the ``variables`` + dict will be overwritten with this value. + variables (dict) - If provided, the "variables" field in GraphQL will be + set to this value. + headers (dict) - If provided, the headers in POST request to GRAPHQL_URL + will be set to this value. + client (django.test.Client) - Test client. Defaults to django.test.Client. + graphql_url (string) - URL to graphql endpoint. Defaults to "/graphql". + + Returns: + Response object from client + """ + if client is None: + client = Client() + if not graphql_url: + graphql_url = DEFAULT_GRAPHQL_URL + + body = {"query": query} + if op_name: + body["operationName"] = op_name + if variables: + body["variables"] = variables + if input_data: + if variables in body: + body["variables"]["input"] = input_data + else: + body["variables"] = {"input": input_data} + if headers: + resp = client.post( + graphql_url, json.dumps(body), content_type="application/json", **headers + ) + else: + resp = client.post( + graphql_url, json.dumps(body), content_type="application/json" + ) + return resp + class GraphQLTestCase(TestCase): """ @@ -9,7 +66,7 @@ class GraphQLTestCase(TestCase): """ # URL to graphql endpoint - GRAPHQL_URL = "/graphql/" + GRAPHQL_URL = DEFAULT_GRAPHQL_URL # Here you need to set your graphql schema for the tests GRAPHQL_SCHEMA = None @@ -43,28 +100,15 @@ class GraphQLTestCase(TestCase): Returns: Response object from client """ - body = {"query": query} - if op_name: - body["operationName"] = op_name - if variables: - body["variables"] = variables - if input_data: - if variables in body: - body["variables"]["input"] = input_data - else: - body["variables"] = {"input": input_data} - if headers: - resp = self._client.post( - self.GRAPHQL_URL, - json.dumps(body), - content_type="application/json", - **headers - ) - else: - resp = self._client.post( - self.GRAPHQL_URL, json.dumps(body), content_type="application/json" - ) - return resp + return graphql_query( + query, + op_name=op_name, + input_data=input_data, + variables=variables, + headers=headers, + client=self._client, + graphql_url=self.GRAPHQL_URL, + ) def assertResponseNoErrors(self, resp): """