Skip to content

Commit e39398a

Browse files
r-owenKingDarBoja
andauthored
Fix enable_async for aiohttp and sanic if graphiql is enabled (#67)
* Fix enable_async=True in aiohttp Apply the fix suggested by ketanbshah in #64 * Apply the same fix to sanic * tests: add tests for graphiql enabled plus async Co-authored-by: Manuel Bojato <[email protected]> Co-authored-by: KingDarBoja <[email protected]>
1 parent 49f73c3 commit e39398a

File tree

6 files changed

+120
-11
lines changed

6 files changed

+120
-11
lines changed

graphql_server/aiohttp/graphqlview.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import List
55

66
from aiohttp import web
7-
from graphql import GraphQLError
7+
from graphql import ExecutionResult, GraphQLError
88
from graphql.type.schema import GraphQLSchema
99

1010
from graphql_server import (
@@ -152,7 +152,10 @@ async def __call__(self, request):
152152
)
153153

154154
exec_res = (
155-
[await ex for ex in execution_results]
155+
[
156+
ex if ex is None or isinstance(ex, ExecutionResult) else await ex
157+
for ex in execution_results
158+
]
156159
if self.enable_async
157160
else execution_results
158161
)

graphql_server/sanic/graphqlview.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from functools import partial
55
from typing import List
66

7-
from graphql import GraphQLError
7+
from graphql import ExecutionResult, GraphQLError
88
from graphql.type.schema import GraphQLSchema
99
from sanic.response import HTTPResponse, html
1010
from sanic.views import HTTPMethodView
@@ -105,7 +105,12 @@ async def dispatch_request(self, request, *args, **kwargs):
105105
middleware=self.get_middleware(),
106106
)
107107
exec_res = (
108-
[await ex for ex in execution_results]
108+
[
109+
ex
110+
if ex is None or isinstance(ex, ExecutionResult)
111+
else await ex
112+
for ex in execution_results
113+
]
109114
if self.enable_async
110115
else execution_results
111116
)

tests/aiohttp/schema.py

+18
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,22 @@ def resolver_field_sync(_obj, info):
9191
)
9292

9393

94+
def resolver_field_sync_1(_obj, info):
95+
return "synced_one"
96+
97+
98+
def resolver_field_sync_2(_obj, info):
99+
return "synced_two"
100+
101+
102+
SyncQueryType = GraphQLObjectType(
103+
"SyncQueryType",
104+
{
105+
"a": GraphQLField(GraphQLString, resolve=resolver_field_sync_1),
106+
"b": GraphQLField(GraphQLString, resolve=resolver_field_sync_2),
107+
},
108+
)
109+
110+
94111
AsyncSchema = GraphQLSchema(AsyncQueryType)
112+
SyncSchema = GraphQLSchema(SyncQueryType)

tests/aiohttp/test_graphiqlview.py

+44-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from jinja2 import Environment
44

55
from tests.aiohttp.app import create_app, url_string
6-
from tests.aiohttp.schema import AsyncSchema, Schema
6+
from tests.aiohttp.schema import AsyncSchema, Schema, SyncSchema
77

88

99
@pytest.fixture
@@ -102,11 +102,51 @@ async def test_graphiql_get_subscriptions(app, client):
102102

103103

104104
@pytest.mark.asyncio
105-
@pytest.mark.parametrize("app", [create_app(schema=AsyncSchema, enable_async=True)])
106-
async def test_graphiql_async_schema(app, client):
105+
@pytest.mark.parametrize(
106+
"app", [create_app(schema=AsyncSchema, enable_async=True, graphiql=True)]
107+
)
108+
async def test_graphiql_enabled_async_schema(app, client):
107109
response = await client.get(
108110
url_string(query="{a,b,c}"), headers={"Accept": "text/html"},
109111
)
110112

113+
expected_response = (
114+
(
115+
"{\n"
116+
' "data": {\n'
117+
' "a": "hey",\n'
118+
' "b": "hey2",\n'
119+
' "c": "hey3"\n'
120+
" }\n"
121+
"}"
122+
)
123+
.replace('"', '\\"')
124+
.replace("\n", "\\n")
125+
)
126+
assert response.status == 200
127+
assert expected_response in await response.text()
128+
129+
130+
@pytest.mark.asyncio
131+
@pytest.mark.parametrize(
132+
"app", [create_app(schema=SyncSchema, enable_async=True, graphiql=True)]
133+
)
134+
async def test_graphiql_enabled_sync_schema(app, client):
135+
response = await client.get(
136+
url_string(query="{a,b}"), headers={"Accept": "text/html"},
137+
)
138+
139+
expected_response = (
140+
(
141+
"{\n"
142+
' "data": {\n'
143+
' "a": "synced_one",\n'
144+
' "b": "synced_two"\n'
145+
" }\n"
146+
"}"
147+
)
148+
.replace('"', '\\"')
149+
.replace("\n", "\\n")
150+
)
111151
assert response.status == 200
112-
assert await response.json() == {"data": {"a": "hey", "b": "hey2", "c": "hey3"}}
152+
assert expected_response in await response.text()

tests/sanic/schema.py

+18
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,22 @@ def resolver_field_sync(_obj, info):
7878
},
7979
)
8080

81+
82+
def resolver_field_sync_1(_obj, info):
83+
return "synced_one"
84+
85+
86+
def resolver_field_sync_2(_obj, info):
87+
return "synced_two"
88+
89+
90+
SyncQueryType = GraphQLObjectType(
91+
"SyncQueryType",
92+
{
93+
"a": GraphQLField(GraphQLString, resolve=resolver_field_sync_1),
94+
"b": GraphQLField(GraphQLString, resolve=resolver_field_sync_2),
95+
},
96+
)
97+
8198
AsyncSchema = GraphQLSchema(AsyncQueryType)
99+
SyncSchema = GraphQLSchema(SyncQueryType)

tests/sanic/test_graphiqlview.py

+28-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from jinja2 import Environment
33

44
from .app import create_app, url_string
5-
from .schema import AsyncSchema
5+
from .schema import AsyncSchema, SyncSchema
66

77

88
@pytest.fixture
@@ -62,9 +62,9 @@ def test_graphiql_html_is_not_accepted(app):
6262

6363

6464
@pytest.mark.parametrize(
65-
"app", [create_app(graphiql=True, schema=AsyncSchema, enable_async=True)]
65+
"app", [create_app(schema=AsyncSchema, enable_async=True, graphiql=True)]
6666
)
67-
def test_graphiql_asyncio_schema(app):
67+
def test_graphiql_enabled_async_schema(app):
6868
query = "{a,b,c}"
6969
_, response = app.client.get(
7070
uri=url_string(query=query), headers={"Accept": "text/html"}
@@ -86,3 +86,28 @@ def test_graphiql_asyncio_schema(app):
8686

8787
assert response.status == 200
8888
assert expected_response in response.body.decode("utf-8")
89+
90+
91+
@pytest.mark.parametrize(
92+
"app", [create_app(schema=SyncSchema, enable_async=True, graphiql=True)]
93+
)
94+
def test_graphiql_enabled_sync_schema(app):
95+
query = "{a,b}"
96+
_, response = app.client.get(
97+
uri=url_string(query=query), headers={"Accept": "text/html"}
98+
)
99+
100+
expected_response = (
101+
(
102+
"{\n"
103+
' "data": {\n'
104+
' "a": "synced_one",\n'
105+
' "b": "synced_two"\n'
106+
" }\n"
107+
"}"
108+
)
109+
.replace('"', '\\"')
110+
.replace("\n", "\\n")
111+
)
112+
assert response.status == 200
113+
assert expected_response in response.body.decode("utf-8")

0 commit comments

Comments
 (0)