1
+ import inspect
1
2
from typing import Awaitable , cast
2
3
3
4
import pytest
5
+ from graphql import subscribe
4
6
from graphql .execution import Middleware , MiddlewareManager , execute
5
7
from graphql .language .parser import parse
6
8
from graphql .type import GraphQLField , GraphQLObjectType , GraphQLSchema , GraphQLString
7
9
8
- def _create_schema (tp : GraphQLObjectType , is_subscription : bool ) -> GraphQLSchema :
10
+
11
+ def _create_schema (
12
+ tp : GraphQLObjectType , is_subscription : bool = False
13
+ ) -> GraphQLSchema :
9
14
if is_subscription :
10
- noop_type = GraphQLObjectType ("Noop" , {"noop" : GraphQLField (GraphQLString , resolve = lambda * _ : "noop" )})
15
+ noop_type = GraphQLObjectType (
16
+ "Noop" , {"noop" : GraphQLField (GraphQLString , resolve = lambda * _ : "noop" )}
17
+ )
11
18
return GraphQLSchema (query = noop_type , subscription = tp )
12
19
return GraphQLSchema (tp )
13
- @pytest .mark .parametrize ("is_subscription" , [False , True ], ids = ["query" , "subscription" ])
14
- def test_describe_middleware (is_subscription : bool ):
15
20
16
- def test_test_describe_with_manager ():
17
- def test_default ():
21
+
22
+ def describe_middleware ():
23
+ def describe_with_manager ():
24
+ def default ():
18
25
doc = parse ("{ field }" )
19
26
20
27
# noinspection PyMethodMayBeStatic
21
28
class Data :
22
- def test_field (self , _info ):
29
+ def field (self , _info ):
23
30
return "resolved"
24
31
25
32
test_type = GraphQLObjectType (
@@ -28,20 +35,20 @@ def test_field(self, _info):
28
35
29
36
middlewares = MiddlewareManager ()
30
37
result = execute (
31
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
38
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
32
39
)
33
40
34
41
assert result .data ["field" ] == "resolved" # type: ignore
35
42
36
- def test_single_function ():
43
+ def single_function ():
37
44
doc = parse ("{ first second }" )
38
45
39
46
# noinspection PyMethodMayBeStatic
40
47
class Data :
41
- def test_first (self , _info ):
48
+ def first (self , _info ):
42
49
return "one"
43
50
44
- def test_second (self , _info ):
51
+ def second (self , _info ):
45
52
return "two"
46
53
47
54
test_type = GraphQLObjectType (
@@ -57,12 +64,12 @@ def reverse_middleware(next_, *args, **kwargs):
57
64
58
65
middlewares = MiddlewareManager (reverse_middleware )
59
66
result = execute (
60
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
67
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
61
68
)
62
69
63
70
assert result .data == {"first" : "eno" , "second" : "owt" } # type: ignore
64
71
65
- def test_two_functions_and_field_resolvers ():
72
+ def two_functions_and_field_resolvers ():
66
73
doc = parse ("{ first second }" )
67
74
68
75
# noinspection PyMethodMayBeStatic
@@ -90,21 +97,21 @@ def capitalize_middleware(next_, *args, **kwargs):
90
97
91
98
middlewares = MiddlewareManager (reverse_middleware , capitalize_middleware )
92
99
result = execute (
93
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
100
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
94
101
)
95
102
96
103
assert result .data == {"first" : "Eno" , "second" : "Owt" } # type: ignore
97
104
98
105
@pytest .mark .asyncio ()
99
- async def test_single_async_function ():
106
+ async def single_async_function ():
100
107
doc = parse ("{ first second }" )
101
108
102
109
# noinspection PyMethodMayBeStatic
103
110
class Data :
104
- async def test_first (self , _info ):
111
+ async def first (self , _info ):
105
112
return "one"
106
113
107
- async def test_second (self , _info ):
114
+ async def second (self , _info ):
108
115
return "two"
109
116
110
117
test_type = GraphQLObjectType (
@@ -120,21 +127,21 @@ async def reverse_middleware(next_, *args, **kwargs):
120
127
121
128
middlewares = MiddlewareManager (reverse_middleware )
122
129
awaitable_result = execute (
123
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
130
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
124
131
)
125
132
assert isinstance (awaitable_result , Awaitable )
126
133
result = await awaitable_result
127
134
assert result .data == {"first" : "eno" , "second" : "owt" }
128
135
129
- def test_single_object ():
136
+ def single_object ():
130
137
doc = parse ("{ first second }" )
131
138
132
139
# noinspection PyMethodMayBeStatic
133
140
class Data :
134
- def test_first (self , _info ):
141
+ def first (self , _info ):
135
142
return "one"
136
143
137
- def test_second (self , _info ):
144
+ def second (self , _info ):
138
145
return "two"
139
146
140
147
test_type = GraphQLObjectType (
@@ -147,17 +154,17 @@ def test_second(self, _info):
147
154
148
155
class ReverseMiddleware :
149
156
# noinspection PyMethodMayBeStatic
150
- def test_resolve (self , next_ , * args , ** kwargs ):
157
+ def resolve (self , next_ , * args , ** kwargs ):
151
158
return next_ (* args , ** kwargs )[::- 1 ]
152
159
153
160
middlewares = MiddlewareManager (ReverseMiddleware ())
154
161
result = execute (
155
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
162
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
156
163
)
157
164
158
165
assert result .data == {"first" : "eno" , "second" : "owt" } # type: ignore
159
166
160
- def test_skip_middleware_without_resolve_method ():
167
+ def skip_middleware_without_resolve_method ():
161
168
class BadMiddleware :
162
169
pass # no resolve method here
163
170
@@ -173,12 +180,12 @@ class BadMiddleware:
173
180
middleware = MiddlewareManager (BadMiddleware ()),
174
181
) == ({"foo" : "bar" }, None )
175
182
176
- def test_with_function_and_object ():
183
+ def with_function_and_object ():
177
184
doc = parse ("{ field }" )
178
185
179
186
# noinspection PyMethodMayBeStatic
180
187
class Data :
181
- def test_field (self , _info ):
188
+ def field (self , _info ):
182
189
return "resolved"
183
190
184
191
test_type = GraphQLObjectType (
@@ -190,28 +197,28 @@ def reverse_middleware(next_, *args, **kwargs):
190
197
191
198
class CaptitalizeMiddleware :
192
199
# noinspection PyMethodMayBeStatic
193
- def test_resolve (self , next_ , * args , ** kwargs ):
200
+ def resolve (self , next_ , * args , ** kwargs ):
194
201
return next_ (* args , ** kwargs ).capitalize ()
195
202
196
203
middlewares = MiddlewareManager (reverse_middleware , CaptitalizeMiddleware ())
197
204
result = execute (
198
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
205
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
199
206
)
200
207
assert result .data == {"field" : "Devloser" } # type: ignore
201
208
202
209
middlewares = MiddlewareManager (CaptitalizeMiddleware (), reverse_middleware )
203
210
result = execute (
204
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
211
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
205
212
)
206
213
assert result .data == {"field" : "devloseR" } # type: ignore
207
214
208
215
@pytest .mark .asyncio ()
209
- async def test_with_async_function_and_object ():
216
+ async def with_async_function_and_object ():
210
217
doc = parse ("{ field }" )
211
218
212
219
# noinspection PyMethodMayBeStatic
213
220
class Data :
214
- async def test_field (self , _info ):
221
+ async def field (self , _info ):
215
222
return "resolved"
216
223
217
224
test_type = GraphQLObjectType (
@@ -228,54 +235,86 @@ async def test_resolve(self, next_, *args, **kwargs):
228
235
229
236
middlewares = MiddlewareManager (reverse_middleware , CaptitalizeMiddleware ())
230
237
awaitable_result = execute (
231
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
238
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
232
239
)
233
240
assert isinstance (awaitable_result , Awaitable )
234
241
result = await awaitable_result
235
242
assert result .data == {"field" : "Devloser" }
236
243
237
244
middlewares = MiddlewareManager (CaptitalizeMiddleware (), reverse_middleware )
238
245
awaitable_result = execute (
239
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
246
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
240
247
)
241
248
assert isinstance (awaitable_result , Awaitable )
242
249
result = await awaitable_result
243
250
assert result .data == {"field" : "devloseR" }
244
251
245
- def test_describe_without_manager ():
246
- def test_no_middleware ():
252
+ @pytest .mark .asyncio ()
253
+ async def subscription_simple ():
254
+ async def bar_resolve (_obj , _info ):
255
+ yield "bar"
256
+
257
+ test_type = GraphQLObjectType (
258
+ "Subscription" ,
259
+ {
260
+ "bar" : GraphQLField (
261
+ GraphQLString ,
262
+ resolve = lambda message , _ : message ,
263
+ subscribe = bar_resolve ,
264
+ ),
265
+ },
266
+ )
267
+ doc = parse ("subscription { bar }" )
268
+
269
+ async def reverse_middleware (next_ , value , info , ** kwargs ):
270
+ awaitable_maybe = next_ (value , info , ** kwargs )
271
+ if inspect .isawaitable (awaitable_maybe ):
272
+ return (await awaitable_maybe )[::- 1 ]
273
+ return awaitable_maybe [::- 1 ]
274
+
275
+ agen = subscribe (
276
+ _create_schema (test_type , is_subscription = True ),
277
+ doc ,
278
+ middleware = MiddlewareManager (reverse_middleware ),
279
+ )
280
+ assert inspect .isasyncgen (agen )
281
+ data = (await agen .__anext__ ()).data
282
+ assert data == {"bar" : "rab" }
283
+
284
+ def describe_without_manager ():
285
+ def no_middleware ():
247
286
doc = parse ("{ field }" )
248
287
249
288
# noinspection PyMethodMayBeStatic
250
289
class Data :
251
- def test_field (self , _info ):
290
+ def field (self , _info ):
252
291
return "resolved"
253
292
254
293
test_type = GraphQLObjectType (
255
294
"TestType" , {"field" : GraphQLField (GraphQLString )}
256
295
)
257
296
258
- result = execute (_create_schema (test_type , is_subscription ), doc , Data (), middleware = None )
297
+ result = execute (_create_schema (test_type ), doc , Data (), middleware = None )
259
298
260
299
assert result .data ["field" ] == "resolved" # type: ignore
261
300
262
- def test_empty_middleware_list ():
301
+ def empty_middleware_list ():
263
302
doc = parse ("{ field }" )
264
303
265
304
# noinspection PyMethodMayBeStatic
266
305
class Data :
267
- def test_field (self , _info ):
306
+ def field (self , _info ):
268
307
return "resolved"
269
308
270
309
test_type = GraphQLObjectType (
271
310
"TestType" , {"field" : GraphQLField (GraphQLString )}
272
311
)
273
312
274
- result = execute (_create_schema (test_type , is_subscription ), doc , Data (), middleware = [])
313
+ result = execute (_create_schema (test_type ), doc , Data (), middleware = [])
275
314
276
315
assert result .data ["field" ] == "resolved" # type: ignore
277
316
278
- def test_bad_middleware_object ():
317
+ def bad_middleware_object ():
279
318
doc = parse ("{ field }" )
280
319
281
320
test_type = GraphQLObjectType (
@@ -285,7 +324,7 @@ def test_bad_middleware_object():
285
324
with pytest .raises (TypeError ) as exc_info :
286
325
# noinspection PyTypeChecker
287
326
execute (
288
- _create_schema (test_type , is_subscription ),
327
+ _create_schema (test_type ),
289
328
doc ,
290
329
None ,
291
330
middleware = cast (Middleware , {"bad" : "value" }),
@@ -297,12 +336,12 @@ def test_bad_middleware_object():
297
336
" Got {'bad': 'value'} instead."
298
337
)
299
338
300
- def test_list_of_functions ():
339
+ def list_of_functions ():
301
340
doc = parse ("{ field }" )
302
341
303
342
# noinspection PyMethodMayBeStatic
304
343
class Data :
305
- def test_field (self , _info ):
344
+ def field (self , _info ):
306
345
return "resolved"
307
346
308
347
test_type = GraphQLObjectType (
@@ -312,11 +351,11 @@ def test_field(self, _info):
312
351
log = []
313
352
314
353
class LogMiddleware :
315
- def test___init__ (self , name ):
354
+ def __init__ (self , name ):
316
355
self .name = name
317
356
318
357
# noinspection PyMethodMayBeStatic
319
- def test_resolve (self , next_ , * args , ** kwargs ):
358
+ def resolve (self , next_ , * args , ** kwargs ):
320
359
log .append (f"enter { self .name } " )
321
360
value = next_ (* args , ** kwargs )
322
361
log .append (f"exit { self .name } " )
@@ -325,7 +364,7 @@ def test_resolve(self, next_, *args, **kwargs):
325
364
middlewares = [LogMiddleware ("A" ), LogMiddleware ("B" ), LogMiddleware ("C" )]
326
365
327
366
result = execute (
328
- _create_schema (test_type , is_subscription ), doc , Data (), middleware = middlewares
367
+ _create_schema (test_type ), doc , Data (), middleware = middlewares
329
368
)
330
369
assert result .data == {"field" : "resolved" } # type: ignore
331
370
0 commit comments