11use std:: { future:: IntoFuture , time:: Duration } ;
22
33use assert_matches:: assert_matches;
4+ use cynic:: StreamingOperation ;
45use futures_lite:: { StreamExt , future} ;
6+ use graphql_ws_client:: Subscription ;
57use subscription_server:: SubscriptionServer ;
68use tokio:: time:: sleep;
79
@@ -54,29 +56,14 @@ struct BooksChangedSubscription {
5456
5557#[ tokio:: test]
5658async fn main_test ( ) {
57- use async_tungstenite:: tungstenite:: { client:: IntoClientRequest , http:: HeaderValue } ;
58-
5959 let server = SubscriptionServer :: start ( ) . await ;
6060
61- sleep ( Duration :: from_millis ( 20 ) ) . await ;
62-
63- let mut request = server. websocket_url ( ) . into_client_request ( ) . unwrap ( ) ;
64- request. headers_mut ( ) . insert (
65- "Sec-WebSocket-Protocol" ,
66- HeaderValue :: from_str ( "graphql-transport-ws" ) . unwrap ( ) ,
67- ) ;
68-
69- let ( connection, _) = async_tungstenite:: tokio:: connect_async ( request)
70- . await
71- . unwrap ( ) ;
72-
73- println ! ( "Connected" ) ;
74-
75- let ( client, actor) = graphql_ws_client:: Client :: build ( connection) . await . unwrap ( ) ;
61+ let client_builder = server. client_builder ( ) . await ;
62+ let ( client, actor) = client_builder. await . unwrap ( ) ;
7663
7764 tokio:: spawn ( actor. into_future ( ) ) ;
7865
79- let stream = client. subscribe ( build_query ( ) ) . await . unwrap ( ) ;
66+ let mut stream = client. subscribe ( build_query ( ) ) . await . unwrap ( ) ;
8067
8168 sleep ( Duration :: from_millis ( 100 ) ) . await ;
8269
@@ -95,50 +82,16 @@ async fn main_test() {
9582 } ,
9683 ] ;
9784
98- future:: zip (
99- async {
100- for update in & updates {
101- server. send ( update. to_owned ( ) ) . unwrap ( ) ;
102- }
103- } ,
104- async {
105- let received_updates = stream. take ( updates. len ( ) ) . collect :: < Vec < _ > > ( ) . await ;
106-
107- for ( expected, update) in updates. iter ( ) . zip ( received_updates) {
108- let update = update. unwrap ( ) ;
109- assert_matches ! ( update. errors, None ) ;
110- let data = update. data . unwrap ( ) ;
111- assert_eq ! ( data. books. id. inner( ) , expected. id. 0 ) ;
112- }
113- } ,
114- )
115- . await ;
85+ send_and_verify_updates ( & server, & updates, & mut stream) . await ;
11686}
11787
11888#[ tokio:: test]
11989async fn oneshot_operation_test ( ) {
120- use async_tungstenite:: tungstenite:: { client:: IntoClientRequest , http:: HeaderValue } ;
121-
12290 let server = SubscriptionServer :: start ( ) . await ;
12391
124- sleep ( Duration :: from_millis ( 20 ) ) . await ;
125-
126- let mut request = server. websocket_url ( ) . into_client_request ( ) . unwrap ( ) ;
127- request. headers_mut ( ) . insert (
128- "Sec-WebSocket-Protocol" ,
129- HeaderValue :: from_str ( "graphql-transport-ws" ) . unwrap ( ) ,
130- ) ;
131-
132- let ( connection, _) = async_tungstenite:: tokio:: connect_async ( request)
133- . await
134- . unwrap ( ) ;
92+ let client_builder = server. client_builder ( ) . await ;
13593
136- println ! ( "Connected" ) ;
137-
138- let stream = graphql_ws_client:: Client :: build ( connection)
139- . subscribe ( build_query ( ) )
140- . await
141- . unwrap ( ) ;
94+ let mut stream = client_builder. subscribe ( build_query ( ) ) . await . unwrap ( ) ;
14295
14396 let updates = [
14497 subscription_server:: BookChanged {
@@ -155,15 +108,115 @@ async fn oneshot_operation_test() {
155108 } ,
156109 ] ;
157110
111+ send_and_verify_updates ( & server, & updates, & mut stream) . await ;
112+ }
113+
114+ #[ tokio:: test]
115+ async fn test_client_stop ( ) {
116+ let server = SubscriptionServer :: start ( ) . await ;
117+
118+ let client_builder = server. client_builder ( ) . await ;
119+ let ( client, actor) = client_builder. await . unwrap ( ) ;
120+
121+ tokio:: spawn ( actor. into_future ( ) ) ;
122+
123+ let mut stream = client. subscribe ( build_query ( ) ) . await . unwrap ( ) ;
124+
125+ sleep ( Duration :: from_millis ( 10 ) ) . await ;
126+
127+ let updates = [ subscription_server:: BookChanged {
128+ id : "123" . into ( ) ,
129+ book : None ,
130+ } ] ;
131+
132+ send_and_verify_updates ( & server, & updates, & mut stream) . await ;
133+
134+ assert_eq ! ( server. subscriber_count( ) , 1 ) ;
135+
136+ client. stop ( stream. id ( ) ) . await . unwrap ( ) ;
137+
138+ sleep ( Duration :: from_millis ( 10 ) ) . await ;
139+
140+ assert_eq ! ( server. subscriber_count( ) , 0 ) ;
141+
142+ assert ! ( stream. next( ) . await . is_none( ) ) ;
143+ }
144+
145+ #[ tokio:: test]
146+ async fn test_subscription_stop ( ) {
147+ let server = SubscriptionServer :: start ( ) . await ;
148+
149+ let client_builder = server. client_builder ( ) . await ;
150+ let ( client, actor) = client_builder. await . unwrap ( ) ;
151+
152+ tokio:: spawn ( actor. into_future ( ) ) ;
153+
154+ let mut stream = client. subscribe ( build_query ( ) ) . await . unwrap ( ) ;
155+
156+ sleep ( Duration :: from_millis ( 10 ) ) . await ;
157+
158+ let updates = [ subscription_server:: BookChanged {
159+ id : "123" . into ( ) ,
160+ book : None ,
161+ } ] ;
162+
163+ send_and_verify_updates ( & server, & updates, & mut stream) . await ;
164+
165+ assert_eq ! ( server. subscriber_count( ) , 1 ) ;
166+
167+ stream. stop ( ) . await . unwrap ( ) ;
168+
169+ sleep ( Duration :: from_millis ( 10 ) ) . await ;
170+
171+ assert_eq ! ( server. subscriber_count( ) , 0 ) ;
172+ }
173+
174+ #[ tokio:: test]
175+ async fn test_subscription_stops_on_drop ( ) {
176+ let server = SubscriptionServer :: start ( ) . await ;
177+
178+ let client_builder = server. client_builder ( ) . await ;
179+ let ( client, actor) = client_builder. await . unwrap ( ) ;
180+
181+ tokio:: spawn ( actor. into_future ( ) ) ;
182+
183+ let mut stream = client. subscribe ( build_query ( ) ) . await . unwrap ( ) ;
184+
185+ sleep ( Duration :: from_millis ( 10 ) ) . await ;
186+
187+ let updates = [ subscription_server:: BookChanged {
188+ id : "123" . into ( ) ,
189+ book : None ,
190+ } ] ;
191+
192+ send_and_verify_updates ( & server, & updates, & mut stream) . await ;
193+
194+ assert_eq ! ( server. subscriber_count( ) , 1 ) ;
195+
196+ drop ( stream) ;
197+
198+ sleep ( Duration :: from_millis ( 10 ) ) . await ;
199+
200+ assert_eq ! ( server. subscriber_count( ) , 0 ) ;
201+ }
202+
203+ async fn send_and_verify_updates (
204+ server : & SubscriptionServer ,
205+ updates : & [ subscription_server:: BookChanged ] ,
206+ stream : & mut Subscription < StreamingOperation < BooksChangedSubscription , BooksChangedVariables > > ,
207+ ) {
158208 future:: zip (
159209 async {
160210 sleep ( Duration :: from_millis ( 10 ) ) . await ;
161- for update in & updates {
211+ for update in updates {
162212 server. send ( update. to_owned ( ) ) . unwrap ( ) ;
163213 }
164214 } ,
165215 async {
166- let received_updates = stream. take ( updates. len ( ) ) . collect :: < Vec < _ > > ( ) . await ;
216+ let mut received_updates = Vec :: new ( ) ;
217+ for _ in updates {
218+ received_updates. push ( stream. next ( ) . await . unwrap ( ) ) ;
219+ }
167220
168221 for ( expected, update) in updates. iter ( ) . zip ( received_updates) {
169222 let update = update. unwrap ( ) ;
0 commit comments