Skip to content

Commit 36b6684

Browse files
committed
add filter tests for discussion
1 parent 57cd786 commit 36b6684

File tree

1 file changed

+317
-0
lines changed

1 file changed

+317
-0
lines changed
Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,317 @@
1+
import graphene
2+
3+
from ..fields import SQLAlchemyConnectionField
4+
from ..filters import FloatFilter
5+
from ..types import SQLAlchemyObjectType
6+
from .models import Article, Editor, HairKind, Image, Pet, Reporter, Tag
7+
from .utils import to_std_dicts
8+
9+
10+
def add_test_data(session):
11+
reporter = Reporter(
12+
first_name='John', last_name='Doe', favorite_pet_kind='cat')
13+
session.add(reporter)
14+
pet = Pet(name='Garfield', pet_kind='cat', hair_kind=HairKind.SHORT)
15+
pet.reporters = reporter
16+
session.add(pet)
17+
pet = Pet(name='Snoopy', pet_kind='dog', hair_kind=HairKind.SHORT)
18+
pet.reporters = reporter
19+
session.add(pet)
20+
reporter = Reporter(
21+
first_name='John', last_name='Woe', favorite_pet_kind='cat')
22+
session.add(reporter)
23+
article = Article(headline='Hi!')
24+
article.reporter = reporter
25+
session.add(article)
26+
reporter = Reporter(
27+
first_name='Jane', last_name='Roe', favorite_pet_kind='dog')
28+
session.add(reporter)
29+
pet = Pet(name='Lassie', pet_kind='dog', hair_kind=HairKind.LONG)
30+
pet.reporters.append(reporter)
31+
session.add(pet)
32+
editor = Editor(name="Jack")
33+
session.add(editor)
34+
session.commit()
35+
36+
37+
def create_schema(session):
38+
class ArticleType(SQLAlchemyObjectType):
39+
class Meta:
40+
model = Article
41+
42+
class ImageType(SQLAlchemyObjectType):
43+
class Meta:
44+
model = Image
45+
46+
class ReporterType(SQLAlchemyObjectType):
47+
class Meta:
48+
model = Reporter
49+
50+
class Query(graphene.ObjectType):
51+
article = graphene.Field(ArticleType)
52+
articles = graphene.List(ArticleType)
53+
image = graphene.Field(ImageType)
54+
images = graphene.List(ImageType)
55+
reporter = graphene.Field(ReporterType)
56+
reporters = graphene.List(ReporterType)
57+
58+
def resolve_article(self, _info):
59+
return session.query(Article).first()
60+
61+
def resolve_articles(self, _info):
62+
return session.query(Article)
63+
64+
def resolve_image(self, _info):
65+
return session.query(Image).first()
66+
67+
def resolve_images(self, _info):
68+
return session.query(Image)
69+
70+
def resolve_reporter(self, _info):
71+
return session.query(Reporter).first()
72+
73+
def resolve_reporters(self, _info):
74+
return session.query(Reporter)
75+
76+
return Query
77+
78+
79+
# Test a simple example of filtering
80+
def test_filter_simple(session):
81+
add_test_data(session)
82+
Query = create_schema(session)
83+
84+
query = """
85+
query {
86+
reporters(filters: {firstName: "John"}) {
87+
firstName
88+
}
89+
}
90+
"""
91+
expected = {
92+
"reporters": [{"firstName": "John"}],
93+
}
94+
schema = graphene.Schema(query=Query)
95+
result = schema.execute(query)
96+
assert not result.errors
97+
result = to_std_dicts(result.data)
98+
assert result == expected
99+
100+
101+
# Test a custom filter type
102+
def test_filter_custom_type(session):
103+
add_test_data(session)
104+
Query = create_schema(session)
105+
106+
class MathFilter(FloatFilter):
107+
def divisibleBy(dividend, divisor):
108+
return dividend % divisor == 0
109+
110+
class ExtraQuery:
111+
pets = SQLAlchemyConnectionField(Pet, filters=MathFilter())
112+
113+
class CustomQuery(Query, ExtraQuery):
114+
pass
115+
116+
query = """
117+
query {
118+
pets (filters: {
119+
legs: {divisibleBy: 2}
120+
}) {
121+
name
122+
}
123+
}
124+
"""
125+
expected = {
126+
"pets": [{"name": "Garfield"}, {"name": "Lassie"}],
127+
}
128+
schema = graphene.Schema(query=CustomQuery)
129+
result = schema.execute(query)
130+
assert not result.errors
131+
result = to_std_dicts(result.data)
132+
assert result == expected
133+
134+
# Test a 1:1 relationship
135+
def test_filter_relationship_one_to_one(session):
136+
article = Article(headline='Hi!')
137+
image = Image(external_id=1, description="A beautiful image.")
138+
article.image = image
139+
session.add(article)
140+
session.add(image)
141+
session.commit()
142+
143+
Query = create_schema(session)
144+
145+
query = """
146+
query {
147+
article (filters: {
148+
image: {description: "A beautiful image."}
149+
}) {
150+
firstName
151+
}
152+
}
153+
"""
154+
expected = {
155+
"article": [{"headline": "Hi!"}],
156+
}
157+
schema = graphene.Schema(query=Query)
158+
result = schema.execute(query)
159+
assert not result.errors
160+
result = to_std_dicts(result.data)
161+
assert result == expected
162+
163+
164+
# Test a 1:n relationship
165+
def test_filter_relationship_one_to_many(session):
166+
add_test_data(session)
167+
Query = create_schema(session)
168+
169+
query = """
170+
query {
171+
reporter (filters: {
172+
pets: {
173+
name: {in: ["Garfield", "Snoopy"]}
174+
}
175+
}) {
176+
firstName
177+
lastName
178+
}
179+
}
180+
"""
181+
expected = {
182+
"reporter": [{"firstName": "John"}, {"lastName": "Doe"}],
183+
}
184+
schema = graphene.Schema(query=Query)
185+
result = schema.execute(query)
186+
assert not result.errors
187+
result = to_std_dicts(result.data)
188+
assert result == expected
189+
190+
191+
# Test a n:m relationship
192+
def test_filter_relationship_many_to_many(session):
193+
article1 = Article(headline='Article! Look!')
194+
article2 = Article(headline='Woah! Another!')
195+
tag1 = Tag(name="sensational")
196+
tag2 = Tag(name="eye-grabbing")
197+
article1.tags.append(tag1)
198+
article2.tags.append([tag1, tag2])
199+
session.add(article1)
200+
session.add(article2)
201+
session.add(tag1)
202+
session.add(tag2)
203+
session.commit()
204+
205+
Query = create_schema(session)
206+
207+
query = """
208+
query {
209+
articles (filters: {
210+
tags: { name: { in: ["sensational", "eye-grabbing"] } }
211+
}) {
212+
headline
213+
}
214+
}
215+
"""
216+
expected = {
217+
"articles": [{"headline": "Woah! Another!"}],
218+
}
219+
schema = graphene.Schema(query=Query)
220+
result = schema.execute(query)
221+
assert not result.errors
222+
result = to_std_dicts(result.data)
223+
assert result == expected
224+
225+
226+
# Test connecting filters with "and"
227+
def test_filter_logic_and(session):
228+
add_test_data(session)
229+
230+
Query = create_schema(session)
231+
232+
query = """
233+
query {
234+
reporters (filters: {
235+
and: [
236+
{firstName: "John"},
237+
{favoritePetKind: "cat"},
238+
]
239+
}) {
240+
lastName
241+
}
242+
}
243+
"""
244+
expected = {
245+
"reporters": [{"lastName": "Doe"}, {"lastName": "Woe"}],
246+
}
247+
schema = graphene.Schema(query=Query)
248+
result = schema.execute(query)
249+
assert not result.errors
250+
result = to_std_dicts(result.data)
251+
assert result == expected
252+
253+
254+
# Test connecting filters with "or"
255+
def test_filter_logic_or(session):
256+
add_test_data(session)
257+
Query = create_schema(session)
258+
259+
query = """
260+
query {
261+
reporters (filters: {
262+
or: [
263+
{lastName: "Woe"},
264+
{favoritePetKind: "dog"},
265+
]
266+
}) {
267+
firstName
268+
lastName
269+
}
270+
}
271+
"""
272+
expected = {
273+
"reporters": [
274+
{"firstName": "John", "lastName": "Woe"},
275+
{"firstName": "Jane", "lastName": "Roe"},
276+
],
277+
}
278+
schema = graphene.Schema(query=Query)
279+
result = schema.execute(query)
280+
assert not result.errors
281+
result = to_std_dicts(result.data)
282+
assert result == expected
283+
284+
285+
# Test connecting filters with "and" and "or" together
286+
def test_filter_logic_and_or(session):
287+
add_test_data(session)
288+
Query = create_schema(session)
289+
290+
query = """
291+
query {
292+
reporters (filters: {
293+
and: [
294+
{firstName: "John"},
295+
or : [
296+
{lastName: "Doe"},
297+
{favoritePetKind: "cat"},
298+
]
299+
]
300+
}) {
301+
firstName
302+
}
303+
}
304+
"""
305+
expected = {
306+
"reporters": [{"firstName": "John"}, {"firstName": "Jane"}],
307+
}
308+
schema = graphene.Schema(query=Query)
309+
result = schema.execute(query)
310+
assert not result.errors
311+
result = to_std_dicts(result.data)
312+
assert result == expected
313+
314+
315+
# TODO hybrid property
316+
def test_filter_hybrid_property(session):
317+
raise NotImplementedError

0 commit comments

Comments
 (0)