1use crate::errors::*;
8use crate::prelude::*;
9
10pub const TRAFFIC_PATTERN: TrafficPattern = TrafficPattern {
12 avg_traffic: 500,
13 peak_sustainable_traffic: 5_000,
14 broke_my_site_traffic: Some(10_000),
15};
16
17pub const LEVELS: [Level; 3] = [
19 Level {
20 difficulty_factor: 1,
21 visitor_threshold: 1,
22 },
23 Level {
24 difficulty_factor: 2,
25 visitor_threshold: 2,
26 },
27 Level {
28 difficulty_factor: 3,
29 visitor_threshold: 3,
30 },
31];
32
33pub async fn database_works<'a, T: MCDatabase>(
35 db: &T,
36 p: &Register<'a>,
37 c: &CreateCaptcha<'a>,
38 l: &[Level],
39 tp: &TrafficPattern,
40 an: &AddNotification<'a>,
41) {
42 assert!(db.ping().await, "ping test");
43
44 if db.username_exists(p.username).await.unwrap() {
45 db.delete_user(p.username).await.unwrap();
46 assert!(
47 !db.username_exists(p.username).await.unwrap(),
48 "user is deleted so username shouldn't exist"
49 );
50 }
51
52 assert!(matches!(
53 db.get_secret(&p.username).await,
54 Err(DBError::AccountNotFound)
55 ));
56
57 db.register(p).await.unwrap();
58
59 assert!(matches!(db.register(&p).await, Err(DBError::UsernameTaken)));
60
61 let secret = db.get_secret(p.username).await.unwrap();
63 assert_eq!(secret.secret, p.secret, "user secret matches");
64
65 db.update_secret(p.username, p.username).await.unwrap();
67
68 let secret = db.get_secret(p.username).await.unwrap();
69 assert_eq!(
70 secret.secret, p.username,
71 "user secret matches username; as set by previous step"
72 );
73
74 let name_hash = db.get_password(&Login::Username(p.username)).await.unwrap();
78 assert_eq!(name_hash.hash, p.hash, "user password matches");
79
80 assert_eq!(name_hash.username, p.username, "username matches");
81
82 let mut name_hash = db
84 .get_password(&Login::Email(p.email.as_ref().unwrap()))
85 .await
86 .unwrap();
87 assert_eq!(name_hash.hash, p.hash, "user password matches");
88 assert_eq!(name_hash.username, p.username, "username matches");
89
90 assert_eq!(
92 db.get_email(p.username)
93 .await
94 .unwrap()
95 .as_ref()
96 .unwrap()
97 .as_str(),
98 p.email.unwrap()
99 );
100
101 assert!(
103 db.email_exists(p.email.as_ref().unwrap()).await.unwrap(),
104 "user is registered so email should exist"
105 );
106 assert!(
107 db.username_exists(p.username).await.unwrap(),
108 "user is registered so username should exist"
109 );
110
111 name_hash.hash = name_hash.username.clone();
113 db.update_password(&name_hash).await.unwrap();
114
115 let name_hash = db.get_password(&Login::Username(p.username)).await.unwrap();
116 assert_eq!(
117 name_hash.hash, p.username,
118 "user password matches with changed value"
119 );
120 assert_eq!(name_hash.username, p.username, "username matches");
121
122 assert!(
124 !db.username_exists(p.email.as_ref().unwrap()).await.unwrap(),
125 "user with p.email doesn't exist. pre-check to update username to p.email"
126 );
127 db.update_username(p.username, p.email.as_ref().unwrap())
128 .await
129 .unwrap();
130 assert!(
131 db.username_exists(p.email.as_ref().unwrap()).await.unwrap(),
132 "user with p.email exist post-update"
133 );
134
135 db.delete_user(p.email.as_ref().unwrap()).await.unwrap();
137 assert!(
138 !db.username_exists(p.email.as_ref().unwrap()).await.unwrap(),
139 "user is deleted so username shouldn't exist"
140 );
141
142 let mut p2 = p.clone();
144 p2.email = None;
145 db.register(&p2).await.unwrap();
146 assert!(
147 db.username_exists(p2.username).await.unwrap(),
148 "user is registered so username should exist"
149 );
150 assert!(
151 !db.email_exists(p.email.as_ref().unwrap()).await.unwrap(),
152 "user registration with email is deleted; so email shouldn't exist"
153 );
154
155 assert_eq!(db.get_email(p.username).await.unwrap(), None);
157
158 let update_email = UpdateEmail {
160 username: p.username,
161 new_email: p.email.as_ref().unwrap(),
162 };
163 db.update_email(&update_email).await.unwrap();
164 println!(
165 "null user email: {}",
166 db.email_exists(p.email.as_ref().unwrap()).await.unwrap()
167 );
168 assert!(
169 db.email_exists(p.email.as_ref().unwrap()).await.unwrap(),
170 "user was with empty email but email is set; so email should exist"
171 );
172
173 db.create_notification(an).await.unwrap();
182 db.create_notification(an).await.unwrap();
183
184 let notifications = db.get_all_unread_notifications(an.to).await.unwrap();
186 assert_eq!(notifications.len(), 2);
187 assert_eq!(notifications[0].heading.as_ref().unwrap(), an.heading);
188
189 db.mark_notification_read(an.to, notifications[0].id.unwrap())
191 .await
192 .unwrap();
193 let new_notifications = db.get_all_unread_notifications(an.to).await.unwrap();
194 assert_eq!(new_notifications.len(), 1);
195
196 db.create_captcha(p.username, c).await.unwrap();
198 assert!(db.captcha_exists(None, c.key).await.unwrap());
199 assert!(db.captcha_exists(Some(p.username), c.key).await.unwrap());
200
201 let secret_from_captcha = db.get_secret_from_captcha(&c.key).await.unwrap();
203 assert_eq!(secret_from_captcha.secret, p.secret, "user secret matches");
204
205 let captcha = db.get_captcha_config(p.username, c.key).await.unwrap();
207 assert_eq!(captcha.key, c.key);
208 assert_eq!(captcha.duration, c.duration);
209 assert_eq!(captcha.description, c.description);
210
211 let all_user_captchas = db.get_all_user_captchas(p.username).await.unwrap();
213 assert_eq!(all_user_captchas.len(), 1);
214 assert_eq!(all_user_captchas[0], captcha);
215
216 assert_eq!(db.get_captcha_cooldown(c.key).await.unwrap(), c.duration);
218
219 db.add_traffic_pattern(p.username, c.key, tp).await.unwrap();
221 assert_eq!(
222 &db.get_traffic_pattern(p.username, c.key).await.unwrap(),
223 tp
224 );
225
226 let patterns = db.get_all_easy_captchas(10, 0).await.unwrap();
228 assert_eq!(patterns.get(0).as_ref().unwrap().key, c.key);
229 assert_eq!(&patterns.get(0).unwrap().traffic_pattern, tp);
230
231 db.delete_traffic_pattern(p.username, c.key).await.unwrap();
233 assert!(
234 matches!(
235 db.get_traffic_pattern(p.username, c.key).await,
236 Err(DBError::TrafficPatternNotFound)
237 ),
238 "deletion successful; traffic pattern no longer exists"
239 );
240
241 db.add_captcha_levels(p.username, c.key, l).await.unwrap();
243
244 let levels = db
246 .get_captcha_levels(Some(p.username), c.key)
247 .await
248 .unwrap();
249 assert_eq!(levels, l);
250 let levels = db.get_captcha_levels(None, c.key).await.unwrap();
252 assert_eq!(levels, l);
253
254 assert!(db
265 .fetch_config_fetched(p.username, c.key)
266 .await
267 .unwrap()
268 .is_empty());
269 assert!(db.fetch_solve(p.username, c.key).await.unwrap().is_empty());
270 assert!(db
271 .fetch_confirm(p.username, c.key)
272 .await
273 .unwrap()
274 .is_empty());
275
276 db.record_fetch(c.key).await.unwrap();
277 db.record_solve(c.key).await.unwrap();
278 db.record_confirm(c.key).await.unwrap();
279
280 db.analytics_create_psuedo_id_if_not_exists(c.key)
282 .await
283 .unwrap();
284 let psuedo_id = db
285 .analytics_get_psuedo_id_from_capmaign_id(c.key)
286 .await
287 .unwrap();
288 assert_eq!(
289 vec![psuedo_id.clone()],
290 db.analytics_get_all_psuedo_ids(0).await.unwrap()
291 );
292 assert!(db.analytics_get_all_psuedo_ids(1).await.unwrap().is_empty());
293
294 db.analytics_create_psuedo_id_if_not_exists(c.key)
295 .await
296 .unwrap();
297 assert_eq!(
298 psuedo_id,
299 db.analytics_get_psuedo_id_from_capmaign_id(c.key)
300 .await
301 .unwrap()
302 );
303
304 assert_eq!(
305 c.key,
306 db.analytics_get_capmaign_id_from_psuedo_id(&psuedo_id)
307 .await
308 .unwrap()
309 );
310
311 let analytics = CreatePerformanceAnalytics {
312 time: 1,
313 difficulty_factor: 1,
314 worker_type: "wasm".into(),
315 };
316
317 assert_eq!(
318 db.stats_get_num_logs_under_time(analytics.time)
319 .await
320 .unwrap(),
321 0
322 );
323
324 db.analysis_save(c.key, &analytics).await.unwrap();
325 assert_eq!(
326 db.stats_get_num_logs_under_time(analytics.time)
327 .await
328 .unwrap(),
329 1
330 );
331 assert_eq!(
332 db.stats_get_num_logs_under_time(analytics.time - 1)
333 .await
334 .unwrap(),
335 0
336 );
337 let limit = 50;
338 let mut offset = 0;
339 let a = db.analytics_fetch(c.key, limit, offset).await.unwrap();
340 assert_eq!(a[0].time, analytics.time);
341 assert_eq!(a[0].difficulty_factor, analytics.difficulty_factor);
342 assert_eq!(a[0].worker_type, analytics.worker_type);
343 offset += 1;
344 assert!(db
345 .analytics_fetch(c.key, limit, offset)
346 .await
347 .unwrap()
348 .is_empty());
349
350 db.analytics_delete_all_records_for_campaign(c.key)
351 .await
352 .unwrap();
353 assert_eq!(db.analytics_fetch(c.key, 1000, 0).await.unwrap().len(), 0);
354 assert!(!db.analytics_captcha_is_published(c.key).await.unwrap());
355
356 let rest_analytics = [
357 CreatePerformanceAnalytics {
358 time: 2,
359 difficulty_factor: 2,
360 worker_type: "wasm".into(),
361 },
362 CreatePerformanceAnalytics {
363 time: 3,
364 difficulty_factor: 3,
365 worker_type: "wasm".into(),
366 },
367 CreatePerformanceAnalytics {
368 time: 4,
369 difficulty_factor: 4,
370 worker_type: "wasm".into(),
371 },
372 CreatePerformanceAnalytics {
373 time: 5,
374 difficulty_factor: 5,
375 worker_type: "wasm".into(),
376 },
377 ];
378 for a in rest_analytics.iter() {
379 db.analysis_save(c.key, &a).await.unwrap();
380 }
381 assert!(db
382 .stats_get_entry_at_location_for_time_limit_asc(1, 2)
383 .await
384 .unwrap()
385 .is_none());
386 assert_eq!(
387 db.stats_get_entry_at_location_for_time_limit_asc(2, 1)
388 .await
389 .unwrap(),
390 Some(2)
391 );
392 assert_eq!(
393 db.stats_get_entry_at_location_for_time_limit_asc(3, 2)
394 .await
395 .unwrap(),
396 Some(3)
397 );
398
399 db.analytics_delete_all_records_for_campaign(c.key)
400 .await
401 .unwrap();
402 assert_eq!(
406 db.get_max_nonce_for_level(c.key, l[0].difficulty_factor)
407 .await
408 .unwrap(),
409 0
410 );
411 db.update_max_nonce_for_level(c.key, l[0].difficulty_factor, 1000)
412 .await
413 .unwrap();
414 assert_eq!(
415 db.get_max_nonce_for_level(c.key, l[0].difficulty_factor)
416 .await
417 .unwrap(),
418 1000
419 );
420 db.update_max_nonce_for_level(c.key, l[0].difficulty_factor, 10_000)
421 .await
422 .unwrap();
423 assert_eq!(
424 db.get_max_nonce_for_level(c.key, l[0].difficulty_factor)
425 .await
426 .unwrap(),
427 10_000
428 );
429 assert_eq!(db.fetch_solve(p.username, c.key).await.unwrap().len(), 1);
432 assert_eq!(
433 db.fetch_config_fetched(p.username, c.key)
434 .await
435 .unwrap()
436 .len(),
437 1
438 );
439 assert_eq!(db.fetch_solve(p.username, c.key).await.unwrap().len(), 1);
440 assert_eq!(db.fetch_confirm(p.username, c.key).await.unwrap().len(), 1);
441
442 db.update_captcha_key(p.username, c.key, p.username)
444 .await
445 .unwrap();
446 assert!(!db.captcha_exists(Some(p.username), c.key).await.unwrap());
448 assert!(db
450 .captcha_exists(Some(p.username), p.username)
451 .await
452 .unwrap());
453
454 db.delete_captcha_levels(p.username, c.key).await.unwrap();
456
457 let mut c2 = c.clone();
459 c2.duration *= c2.duration;
460 c2.description = p.username;
461 db.update_captcha_metadata(p.username, &c2).await.unwrap();
462
463 db.delete_captcha(p.username, p.username).await.unwrap();
465 assert!(!db.captcha_exists(Some(p.username), c.key).await.unwrap());
466}