toasty_driver_integration_suite/tests/
crud_basic.rs1use crate::prelude::*;
2
3use toasty_core::{
4 driver::{Operation, Rows},
5 stmt::{Assignment, Expr, 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]: Assignment::Set(Expr::Arg({ position: 0 }))},
137 }),
138 params: [{ value: == "updated!" }, ..],
139 ret: None,
140 }));
141 } else {
142 assert_struct!(op, Operation::UpdateByKey({
143 table: == item_table_id,
144 keys.len(): 1,
145 assignments: #{ [1]: Assignment::Set(== "updated!")},
146 filter: None,
147 returning: false,
148 }));
149 }
150 assert_struct!(resp, { values: Rows::Count(1) });
151 assert!(test.log().is_empty());
152
153 test.log().clear();
154 let reload = Item::get_by_id(&mut db, &created.id).await?;
155 assert_eq!(reload.val, created.val);
156
157 Item::filter_by_id(created.id)
159 .update()
160 .val("updated again!")
161 .exec(&mut db)
162 .await?;
163 let reload = Item::get_by_id(&mut db, &created.id).await?;
164 assert_eq!(reload.val, "updated again!");
165
166 test.log().clear();
168 reload.delete().exec(&mut db).await?;
169
170 let (op, resp) = test.log().pop();
171 if is_sql {
172 assert_struct!(op, Operation::QuerySql({
173 stmt: Statement::Delete({
174 from: Source::Table({
175 tables: [== item_table_id, ..],
176 }),
177 }),
178 }));
179 } else {
180 assert_struct!(op, Operation::DeleteByKey({
181 table: == item_table_id,
182 keys.len(): 1,
183 filter: None,
184 }));
185 }
186 assert_struct!(resp, { values: Rows::Count(1) });
187 assert!(test.log().is_empty());
188
189 assert_err!(Item::get_by_id(&mut db, &created.id).await);
191
192 Item::filter_by_id(ids[0]).delete().exec(&mut db).await?;
194
195 assert_err!(Item::get_by_id(&mut db, &ids[0]).await);
197 Ok(())
198}
199
200#[driver_test(id(ID))]
201pub async fn required_field_create_without_setting(test: &mut Test) {
202 #[derive(Debug, toasty::Model)]
203 struct User {
204 #[key]
205 #[auto]
206 id: ID,
207
208 #[allow(dead_code)]
209 name: String,
210 }
211
212 let mut db = test.setup_db(models!(User)).await;
213
214 assert_err!(User::create().exec(&mut db).await);
216}
217
218#[driver_test(id(ID), scenario(crate::scenarios::user_unique_email))]
219pub async fn unique_index_required_field_update(test: &mut Test) -> Result<()> {
220 let mut db = setup(test).await;
221
222 let email = "user1@example.com";
223
224 let user = User::create().email(email).exec(&mut db).await?;
225
226 assert_eq!("user1@example.com", user.email);
227
228 assert_err!(User::create().email(email).exec(&mut db).await);
230
231 let user_reloaded = User::get_by_email(&mut db, email).await?;
233 assert_eq!(user.id, user_reloaded.id);
234 assert_eq!(user_reloaded.email, email);
235
236 let user_alt_email = User::create()
238 .email("alt-email@example.com")
239 .exec(&mut db)
240 .await?;
241
242 assert_ne!(user.id, user_alt_email.id);
243
244 user.delete().exec(&mut db).await?;
246
247 assert_none!(User::filter_by_email(email).first().exec(&mut db).await?);
249
250 let mut user2 = User::create().email(email).exec(&mut db).await?;
251 assert_ne!(user2.id, user_reloaded.id);
252
253 assert_err!(User::create().email(email).exec(&mut db).await);
255
256 user2
258 .update()
259 .email("user2@example.com")
260 .exec(&mut db)
261 .await?;
262
263 let user_reloaded = User::filter_by_id(user2.id).get(&mut db).await?;
265 assert_eq!(user2.id, user_reloaded.id);
266 assert_eq!(user_reloaded.email, "user2@example.com");
267
268 assert_none!(User::filter_by_email(email).first().exec(&mut db).await?);
270
271 assert_err!(
273 User::create()
274 .email("user2@example.com")
275 .exec(&mut db)
276 .await
277 );
278
279 let user3 = User::create().email(email).exec(&mut db).await?;
281 assert_eq!(user3.email, email);
282 assert_ne!(user3.id, user2.id);
283
284 User::filter_by_id(user2.id)
286 .update()
287 .email("user3@example.com")
288 .exec(&mut db)
289 .await?;
290
291 assert_none!(
293 User::filter_by_email(&user2.email)
294 .first()
295 .exec(&mut db)
296 .await?
297 );
298
299 let u = User::filter_by_email("user3@example.com")
301 .get(&mut db)
302 .await?;
303
304 assert_eq!(u.id, user2.id);
305
306 assert_err!(
307 User::create()
308 .email("user3@example.com")
309 .exec(&mut db)
310 .await
311 );
312
313 assert_ok!(
315 User::create()
316 .email("user2@example.com")
317 .exec(&mut db)
318 .await
319 );
320 Ok(())
321}
322
323#[driver_test(id(ID))]
324pub async fn unique_index_nullable_field_update(test: &mut Test) -> Result<()> {
325 #[derive(Debug, toasty::Model)]
326 struct User {
327 #[key]
328 #[auto]
329 id: ID,
330
331 #[unique]
332 email: Option<String>,
333 }
334
335 let mut db = test.setup_db(models!(User)).await;
336
337 let mut u1 = User::create().exec(&mut db).await?;
339 assert!(u1.email.is_none());
340
341 let mut u2 = User::create().exec(&mut db).await?;
343 assert!(u2.email.is_none());
344
345 let u1_reload = User::get_by_id(&mut db, &u1.id).await?;
347 assert!(u1_reload.email.is_none());
348
349 assert_none!(
351 User::filter_by_email("nobody@example.com")
352 .first()
353 .exec(&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 unique_index_set_same_value(test: &mut Test) -> Result<()> {
446 #[derive(Debug, toasty::Model)]
447 struct User {
448 #[key]
449 #[auto]
450 id: ID,
451
452 #[unique]
453 email: String,
454
455 name: String,
456 }
457
458 let mut db = test.setup_db(models!(User)).await;
459
460 let mut user = toasty::create!(User {
461 email: "user@example.com",
462 name: "John Doe",
463 })
464 .exec(&mut db)
465 .await?;
466
467 user.update()
471 .email("user@example.com")
472 .name("Jane Doe")
473 .exec(&mut db)
474 .await?;
475
476 assert_eq!("user@example.com", user.email);
477 assert_eq!("Jane Doe", user.name);
478
479 let u = User::get_by_id(&mut db, &user.id).await?;
480 assert_eq!(user.email, u.email);
481 assert_eq!(user.name, u.name);
482
483 let u = User::get_by_email(&mut db, &user.email).await?;
485 assert_eq!(user.name, u.name);
486
487 Ok(())
488}
489
490#[driver_test(id(ID))]
491pub async fn update_multiple_fields(test: &mut Test) -> Result<()> {
492 #[derive(Debug, toasty::Model)]
493 struct User {
494 #[key]
495 #[auto]
496 id: ID,
497
498 name: String,
499 email: String,
500 }
501
502 let mut db = test.setup_db(models!(User)).await;
503
504 let mut user = User::create()
505 .name("John Doe")
506 .email("john@example.com")
507 .exec(&mut db)
508 .await?;
509
510 user.update()
512 .name("Jane Doe")
513 .email("jane@example.com")
514 .exec(&mut db)
515 .await?;
516
517 assert_eq!("Jane Doe", user.name);
518 assert_eq!("jane@example.com", user.email);
519
520 let user = User::get_by_id(&mut db, &user.id).await?;
521 assert_eq!("Jane Doe", user.name);
522 assert_eq!("jane@example.com", user.email);
523
524 User::filter_by_id(user.id)
526 .update()
527 .name("John2 Doe")
528 .email("john2@example.com")
529 .exec(&mut db)
530 .await?;
531
532 let user = User::get_by_id(&mut db, &user.id).await?;
533 assert_eq!("John2 Doe", user.name);
534 assert_eq!("john2@example.com", user.email);
535 Ok(())
536}
537
538#[driver_test(id(ID))]
539pub async fn update_and_delete_snippets(test: &mut Test) -> Result<()> {
540 #[derive(Debug, toasty::Model)]
541 struct User {
542 #[key]
543 #[auto]
544 id: ID,
545
546 #[allow(dead_code)]
547 name: String,
548 }
549
550 let mut db = test.setup_db(models!(User)).await;
551
552 let user = User::create().name("John Doe").exec(&mut db).await?;
553
554 User::update_by_id(user.id)
555 .name("John Doe2")
556 .exec(&mut db)
557 .await?;
558
559 let new_user = User::get_by_id(&mut db, user.id).await?;
560 assert!(new_user.name == "John Doe2");
561
562 User::delete_by_id(&mut db, user.id).await?;
563
564 assert_err!(User::get_by_id(&mut db, user.id).await);
565 Ok(())
566}