toasty_driver_integration_suite/tests/
crud_basic.rs1use crate::prelude::*;
2
3use toasty_core::{
4 driver::{Operation, Rows},
5 stmt::{Assignment, 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(== "updated!")},
137 }),
138 ret: None,
139 }));
140 } else {
141 assert_struct!(op, Operation::UpdateByKey({
142 table: == item_table_id,
143 keys.len(): 1,
144 assignments: #{ [1]: Assignment::Set(== "updated!")},
145 filter: None,
146 returning: false,
147 }));
148 }
149 assert_struct!(resp, { values: Rows::Count(1) });
150 assert!(test.log().is_empty());
151
152 test.log().clear();
153 let reload = Item::get_by_id(&mut db, &created.id).await?;
154 assert_eq!(reload.val, created.val);
155
156 Item::filter_by_id(created.id)
158 .update()
159 .val("updated again!")
160 .exec(&mut db)
161 .await?;
162 let reload = Item::get_by_id(&mut db, &created.id).await?;
163 assert_eq!(reload.val, "updated again!");
164
165 test.log().clear();
167 reload.delete().exec(&mut db).await?;
168
169 let (op, resp) = test.log().pop();
170 if is_sql {
171 assert_struct!(op, Operation::QuerySql({
172 stmt: Statement::Delete({
173 from: Source::Table({
174 tables: [== item_table_id, ..],
175 }),
176 }),
177 }));
178 } else {
179 assert_struct!(op, Operation::DeleteByKey({
180 table: == item_table_id,
181 keys.len(): 1,
182 filter: None,
183 }));
184 }
185 assert_struct!(resp, { values: Rows::Count(1) });
186 assert!(test.log().is_empty());
187
188 assert_err!(Item::get_by_id(&mut db, &created.id).await);
190
191 Item::filter_by_id(ids[0]).delete().exec(&mut db).await?;
193
194 assert_err!(Item::get_by_id(&mut db, &ids[0]).await);
196 Ok(())
197}
198
199#[driver_test(id(ID))]
200pub async fn required_field_create_without_setting(test: &mut Test) {
201 #[derive(Debug, toasty::Model)]
202 struct User {
203 #[key]
204 #[auto]
205 id: ID,
206
207 #[allow(dead_code)]
208 name: String,
209 }
210
211 let mut db = test.setup_db(models!(User)).await;
212
213 assert_err!(User::create().exec(&mut db).await);
215}
216
217#[driver_test(id(ID), scenario(crate::scenarios::user_unique_email))]
218pub async fn unique_index_required_field_update(test: &mut Test) -> Result<()> {
219 let mut db = setup(test).await;
220
221 let email = "user1@example.com";
222
223 let user = User::create().email(email).exec(&mut db).await?;
224
225 assert_eq!("user1@example.com", user.email);
226
227 assert_err!(User::create().email(email).exec(&mut db).await);
229
230 let user_reloaded = User::get_by_email(&mut db, email).await?;
232 assert_eq!(user.id, user_reloaded.id);
233 assert_eq!(user_reloaded.email, email);
234
235 let user_alt_email = User::create()
237 .email("alt-email@example.com")
238 .exec(&mut db)
239 .await?;
240
241 assert_ne!(user.id, user_alt_email.id);
242
243 user.delete().exec(&mut db).await?;
245
246 assert_none!(User::filter_by_email(email).first().exec(&mut db).await?);
248
249 let mut user2 = User::create().email(email).exec(&mut db).await?;
250 assert_ne!(user2.id, user_reloaded.id);
251
252 assert_err!(User::create().email(email).exec(&mut db).await);
254
255 user2
257 .update()
258 .email("user2@example.com")
259 .exec(&mut db)
260 .await?;
261
262 let user_reloaded = User::filter_by_id(user2.id).get(&mut db).await?;
264 assert_eq!(user2.id, user_reloaded.id);
265 assert_eq!(user_reloaded.email, "user2@example.com");
266
267 assert_none!(User::filter_by_email(email).first().exec(&mut db).await?);
269
270 assert_err!(
272 User::create()
273 .email("user2@example.com")
274 .exec(&mut db)
275 .await
276 );
277
278 let user3 = User::create().email(email).exec(&mut db).await?;
280 assert_eq!(user3.email, email);
281 assert_ne!(user3.id, user2.id);
282
283 User::filter_by_id(user2.id)
285 .update()
286 .email("user3@example.com")
287 .exec(&mut db)
288 .await?;
289
290 assert_none!(
292 User::filter_by_email(&user2.email)
293 .first()
294 .exec(&mut db)
295 .await?
296 );
297
298 let u = User::filter_by_email("user3@example.com")
300 .get(&mut db)
301 .await?;
302
303 assert_eq!(u.id, user2.id);
304
305 assert_err!(
306 User::create()
307 .email("user3@example.com")
308 .exec(&mut db)
309 .await
310 );
311
312 assert_ok!(
314 User::create()
315 .email("user2@example.com")
316 .exec(&mut db)
317 .await
318 );
319 Ok(())
320}
321
322#[driver_test(id(ID))]
323pub async fn unique_index_nullable_field_update(test: &mut Test) -> Result<()> {
324 #[derive(Debug, toasty::Model)]
325 struct User {
326 #[key]
327 #[auto]
328 id: ID,
329
330 #[unique]
331 email: Option<String>,
332 }
333
334 let mut db = test.setup_db(models!(User)).await;
335
336 let mut u1 = User::create().exec(&mut db).await?;
338 assert!(u1.email.is_none());
339
340 let mut u2 = User::create().exec(&mut db).await?;
342 assert!(u2.email.is_none());
343
344 let u1_reload = User::get_by_id(&mut db, &u1.id).await?;
346 assert!(u1_reload.email.is_none());
347
348 assert_none!(
350 User::filter_by_email("nobody@example.com")
351 .first()
352 .exec(&mut db)
353 .await?
354 );
355
356 let mut u3 = User::create()
358 .email("three@example.com")
359 .exec(&mut db)
360 .await?;
361 assert_eq!(u3.email, Some("three@example.com".to_string()));
362
363 let u3_reload = User::get_by_email(&mut db, "three@example.com").await?;
364 assert_eq!(u3_reload.id, u3.id);
365
366 u1.update().email("one@example.com").exec(&mut db).await?;
368 assert_eq!(u1.email, Some("one@example.com".to_string()));
369
370 let u1_reload = User::get_by_email(&mut db, "one@example.com").await?;
372 assert_eq!(u1.id, u1_reload.id);
373
374 assert_err!(u2.update().email("three@example.com").exec(&mut db).await);
376
377 let u3_reload = User::get_by_email(&mut db, "three@example.com").await?;
379 assert_eq!(u3_reload.id, u3.id);
380
381 u2.update().email("two@example.com").exec(&mut db).await?;
383 let u2_reload = User::get_by_email(&mut db, "two@example.com").await?;
384 assert_eq!(u2_reload.id, u2.id);
385
386 let mut update = u3.update();
388 update.set_email(None);
389 update.exec(&mut db).await?;
390 assert!(u3.email.is_none());
391
392 let u4 = User::create()
394 .email("three@example.com")
395 .exec(&mut db)
396 .await?;
397 let u4_reload = User::filter_by_email("three@example.com")
398 .get(&mut db)
399 .await?;
400 assert_eq!(u4_reload.id, u4.id);
401 Ok(())
402}
403
404#[driver_test(id(ID))]
405pub async fn unique_index_no_update(test: &mut Test) -> Result<()> {
406 #[derive(Debug, toasty::Model)]
407 struct User {
408 #[key]
409 #[auto]
410 id: ID,
411
412 #[unique]
413 email: String,
414
415 name: String,
416 }
417
418 let mut db = test.setup_db(models!(User)).await;
419
420 let mut user = User::create()
421 .email("user@example.com")
422 .name("John Doe")
423 .exec(&mut db)
424 .await?;
425
426 let u = User::filter_by_id(user.id).get(&mut db).await?;
427 assert_eq!(user.name, u.name);
428
429 user.update().name("Jane Doe").exec(&mut db).await?;
431
432 assert_eq!("Jane Doe", user.name);
433
434 let u = User::get_by_id(&mut db, &user.id).await?;
435 assert_eq!(user.name, u.name);
436
437 let u = User::get_by_email(&mut db, &user.email).await?;
439 assert_eq!(user.name, u.name);
440 Ok(())
441}
442
443#[driver_test(id(ID))]
444pub async fn update_multiple_fields(test: &mut Test) -> Result<()> {
445 #[derive(Debug, toasty::Model)]
446 struct User {
447 #[key]
448 #[auto]
449 id: ID,
450
451 name: String,
452 email: String,
453 }
454
455 let mut db = test.setup_db(models!(User)).await;
456
457 let mut user = User::create()
458 .name("John Doe")
459 .email("john@example.com")
460 .exec(&mut db)
461 .await?;
462
463 user.update()
465 .name("Jane Doe")
466 .email("jane@example.com")
467 .exec(&mut db)
468 .await?;
469
470 assert_eq!("Jane Doe", user.name);
471 assert_eq!("jane@example.com", user.email);
472
473 let user = User::get_by_id(&mut db, &user.id).await?;
474 assert_eq!("Jane Doe", user.name);
475 assert_eq!("jane@example.com", user.email);
476
477 User::filter_by_id(user.id)
479 .update()
480 .name("John2 Doe")
481 .email("john2@example.com")
482 .exec(&mut db)
483 .await?;
484
485 let user = User::get_by_id(&mut db, &user.id).await?;
486 assert_eq!("John2 Doe", user.name);
487 assert_eq!("john2@example.com", user.email);
488 Ok(())
489}
490
491#[driver_test(id(ID))]
492pub async fn update_and_delete_snippets(test: &mut Test) -> Result<()> {
493 #[derive(Debug, toasty::Model)]
494 struct User {
495 #[key]
496 #[auto]
497 id: ID,
498
499 #[allow(dead_code)]
500 name: String,
501 }
502
503 let mut db = test.setup_db(models!(User)).await;
504
505 let user = User::create().name("John Doe").exec(&mut db).await?;
506
507 User::update_by_id(user.id)
508 .name("John Doe2")
509 .exec(&mut db)
510 .await?;
511
512 let new_user = User::get_by_id(&mut db, user.id).await?;
513 assert!(new_user.name == "John Doe2");
514
515 User::delete_by_id(&mut db, user.id).await?;
516
517 assert_err!(User::get_by_id(&mut db, user.id).await);
518 Ok(())
519}