Skip to content

Commit debd053

Browse files
author
Daniel Gallagher
committed
Create dedicated test file for middleware (test_middleware.py) and add test that pins down the order that middleware is executed in
1 parent 2692232 commit debd053

File tree

4 files changed

+159
-106
lines changed

4 files changed

+159
-106
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ htmlcov/
4646
nosetests.xml
4747
coverage.xml
4848
*,cover
49+
.pytest_cache/
4950

5051
# Translations
5152
*.mo

graphql/execution/middleware.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def get_middleware_resolvers(middlewares):
3939
yield getattr(middleware, MIDDLEWARE_RESOLVER_FUNCTION)
4040

4141

42-
def middleware_chain(func, middlewares, wrap_in_promise):
42+
def middleware_chain(func, middlewares, wrap_in_promise=True):
4343
if not middlewares:
4444
return func
4545
if wrap_in_promise:

graphql/execution/tests/test_executor.py

Lines changed: 0 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -565,111 +565,6 @@ def resolver(*_):
565565
"An error occurred while resolving field Query.foo")
566566

567567

568-
def test_middleware():
569-
doc = '''{
570-
ok
571-
not_ok
572-
}'''
573-
574-
class Data(object):
575-
576-
def ok(self):
577-
return 'ok'
578-
579-
def not_ok(self):
580-
return 'not_ok'
581-
582-
doc_ast = parse(doc)
583-
584-
Type = GraphQLObjectType('Type', {
585-
'ok': GraphQLField(GraphQLString),
586-
'not_ok': GraphQLField(GraphQLString),
587-
})
588-
589-
def reversed_middleware(next, *args, **kwargs):
590-
p = next(*args, **kwargs)
591-
return p.then(lambda x: x[::-1])
592-
593-
middlewares = MiddlewareManager(reversed_middleware)
594-
result = execute(GraphQLSchema(Type), doc_ast,
595-
Data(), middleware=middlewares)
596-
assert result.data == {'ok': 'ko', 'not_ok': 'ko_ton'}
597-
598-
599-
def test_middleware_class():
600-
doc = '''{
601-
ok
602-
not_ok
603-
}'''
604-
605-
class Data(object):
606-
607-
def ok(self):
608-
return 'ok'
609-
610-
def not_ok(self):
611-
return 'not_ok'
612-
613-
doc_ast = parse(doc)
614-
615-
Type = GraphQLObjectType('Type', {
616-
'ok': GraphQLField(GraphQLString),
617-
'not_ok': GraphQLField(GraphQLString),
618-
})
619-
620-
class MyMiddleware(object):
621-
def resolve(self, next, *args, **kwargs):
622-
p = next(*args, **kwargs)
623-
return p.then(lambda x: x[::-1])
624-
625-
middlewares = MiddlewareManager(MyMiddleware())
626-
result = execute(GraphQLSchema(Type), doc_ast,
627-
Data(), middleware=middlewares)
628-
assert result.data == {'ok': 'ko', 'not_ok': 'ko_ton'}
629-
630-
631-
def test_middleware_skip_promise_wrap():
632-
doc = '''{
633-
ok
634-
not_ok
635-
}'''
636-
637-
class Data(object):
638-
639-
def ok(self):
640-
return 'ok'
641-
642-
def not_ok(self):
643-
return 'not_ok'
644-
645-
doc_ast = parse(doc)
646-
647-
Type = GraphQLObjectType('Type', {
648-
'ok': GraphQLField(GraphQLString),
649-
'not_ok': GraphQLField(GraphQLString),
650-
})
651-
652-
class MyPromiseMiddleware(object):
653-
def resolve(self, next, *args, **kwargs):
654-
return Promise.resolve(next(*args, **kwargs))
655-
656-
class MyEmptyMiddleware(object):
657-
def resolve(self, next, *args, **kwargs):
658-
return next(*args, **kwargs)
659-
660-
middlewares_with_promise = MiddlewareManager(
661-
MyPromiseMiddleware(), wrap_in_promise=False)
662-
middlewares_without_promise = MiddlewareManager(
663-
MyEmptyMiddleware(), wrap_in_promise=False)
664-
665-
result1 = execute(GraphQLSchema(Type), doc_ast, Data(),
666-
middleware=middlewares_with_promise)
667-
result2 = execute(GraphQLSchema(Type), doc_ast, Data(),
668-
middleware=middlewares_without_promise)
669-
assert result1.data == result2.data and result1.data == {
670-
'ok': 'ok', 'not_ok': 'not_ok'}
671-
672-
673568
def test_executor_properly_propogates_path_data(mocker):
674569
time_mock = mocker.patch('time.time')
675570
time_mock.side_effect = range(0, 10000)
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
from graphql.execution.middleware import middleware_chain
2+
from graphql.execution.middleware import get_middleware_resolvers
3+
from graphql.language.parser import parse
4+
from graphql.execution import MiddlewareManager, execute
5+
from graphql.type import (GraphQLArgument, GraphQLBoolean, GraphQLField,
6+
GraphQLInt, GraphQLList, GraphQLObjectType,
7+
GraphQLSchema, GraphQLString, GraphQLNonNull, GraphQLID)
8+
from promise import Promise
9+
10+
11+
def test_middleware():
12+
doc = '''{
13+
ok
14+
not_ok
15+
}'''
16+
17+
class Data(object):
18+
19+
def ok(self):
20+
return 'ok'
21+
22+
def not_ok(self):
23+
return 'not_ok'
24+
25+
doc_ast = parse(doc)
26+
27+
Type = GraphQLObjectType('Type', {
28+
'ok': GraphQLField(GraphQLString),
29+
'not_ok': GraphQLField(GraphQLString),
30+
})
31+
32+
def reversed_middleware(next, *args, **kwargs):
33+
p = next(*args, **kwargs)
34+
return p.then(lambda x: x[::-1])
35+
36+
middlewares = MiddlewareManager(reversed_middleware)
37+
result = execute(GraphQLSchema(Type), doc_ast,
38+
Data(), middleware=middlewares)
39+
assert result.data == {'ok': 'ko', 'not_ok': 'ko_ton'}
40+
41+
42+
def test_middleware_class():
43+
doc = '''{
44+
ok
45+
not_ok
46+
}'''
47+
48+
class Data(object):
49+
50+
def ok(self):
51+
return 'ok'
52+
53+
def not_ok(self):
54+
return 'not_ok'
55+
56+
doc_ast = parse(doc)
57+
58+
Type = GraphQLObjectType('Type', {
59+
'ok': GraphQLField(GraphQLString),
60+
'not_ok': GraphQLField(GraphQLString),
61+
})
62+
63+
class MyMiddleware(object):
64+
def resolve(self, next, *args, **kwargs):
65+
p = next(*args, **kwargs)
66+
return p.then(lambda x: x[::-1])
67+
68+
middlewares = MiddlewareManager(MyMiddleware())
69+
result = execute(GraphQLSchema(Type), doc_ast,
70+
Data(), middleware=middlewares)
71+
assert result.data == {'ok': 'ko', 'not_ok': 'ko_ton'}
72+
73+
74+
def test_middleware_skip_promise_wrap():
75+
doc = '''{
76+
ok
77+
not_ok
78+
}'''
79+
80+
class Data(object):
81+
82+
def ok(self):
83+
return 'ok'
84+
85+
def not_ok(self):
86+
return 'not_ok'
87+
88+
doc_ast = parse(doc)
89+
90+
Type = GraphQLObjectType('Type', {
91+
'ok': GraphQLField(GraphQLString),
92+
'not_ok': GraphQLField(GraphQLString),
93+
})
94+
95+
class MyPromiseMiddleware(object):
96+
def resolve(self, next, *args, **kwargs):
97+
return Promise.resolve(next(*args, **kwargs))
98+
99+
class MyEmptyMiddleware(object):
100+
def resolve(self, next, *args, **kwargs):
101+
return next(*args, **kwargs)
102+
103+
middlewares_with_promise = MiddlewareManager(
104+
MyPromiseMiddleware(), wrap_in_promise=False)
105+
middlewares_without_promise = MiddlewareManager(
106+
MyEmptyMiddleware(), wrap_in_promise=False)
107+
108+
result1 = execute(GraphQLSchema(Type), doc_ast, Data(),
109+
middleware=middlewares_with_promise)
110+
result2 = execute(GraphQLSchema(Type), doc_ast, Data(),
111+
middleware=middlewares_without_promise)
112+
assert result1.data == result2.data and result1.data == {
113+
'ok': 'ok', 'not_ok': 'not_ok'}
114+
115+
116+
def test_middleware_chain(capsys):
117+
118+
class CharPrintingMiddleware(object):
119+
def __init__(self, char):
120+
self.char = char
121+
122+
def resolve(self, next, *args, **kwargs):
123+
print(f'resolve() called for middleware {self.char}')
124+
return next(*args, **kwargs).then(
125+
lambda x: print(f'then() for {self.char}')
126+
)
127+
128+
middlewares = [
129+
CharPrintingMiddleware('a'),
130+
CharPrintingMiddleware('b'),
131+
CharPrintingMiddleware('c'),
132+
]
133+
134+
middlewares_resolvers = get_middleware_resolvers(middlewares)
135+
136+
def func(): return
137+
138+
chain_iter = middleware_chain(func, middlewares_resolvers)
139+
140+
assert_stdout(capsys, "")
141+
142+
chain_iter()
143+
144+
expected_stdout = (
145+
'resolve() called for middleware c\n'
146+
'resolve() called for middleware b\n'
147+
'resolve() called for middleware a\n'
148+
'then() for a\n'
149+
'then() for b\n'
150+
'then() for c\n'
151+
)
152+
assert_stdout(capsys, expected_stdout)
153+
154+
155+
def assert_stdout(capsys, expected_stdout):
156+
captured = capsys.readouterr()
157+
assert captured.out == expected_stdout

0 commit comments

Comments
 (0)