1#[cfg(test)]
2mod tests {
3 use bolt_proto::{message::*, value::*, version::*, ServerState::*};
4
5 use crate::{client::v1::tests::*, error::CommunicationError, skip_if_handshake_failed};
6
7 #[tokio::test]
8 async fn hello() {
9 let client = new_client(V3_0).await;
10 skip_if_handshake_failed!(client);
11 let mut client = client.unwrap();
12 assert_eq!(client.server_state(), Connected);
13 let response = initialize_client(&mut client, true).await.unwrap();
14 assert!(Success::try_from(response).is_ok());
15 assert_eq!(client.server_state(), Ready);
16 }
17
18 #[tokio::test]
19 async fn hello_fail() {
20 let client = new_client(V3_0).await;
21 skip_if_handshake_failed!(client);
22 let mut client = client.unwrap();
23 assert_eq!(client.server_state(), Connected);
24 let response = initialize_client(&mut client, false).await.unwrap();
25 assert!(Failure::try_from(response).is_ok());
26 assert_eq!(client.server_state(), Defunct);
27 }
28
29 #[tokio::test]
30 async fn goodbye() {
31 let client = get_initialized_client(V3_0).await;
32 skip_if_handshake_failed!(client);
33 let mut client = client.unwrap();
34 assert_eq!(client.server_state(), Ready);
35 assert!(client.goodbye().await.is_ok());
36 assert_eq!(client.server_state(), Defunct);
37 }
38
39 #[tokio::test]
40 async fn run() {
41 let client = get_initialized_client(V3_0).await;
42 skip_if_handshake_failed!(client);
43 let mut client = client.unwrap();
44 assert_eq!(client.server_state(), Ready);
45 let response = run_valid_query(&mut client).await.unwrap();
46 assert!(Success::try_from(response).is_ok());
47 assert_eq!(client.server_state(), Streaming);
48 }
49
50 #[tokio::test]
51 async fn run_pipelined() {
52 let client = get_initialized_client(V3_0).await;
53 skip_if_handshake_failed!(client);
54 let mut client = client.unwrap();
55 let messages = vec![
56 Message::RunWithMetadata(RunWithMetadata::new(
57 "MATCH (n {test: 'v3-pipelined'}) DETACH DELETE n;".to_string(),
58 Default::default(), Default::default())),
59 Message::PullAll,
60 Message::RunWithMetadata(RunWithMetadata::new(
61 "CREATE (:Database {name: 'neo4j', v1_release: date('2010-02-16'), test: 'v3-pipelined'});".to_string(),
62 Default::default(), Default::default())),
63 Message::PullAll,
64 Message::RunWithMetadata(RunWithMetadata::new(
65 "MATCH (neo4j:Database {name: 'neo4j', test: 'v3-pipelined'}) CREATE (:Library {name: 'bolt-client', v1_release: date('2019-12-23'), test: 'v3-pipelined'})-[:CLIENT_FOR]->(neo4j);".to_string(),
66 Default::default(), Default::default())),
67 Message::PullAll,
68 Message::RunWithMetadata(RunWithMetadata::new(
69 "MATCH (neo4j:Database {name: 'neo4j', test: 'v3-pipelined'}), (bolt_client:Library {name: 'bolt-client', test: 'v3-pipelined'}) RETURN duration.between(neo4j.v1_release, bolt_client.v1_release);".to_string(),
70 Default::default(), Default::default())),
71 Message::PullAll,
72 ];
73 for response in client.pipeline(messages).await.unwrap() {
74 assert!(match response {
75 Message::Success(_) => true,
76 Message::Record(record) => {
77 assert_eq!(record.fields()[0], Value::from(Duration::new(118, 7, 0, 0)));
78 true
79 }
80 _ => false,
81 });
82 }
83 }
84
85 #[tokio::test]
86 async fn run_and_pull() {
87 let client = get_initialized_client(V3_0).await;
88 skip_if_handshake_failed!(client);
89 let mut client = client.unwrap();
90 assert_eq!(client.server_state(), Ready);
91 let response = client
92 .run("RETURN 3458376 as n;", None, None)
93 .await
94 .unwrap();
95 assert!(Success::try_from(response).is_ok());
96 assert_eq!(client.server_state(), Streaming);
97
98 let (records, response) = client.pull(None).await.unwrap();
99 assert!(Success::try_from(response).is_ok());
100 assert_eq!(client.server_state(), Ready);
101 assert_eq!(records.len(), 1);
102 assert_eq!(records[0].fields(), &[Value::from(3_458_376)]);
103 }
104
105 #[tokio::test]
106 async fn discard_fail() {
107 let client = get_initialized_client(V3_0).await;
108 skip_if_handshake_failed!(client);
109 let mut client = client.unwrap();
110 assert_eq!(client.server_state(), Ready);
111 assert!(matches!(
112 client.discard(None).await,
113 Err(CommunicationError::InvalidState { state: Ready, .. })
114 ));
115 }
116
117 #[tokio::test]
118 async fn discard() {
119 let client = get_initialized_client(V3_0).await;
120 skip_if_handshake_failed!(client);
121 let mut client = client.unwrap();
122 assert_eq!(client.server_state(), Ready);
123 let response = run_valid_query(&mut client).await.unwrap();
124 assert!(Success::try_from(response).is_ok());
125 assert_eq!(client.server_state(), Streaming);
126 let response = client.discard(None).await.unwrap();
127 assert!(Success::try_from(response).is_ok());
128 assert_eq!(client.server_state(), Ready);
129 }
130
131 #[tokio::test]
132 async fn discard_and_pull() {
133 let client = get_initialized_client(V3_0).await;
134 skip_if_handshake_failed!(client);
135 let mut client = client.unwrap();
136 assert_eq!(client.server_state(), Ready);
137 let response = run_valid_query(&mut client).await.unwrap();
138 assert!(Success::try_from(response).is_ok());
139 assert_eq!(client.server_state(), Streaming);
140 let response = client.discard(None).await.unwrap();
141 assert!(Success::try_from(response).is_ok());
142 assert_eq!(client.server_state(), Ready);
143 assert!(matches!(
144 client.pull(None).await,
145 Err(CommunicationError::InvalidState { state: Ready, .. })
146 ));
147 }
148
149 #[tokio::test]
150 async fn begin() {
151 let client = get_initialized_client(V3_0).await;
152 skip_if_handshake_failed!(client);
153 let mut client = client.unwrap();
154 assert_eq!(client.server_state(), Ready);
155 let response = client.begin(None).await.unwrap();
156 assert!(Success::try_from(response).is_ok());
157 assert_eq!(client.server_state(), TxReady);
158 }
159
160 #[tokio::test]
161 async fn commit_empty_transaction() {
162 let client = get_initialized_client(V3_0).await;
163 skip_if_handshake_failed!(client);
164 let mut client = client.unwrap();
165 assert_eq!(client.server_state(), Ready);
166 client.begin(None).await.unwrap();
167 assert_eq!(client.server_state(), TxReady);
168 let response = client.commit().await.unwrap();
169 assert!(Success::try_from(response).is_ok());
170 assert_eq!(client.server_state(), Ready);
171 }
172
173 #[tokio::test]
174 async fn commit() {
175 let client = get_initialized_client(V3_0).await;
176 skip_if_handshake_failed!(client);
177 let mut client = client.unwrap();
178 assert_eq!(client.server_state(), Ready);
179 client.begin(None).await.unwrap();
180 assert_eq!(client.server_state(), TxReady);
181
182 let messages = vec![
183 Message::RunWithMetadata(RunWithMetadata::new(
184 "MATCH (n {test: 'v3-commit'}) DETACH DELETE n;".to_string(),
185 Default::default(), Default::default())),
186 Message::PullAll,
187 Message::RunWithMetadata(RunWithMetadata::new(
188 "CREATE (:Database {name: 'neo4j', v1_release: date('2010-02-16'), test: 'v3-commit'});".to_string(),
189 Default::default(), Default::default())),
190 Message::PullAll,
191 ];
192 client.pipeline(messages).await.unwrap();
193 assert_eq!(client.server_state(), TxReady);
194 let response = client.commit().await.unwrap();
195 assert!(Success::try_from(response).is_ok());
196 assert_eq!(client.server_state(), Ready);
197
198 let messages = vec![
199 Message::RunWithMetadata(RunWithMetadata::new(
200 "MATCH (n {test: 'v3-commit'}) RETURN n;".to_string(),
201 Default::default(),
202 Default::default(),
203 )),
204 Message::PullAll,
205 ];
206 let mut node_exists = false;
207 for response in client.pipeline(messages).await.unwrap() {
208 if let Message::Record(record) = response {
209 let node = Node::try_from(record.fields()[0].clone()).unwrap();
210 assert_eq!(node.labels(), &["Database"]);
211 node_exists = true;
212 break;
213 }
214 }
215 assert!(node_exists);
216 }
217
218 #[tokio::test]
219 async fn commit_with_no_begin_fails() {
220 let client = get_initialized_client(V3_0).await;
221 skip_if_handshake_failed!(client);
222 let mut client = client.unwrap();
223 assert!(matches!(
224 client.commit().await,
225 Err(CommunicationError::InvalidState { state: Ready, .. })
226 ));
227 }
228
229 #[tokio::test]
230 async fn rollback_empty_transaction() {
231 let client = get_initialized_client(V3_0).await;
232 skip_if_handshake_failed!(client);
233 let mut client = client.unwrap();
234 assert_eq!(client.server_state(), Ready);
235 client.begin(None).await.unwrap();
236 assert_eq!(client.server_state(), TxReady);
237 let response = client.rollback().await.unwrap();
238 assert!(Success::try_from(response).is_ok());
239 assert_eq!(client.server_state(), Ready);
240 }
241
242 #[tokio::test]
243 async fn rollback() {
244 let client = get_initialized_client(V3_0).await;
245 skip_if_handshake_failed!(client);
246 let mut client = client.unwrap();
247 assert_eq!(client.server_state(), Ready);
248 client.begin(None).await.unwrap();
249 assert_eq!(client.server_state(), TxReady);
250 let messages = vec![
251 Message::RunWithMetadata(RunWithMetadata::new(
252 "MATCH (n {test: 'v3-rollback'}) DETACH DELETE n;".to_string(),
253 Default::default(), Default::default())),
254 Message::PullAll,
255 Message::RunWithMetadata(RunWithMetadata::new(
256 "CREATE (:Database {name: 'neo4j', v1_release: date('2010-02-16'), test: 'v3-rollback'});".to_string(),
257 Default::default(), Default::default())),
258 Message::PullAll,
259 ];
260 client.pipeline(messages).await.unwrap();
261 assert_eq!(client.server_state(), TxReady);
262 let response = client.rollback().await.unwrap();
263 assert!(Success::try_from(response).is_ok());
264 assert_eq!(client.server_state(), Ready);
265
266 let messages = vec![
267 Message::RunWithMetadata(RunWithMetadata::new(
268 "MATCH (n {test: 'v3-rollback'}) RETURN n;".to_string(),
269 Default::default(),
270 Default::default(),
271 )),
272 Message::PullAll,
273 ];
274 for response in client.pipeline(messages).await.unwrap() {
275 assert!(matches!(response, Message::Success(_)));
277 }
278 }
279
280 #[tokio::test]
281 async fn rollback_with_no_begin_fails() {
282 let client = get_initialized_client(V3_0).await;
283 skip_if_handshake_failed!(client);
284 let mut client = client.unwrap();
285 assert!(matches!(
286 client.rollback().await,
287 Err(CommunicationError::InvalidState { state: Ready, .. })
288 ));
289 }
290
291 #[tokio::test]
292 async fn reset_internals_pipelined() {
293 let client = get_initialized_client(V3_0).await;
294 skip_if_handshake_failed!(client);
295 let mut client = client.unwrap();
296
297 let mut messages = client
298 .pipeline(vec![
299 Message::RunWithMetadata(RunWithMetadata::new(
300 String::from("RETURN 1;"),
301 Default::default(),
302 Default::default(),
303 )),
304 Message::PullAll,
305 Message::RunWithMetadata(RunWithMetadata::new(
306 String::from("RETURN 1;"),
307 Default::default(),
308 Default::default(),
309 )),
310 Message::PullAll,
311 Message::Reset,
312 ])
313 .await
314 .unwrap();
315
316 assert_eq!(
318 messages.pop(),
319 Some(Message::Success(Success::new(Default::default())))
320 );
321
322 assert!(messages.len() >= 4);
324 for message in messages {
325 assert_eq!(message, Message::Ignored);
326 }
327 }
328
329 #[tokio::test]
330 async fn reset_internals() {
331 let client = get_initialized_client(V3_0).await;
332 skip_if_handshake_failed!(client);
333 let mut client = client.unwrap();
334
335 client.run("RETURN 1;", None, None).await.unwrap();
336 client.send_message(Message::PullAll).await.unwrap();
337 client.send_message(Message::Reset).await.unwrap();
338 assert_eq!(client.server_state(), Interrupted);
339
340 assert_eq!(client.read_message().await.unwrap(), Message::Ignored);
346
347 match client.read_message().await.unwrap() {
348 Message::Ignored => {
350 Success::try_from(client.read_message().await.unwrap()).unwrap();
352 }
353 Message::Success(_) => {}
355 other => panic!("unexpected response {:?}", other),
356 }
357 }
358}