11import pytest
22import redis
33import graphene
4- from graphql_subscriptions import RedisPubsub , SubscriptionManager
4+ import gevent
5+ import sys
6+ from promise import Promise
7+ from graphql_subscriptions import (
8+ RedisPubsub ,
9+ SubscriptionManager ,
10+ )
511
612
713@pytest .fixture
@@ -22,37 +28,35 @@ def pubsub(mock_redis):
2228])
2329def test_pubsub_subscribe_and_publish (pubsub , test_input , expected ):
2430
25- def message_handler (message ):
26- assert message == expected
31+ def message_callback (message ):
32+ try :
33+ assert message == expected
34+ pubsub .greenlet .kill ()
35+ except AssertionError as e :
36+ sys .exit (e )
2737
2838 def publish_callback (sub_id ):
2939 assert pubsub .publish ('a' , test_input )
40+ pubsub .greenlet .join ()
3041
31- pubsub .subscribe ('a' , message_handler , {}).then (publish_callback )
42+ p1 = pubsub .subscribe ('a' , message_callback , {})
43+ p2 = p1 .then (publish_callback )
44+ p2 .get ()
3245
33- while True :
34- message = pubsub .pubsub .get_message (ignore_subscribe_messages = True )
35- if message :
36- pubsub .handle_message (message )
37- break
3846
47+ def test_pubsub_subscribe_and_unsubscribe (pubsub ):
3948
40- @pytest .mark .parametrize ('test_input, expected' , [
41- ('test' , 'test' ),
42- ({1 : 'test' }, {1 : 'test' }),
43- (None , None )
44- ])
45- def test_pubsub_subscribe_and_unsubscribe (pubsub , test_input , expected ):
46-
47- def message_handler (message ):
48- assert 0
49+ def message_callback (message ):
50+ sys .exit ('Message callback should not have been called' )
4951
5052 def unsubscribe_publish_callback (sub_id ):
5153 pubsub .unsubscribe (sub_id )
52- assert pubsub .publish ('a' , test_input )
54+ assert pubsub .publish ('a' , 'test' )
55+ gevent .sleep (.01 )
5356
54- pubsub .subscribe ('a' , message_handler ,
55- {}).then (unsubscribe_publish_callback )
57+ p1 = pubsub .subscribe ('a' , message_callback , {})
58+ p2 = p1 .then (unsubscribe_publish_callback )
59+ p2 .get ()
5660
5761
5862@pytest .fixture
@@ -66,7 +70,7 @@ def resolve_test_string(self, args, context, info):
6670 class Subscription (graphene .ObjectType ):
6771 test_subscription = graphene .String ()
6872 test_context = graphene .String ()
69- test_filter = graphene .String (filter_boolean = graphene .Boolean ())
73+ test_filter = graphene .String (filterBoolean = graphene .Boolean ())
7074 test_filter_multi = graphene .String (
7175 filter_boolean = graphene .Boolean (),
7276 a = graphene .String (),
@@ -81,10 +85,10 @@ def resolve_test_context(self, args, context, info):
8185 return context
8286
8387 def resolve_test_filter (self , args , context , info ):
84- return 'good_filter' if args .get ('filter_boolean ' ) else 'bad_filter'
88+ return 'good_filter' if args .get ('filterBoolean ' ) else 'bad_filter'
8589
8690 def resolve_test_filter_multi (self , args , context , info ):
87- return 'good_filter' if args .get ('filter_boolean ' ) else 'bad_filter'
91+ return 'good_filter' if args .get ('filterBoolean ' ) else 'bad_filter'
8892
8993 def resolve_test_channel_options (self , args , context , info ):
9094 return self
@@ -99,8 +103,11 @@ def filter_single(**kwargs):
99103 args = kwargs .get ('args' )
100104 return {
101105 'filter_1' : {
102- 'filter' : lambda root , context : root .get ('filter_boolean' ) == args .get ('filter_boolean' )
103- }
106+ 'filter' : lambda root , context : root .get ('filterBoolean' ) == args .get ('filterBoolean' )
107+ },
108+ 'filter_2' : {
109+ 'filter' : lambda root , context : Promise .resolve (root .get ('filterBoolean' ) == args .get ('filterBoolean' ))
110+ },
104111 }
105112
106113 def filter_multi (** kwargs ):
@@ -137,3 +144,135 @@ def filter_context(**kwargs):
137144 'test_context' : filter_context
138145 }
139146 )
147+
148+
149+ def test_query_is_valid_and_throws_error (sub_mgr ):
150+ query = 'query a{ testInt }'
151+
152+ def handler (error ):
153+ assert error .message == 'Subscription query has validation errors'
154+
155+ p1 = sub_mgr .subscribe (query , 'a' , lambda : None , {}, {}, None , None )
156+ p2 = p1 .catch (handler )
157+ p2 .get ()
158+
159+
160+ # TODO: Still need to build this validation and add to library
161+ def test_rejects_subscription_with_multiple_root_fields (sub_mgr ):
162+ pass
163+
164+
165+ def test_subscribe_valid_query_return_sub_id (sub_mgr ):
166+ query = 'subscription X{ testSubscription }'
167+
168+ def handler (sub_id ):
169+ assert isinstance (sub_id , int )
170+ sub_mgr .unsubscribe (sub_id )
171+
172+ p1 = sub_mgr .subscribe (query , 'X' , lambda : None , {}, {}, None , None )
173+ p2 = p1 .then (handler )
174+ p2 .get ()
175+
176+
177+ def test_subscribe_nameless_query_and_return_sub_id (sub_mgr ):
178+ query = 'subscription { testSubscription }'
179+
180+ def handler (sub_id ):
181+ assert isinstance (sub_id , int )
182+ sub_mgr .unsubscribe (sub_id )
183+
184+ p1 = sub_mgr .subscribe (query , None , lambda : None , {}, {}, None , None )
185+ p2 = p1 .then (handler )
186+ p2 .get ()
187+
188+
189+ def test_subscribe_with_valid_query_return_root_value (sub_mgr ):
190+ query = 'subscription X{ testSubscription }'
191+
192+ def callback (e , payload ):
193+ try :
194+ assert payload .data .get ('testSubscription' ) == 'good'
195+ sub_mgr .pubsub .greenlet .kill ()
196+ except AssertionError as e :
197+ sys .exit (e )
198+
199+ def publish_and_unsubscribe_handler (sub_id ):
200+ sub_mgr .publish ('testSubscription' , 'good' )
201+ sub_mgr .pubsub .greenlet .join ()
202+ sub_mgr .unsubscribe (sub_id )
203+
204+ p1 = sub_mgr .subscribe (query , 'X' , callback , {}, {}, None , None )
205+ p2 = p1 .then (publish_and_unsubscribe_handler )
206+ p2 .get ()
207+
208+
209+ def test_use_filter_functions_properly (sub_mgr ):
210+ query = 'subscription Filter1($filterBoolean: Boolean) {\
211+ testFilter(filterBoolean: $filterBoolean)}'
212+
213+ def callback (err , payload ):
214+ if err :
215+ sys .exit (err )
216+ else :
217+ try :
218+ if payload is None :
219+ assert True
220+ else :
221+ assert payload .data .get ('testFilter' ) == 'good_filter'
222+ sub_mgr .pubsub .greenlet .kill ()
223+ except AssertionError as e :
224+ sys .exit (e )
225+
226+ def publish_and_unsubscribe_handler (sub_id ):
227+ sub_mgr .publish ('filter_1' , {'filterBoolean' : False })
228+ sub_mgr .publish ('filter_1' , {'filterBoolean' : True })
229+ sub_mgr .pubsub .greenlet .join ()
230+ sub_mgr .unsubscribe (sub_id )
231+
232+ p1 = sub_mgr .subscribe (
233+ query ,
234+ 'Filter1' ,
235+ callback ,
236+ {'filterBoolean' : True },
237+ {},
238+ None ,
239+ None
240+ )
241+ p2 = p1 .then (publish_and_unsubscribe_handler )
242+ p2 .get ()
243+
244+
245+ def test_use_filter_func_that_returns_promise (sub_mgr ):
246+ query = 'subscription Filter2($filterBoolean: Boolean) {\
247+ testFilter(filterBoolean: $filterBoolean)}'
248+
249+ def callback (err , payload ):
250+ if err :
251+ sys .exit (err )
252+ else :
253+ try :
254+ if payload is None :
255+ assert True
256+ else :
257+ assert payload .data .get ('testFilter' ) == 'good_filter'
258+ sub_mgr .pubsub .greenlet .kill ()
259+ except AssertionError as e :
260+ sys .exit (e )
261+
262+ def publish_and_unsubscribe_handler (sub_id ):
263+ sub_mgr .publish ('filter_2' , {'filterBoolean' : False })
264+ sub_mgr .publish ('filter_2' , {'filterBoolean' : True })
265+ sub_mgr .pubsub .greenlet .join ()
266+ sub_mgr .unsubscribe (sub_id )
267+
268+ p1 = sub_mgr .subscribe (
269+ query ,
270+ 'Filter2' ,
271+ callback ,
272+ {'filterBoolean' : True },
273+ {},
274+ None ,
275+ None
276+ )
277+ p2 = p1 .then (publish_and_unsubscribe_handler )
278+ p2 .get ()
0 commit comments