toasty_driver_integration_suite/tests/
one_model_crud.rs1use crate::prelude::*;
2
3use toasty_core::{
4 driver::{Operation, Rows},
5 stmt::{Source, Statement, UpdateTarget},
6};
7
8#[driver_test(id(ID))]
9pub async fn crud_no_fields(t: &mut Test) -> Result<()> {
10 const MORE: i32 = 10;
11
12 #[derive(Debug, toasty::Model)]
13 struct Item {
14 #[key]
15 #[auto]
16 id: ID,
17 }
18
19 let mut db = t.setup_db(models!(Item)).await;
20
21 let created = Item::create().exec(&mut db).await?;
22
23 let read = Item::filter_by_id(created.id).exec(&mut db).await?;
25
26 assert_eq!(1, read.len());
27 assert_eq!(created.id, read[0].id);
28
29 let mut ids = vec![];
32
33 for _ in 0..MORE {
34 let item = Item::create().exec(&mut db).await?;
35 assert_ne!(item.id, created.id);
36 ids.push(item.id);
37 }
38
39 assert_unique!(ids);
40
41 for id in &ids {
42 let read = Item::filter_by_id(id).exec(&mut db).await?;
43
44 assert_eq!(1, read.len());
45 assert_eq!(*id, read[0].id);
46 }
47
48 ids.shuffle();
50
51 for i in 0..MORE {
53 let id = ids.pop().unwrap();
54
55 if i.is_even() {
56 let val = Item::get_by_id(&mut db, &id).await?;
58 val.delete().exec(&mut db).await?;
59 } else {
60 Item::filter_by_id(id).delete().exec(&mut db).await?;
62 }
63
64 assert_err!(Item::get_by_id(&mut db, id).await);
66
67 for id in &ids {
69 let item = Item::get_by_id(&mut db, id).await?;
70 assert_eq!(*id, item.id);
71 }
72 }
73 Ok(())
74}
75
76#[driver_test(id(ID))]
77pub async fn crud_one_string(test: &mut Test) -> Result<()> {
78 #[derive(Debug, toasty::Model)]
79 struct Item {
80 #[key]
81 #[auto]
82 id: ID,
83
84 val: String,
85 }
86
87 let mut db = test.setup_db(models!(Item)).await;
88
89 let item_table_id = table_id(&db, "items");
90 let is_sql = test.capability().sql;
91
92 let mut created = Item::create().val("hello world").exec(&mut db).await?;
93
94 assert_eq!(created.val, "hello world");
95
96 let read = Item::filter_by_id(created.id).exec(&mut db).await?;
98
99 assert_eq!(1, read.len());
100 assert_eq!(created.id, read[0].id);
101 assert_eq!(created.val, "hello world");
102
103 let mut ids = vec![];
104
105 for i in 0..10 {
106 let item = Item::create()
107 .val(format!("hello {i}"))
108 .exec(&mut db)
109 .await?;
110
111 assert_ne!(item.id, created.id);
112 ids.push(item.id);
113 }
114
115 assert_unique!(ids);
116
117 for (i, id) in ids.iter().enumerate() {
118 let read = Item::filter_by_id(id).exec(&mut db).await?;
119
120 assert_eq!(1, read.len());
121 assert_eq!(*id, read[0].id);
122 assert_eq!(format!("hello {i}"), read[0].val);
123 }
124
125 test.log().clear();
127 created.update().val("updated!").exec(&mut db).await?;
128 assert_eq!(created.val, "updated!");
129
130 let (op, resp) = test.log().pop();
131 if is_sql {
133 assert_struct!(op, Operation::QuerySql(_ {
134 stmt: Statement::Update(_ {
135 target: UpdateTarget::Table(== item_table_id),
136 assignments: #{ 1: _ { expr: == "updated!", .. }},
137 ..
138 }),
139 ret: None,
140 ..
141 }));
142 } else {
143 assert_struct!(op, Operation::UpdateByKey(_ {
144 table: == item_table_id,
145 keys.len(): 1,
146 assignments: #{ 1: _ { expr: == "updated!", .. }},
147 filter: None,
148 returning: false,
149 ..
150 }));
151 }
152 assert_struct!(resp, _ { rows: Rows::Count(1), .. });
153 assert!(test.log().is_empty());
154
155 test.log().clear();
156 let reload = Item::get_by_id(&mut db, &created.id).await?;
157 assert_eq!(reload.val, created.val);
158
159 Item::filter_by_id(created.id)
161 .update()
162 .val("updated again!")
163 .exec(&mut db)
164 .await?;
165 let reload = Item::get_by_id(&mut db, &created.id).await?;
166 assert_eq!(reload.val, "updated again!");
167
168 test.log().clear();
170 reload.delete().exec(&mut db).await?;
171
172 let (op, resp) = test.log().pop();
173 if is_sql {
174 assert_struct!(op, Operation::QuerySql(_ {
175 stmt: Statement::Delete(_ {
176 from: Source::Table(_ {
177 tables: [== item_table_id, ..],
178 ..
179 }),
180 ..
181 }),
182 ..
183 }));
184 } else {
185 assert_struct!(op, Operation::DeleteByKey(_ {
186 table: == item_table_id,
187 keys.len(): 1,
188 filter: None,
189 ..
190 }));
191 }
192 assert_struct!(resp, _ { rows: Rows::Count(1), .. });
193 assert!(test.log().is_empty());
194
195 assert_err!(Item::get_by_id(&mut db, &created.id).await);
197
198 Item::filter_by_id(ids[0]).delete().exec(&mut db).await?;
200
201 assert_err!(Item::get_by_id(&mut db, &ids[0]).await);
203 Ok(())
204}
205
206#[driver_test(id(ID))]
207pub async fn required_field_create_without_setting(test: &mut Test) {
208 #[derive(Debug, toasty::Model)]
209 struct User {
210 #[key]
211 #[auto]
212 id: ID,
213
214 #[allow(dead_code)]
215 name: String,
216 }
217
218 let mut db = test.setup_db(models!(User)).await;
219
220 assert_err!(User::create().exec(&mut db).await);
222}
223
224#[driver_test(id(ID), scenario(crate::scenarios::user_unique_email))]
225pub async fn unique_index_required_field_update(test: &mut Test) -> Result<()> {
226 let mut db = setup(test).await;
227
228 let email = "user1@example.com";
229
230 let user = User::create().email(email).exec(&mut db).await?;
231
232 assert_eq!("user1@example.com", user.email);
233
234 assert_err!(User::create().email(email).exec(&mut db).await);
236
237 let user_reloaded = User::get_by_email(&mut db, email).await?;
239 assert_eq!(user.id, user_reloaded.id);
240 assert_eq!(user_reloaded.email, email);
241
242 let user_alt_email = User::create()
244 .email("alt-email@example.com")
245 .exec(&mut db)
246 .await?;
247
248 assert_ne!(user.id, user_alt_email.id);
249
250 user.delete().exec(&mut db).await?;
252
253 assert_none!(User::filter_by_email(email).first(&mut db).await?);
255
256 let mut user2 = User::create().email(email).exec(&mut db).await?;
257 assert_ne!(user2.id, user_reloaded.id);
258
259 assert_err!(User::create().email(email).exec(&mut db).await);
261
262 user2
264 .update()
265 .email("user2@example.com")
266 .exec(&mut db)
267 .await?;
268
269 let user_reloaded = User::filter_by_id(user2.id).get(&mut db).await?;
271 assert_eq!(user2.id, user_reloaded.id);
272 assert_eq!(user_reloaded.email, "user2@example.com");
273
274 assert_none!(User::filter_by_email(email).first(&mut db).await?);
276
277 assert_err!(
279 User::create()
280 .email("user2@example.com")
281 .exec(&mut db)
282 .await
283 );
284
285 let user3 = User::create().email(email).exec(&mut db).await?;
287 assert_eq!(user3.email, email);
288 assert_ne!(user3.id, user2.id);
289
290 User::filter_by_id(user2.id)
292 .update()
293 .email("user3@example.com")
294 .exec(&mut db)
295 .await?;
296
297 assert_none!(User::filter_by_email(&user2.email).first(&mut db).await?);
299
300 let u = User::filter_by_email("user3@example.com")
302 .get(&mut db)
303 .await?;
304
305 assert_eq!(u.id, user2.id);
306
307 assert_err!(
308 User::create()
309 .email("user3@example.com")
310 .exec(&mut db)
311 .await
312 );
313
314 assert_ok!(
316 User::create()
317 .email("user2@example.com")
318 .exec(&mut db)
319 .await
320 );
321 Ok(())
322}
323
324#[driver_test(id(ID))]
325pub async fn unique_index_nullable_field_update(test: &mut Test) -> Result<()> {
326 #[derive(Debug, toasty::Model)]
327 struct User {
328 #[key]
329 #[auto]
330 id: ID,
331
332 #[unique]
333 email: Option<String>,
334 }
335
336 let mut db = test.setup_db(models!(User)).await;
337
338 let mut u1 = User::create().exec(&mut db).await?;
340 assert!(u1.email.is_none());
341
342 let mut u2 = User::create().exec(&mut db).await?;
344 assert!(u2.email.is_none());
345
346 let u1_reload = User::get_by_id(&mut db, &u1.id).await?;
348 assert!(u1_reload.email.is_none());
349
350 assert_none!(
352 User::filter_by_email("nobody@example.com")
353 .first(&mut db)
354 .await?
355 );
356
357 let mut u3 = User::create()
359 .email("three@example.com")
360 .exec(&mut db)
361 .await?;
362 assert_eq!(u3.email, Some("three@example.com".to_string()));
363
364 let u3_reload = User::get_by_email(&mut db, "three@example.com").await?;
365 assert_eq!(u3_reload.id, u3.id);
366
367 u1.update().email("one@example.com").exec(&mut db).await?;
369 assert_eq!(u1.email, Some("one@example.com".to_string()));
370
371 let u1_reload = User::get_by_email(&mut db, "one@example.com").await?;
373 assert_eq!(u1.id, u1_reload.id);
374
375 assert_err!(u2.update().email("three@example.com").exec(&mut db).await);
377
378 let u3_reload = User::get_by_email(&mut db, "three@example.com").await?;
380 assert_eq!(u3_reload.id, u3.id);
381
382 u2.update().email("two@example.com").exec(&mut db).await?;
384 let u2_reload = User::get_by_email(&mut db, "two@example.com").await?;
385 assert_eq!(u2_reload.id, u2.id);
386
387 let mut update = u3.update();
389 update.set_email(None);
390 update.exec(&mut db).await?;
391 assert!(u3.email.is_none());
392
393 let u4 = User::create()
395 .email("three@example.com")
396 .exec(&mut db)
397 .await?;
398 let u4_reload = User::filter_by_email("three@example.com")
399 .get(&mut db)
400 .await?;
401 assert_eq!(u4_reload.id, u4.id);
402 Ok(())
403}
404
405#[driver_test(id(ID))]
406pub async fn unique_index_no_update(test: &mut Test) -> Result<()> {
407 #[derive(Debug, toasty::Model)]
408 struct User {
409 #[key]
410 #[auto]
411 id: ID,
412
413 #[unique]
414 email: String,
415
416 name: String,
417 }
418
419 let mut db = test.setup_db(models!(User)).await;
420
421 let mut user = User::create()
422 .email("user@example.com")
423 .name("John Doe")
424 .exec(&mut db)
425 .await?;
426
427 let u = User::filter_by_id(user.id).get(&mut db).await?;
428 assert_eq!(user.name, u.name);
429
430 user.update().name("Jane Doe").exec(&mut db).await?;
432
433 assert_eq!("Jane Doe", user.name);
434
435 let u = User::get_by_id(&mut db, &user.id).await?;
436 assert_eq!(user.name, u.name);
437
438 let u = User::get_by_email(&mut db, &user.email).await?;
440 assert_eq!(user.name, u.name);
441 Ok(())
442}
443
444#[driver_test(id(ID))]
445pub async fn batch_get_by_id(test: &mut Test) -> Result<()> {
446 #[derive(Debug, toasty::Model)]
447 struct Item {
448 #[key]
449 #[auto]
450 id: ID,
451 }
452
453 let mut db = test.setup_db(models!(Item)).await;
454 let mut keys = vec![];
455
456 for _ in 0..5 {
457 let item = Item::create().exec(&mut db).await?;
458 keys.push(item.id);
459 }
460
461 let items: Vec<_> = Item::filter_by_id_batch([&keys[0], &keys[1], &keys[2]])
462 .exec(&mut db)
463 .await?;
464
465 assert_eq!(3, items.len());
466
467 for item in items {
468 assert!(keys.contains(&item.id));
469 }
470 Ok(())
471}
472
473#[driver_test(id(ID))]
474pub async fn empty_batch_get_by_id(test: &mut Test) -> Result<()> {
475 #[derive(Debug, toasty::Model)]
476 struct Item {
477 #[key]
478 #[auto]
479 id: ID,
480 }
481
482 let mut db = test.setup_db(models!(Item)).await;
483 let mut ids = vec![];
484
485 for _ in 0..5 {
486 let item = Item::create().exec(&mut db).await?;
487 ids.push(item.id);
488 }
489
490 let items: Vec<_> = Item::filter_by_id_batch(&[] as &[ID]).exec(&mut db).await?;
491
492 assert_eq!(0, items.len());
493 Ok(())
494}
495
496#[driver_test(id(ID))]
497pub async fn update_multiple_fields(test: &mut Test) -> Result<()> {
498 #[derive(Debug, toasty::Model)]
499 struct User {
500 #[key]
501 #[auto]
502 id: ID,
503
504 name: String,
505 email: String,
506 }
507
508 let mut db = test.setup_db(models!(User)).await;
509
510 let mut user = User::create()
511 .name("John Doe")
512 .email("john@example.com")
513 .exec(&mut db)
514 .await?;
515
516 user.update()
518 .name("Jane Doe")
519 .email("jane@example.com")
520 .exec(&mut db)
521 .await?;
522
523 assert_eq!("Jane Doe", user.name);
524 assert_eq!("jane@example.com", user.email);
525
526 let user = User::get_by_id(&mut db, &user.id).await?;
527 assert_eq!("Jane Doe", user.name);
528 assert_eq!("jane@example.com", user.email);
529
530 User::filter_by_id(user.id)
532 .update()
533 .name("John2 Doe")
534 .email("john2@example.com")
535 .exec(&mut db)
536 .await?;
537
538 let user = User::get_by_id(&mut db, &user.id).await?;
539 assert_eq!("John2 Doe", user.name);
540 assert_eq!("john2@example.com", user.email);
541 Ok(())
542}
543
544#[driver_test(id(ID))]
545pub async fn update_and_delete_snippets(test: &mut Test) -> Result<()> {
546 #[derive(Debug, toasty::Model)]
547 struct User {
548 #[key]
549 #[auto]
550 id: ID,
551
552 #[allow(dead_code)]
553 name: String,
554 }
555
556 let mut db = test.setup_db(models!(User)).await;
557
558 let user = User::create().name("John Doe").exec(&mut db).await?;
559
560 User::update_by_id(user.id)
561 .name("John Doe2")
562 .exec(&mut db)
563 .await?;
564
565 let new_user = User::get_by_id(&mut db, user.id).await?;
566 assert!(new_user.name == "John Doe2");
567
568 User::delete_by_id(&mut db, user.id).await?;
569
570 assert_err!(User::get_by_id(&mut db, user.id).await);
571 Ok(())
572}