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: None,
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), scenario(crate::scenarios::two_models))]
201pub async fn required_field_create_without_setting(test: &mut Test) {
202 let mut db = setup(test).await;
203
204 assert_err!(User::create().exec(&mut db).await);
206}
207
208#[driver_test(id(ID), scenario(crate::scenarios::user_unique_email))]
209pub async fn unique_index_required_field_update(test: &mut Test) -> Result<()> {
210 let mut db = setup(test).await;
211
212 let email = "user1@example.com";
213
214 let user = User::create().email(email).exec(&mut db).await?;
215
216 assert_eq!("user1@example.com", user.email);
217
218 assert_err!(User::create().email(email).exec(&mut db).await);
220
221 let user_reloaded = User::get_by_email(&mut db, email).await?;
223 assert_eq!(user.id, user_reloaded.id);
224 assert_eq!(user_reloaded.email, email);
225
226 let user_alt_email = User::create()
228 .email("alt-email@example.com")
229 .exec(&mut db)
230 .await?;
231
232 assert_ne!(user.id, user_alt_email.id);
233
234 user.delete().exec(&mut db).await?;
236
237 assert_none!(User::filter_by_email(email).first().exec(&mut db).await?);
239
240 let mut user2 = User::create().email(email).exec(&mut db).await?;
241 assert_ne!(user2.id, user_reloaded.id);
242
243 assert_err!(User::create().email(email).exec(&mut db).await);
245
246 user2
248 .update()
249 .email("user2@example.com")
250 .exec(&mut db)
251 .await?;
252
253 let user_reloaded = User::filter_by_id(user2.id).get(&mut db).await?;
255 assert_eq!(user2.id, user_reloaded.id);
256 assert_eq!(user_reloaded.email, "user2@example.com");
257
258 assert_none!(User::filter_by_email(email).first().exec(&mut db).await?);
260
261 assert_err!(
263 User::create()
264 .email("user2@example.com")
265 .exec(&mut db)
266 .await
267 );
268
269 let user3 = User::create().email(email).exec(&mut db).await?;
271 assert_eq!(user3.email, email);
272 assert_ne!(user3.id, user2.id);
273
274 User::filter_by_id(user2.id)
276 .update()
277 .email("user3@example.com")
278 .exec(&mut db)
279 .await?;
280
281 assert_none!(
283 User::filter_by_email(&user2.email)
284 .first()
285 .exec(&mut db)
286 .await?
287 );
288
289 let u = User::filter_by_email("user3@example.com")
291 .get(&mut db)
292 .await?;
293
294 assert_eq!(u.id, user2.id);
295
296 assert_err!(
297 User::create()
298 .email("user3@example.com")
299 .exec(&mut db)
300 .await
301 );
302
303 assert_ok!(
305 User::create()
306 .email("user2@example.com")
307 .exec(&mut db)
308 .await
309 );
310 Ok(())
311}
312
313#[driver_test(id(ID))]
314pub async fn unique_index_nullable_field_update(test: &mut Test) -> Result<()> {
315 #[derive(Debug, toasty::Model)]
316 struct User {
317 #[key]
318 #[auto]
319 id: ID,
320
321 #[unique]
322 email: Option<String>,
323 }
324
325 let mut db = test.setup_db(models!(User)).await;
326
327 let mut u1 = User::create().exec(&mut db).await?;
329 assert!(u1.email.is_none());
330
331 let mut u2 = User::create().exec(&mut db).await?;
333 assert!(u2.email.is_none());
334
335 let u1_reload = User::get_by_id(&mut db, &u1.id).await?;
337 assert!(u1_reload.email.is_none());
338
339 assert_none!(
341 User::filter_by_email("nobody@example.com")
342 .first()
343 .exec(&mut db)
344 .await?
345 );
346
347 let mut u3 = User::create()
349 .email("three@example.com")
350 .exec(&mut db)
351 .await?;
352 assert_eq!(u3.email, Some("three@example.com".to_string()));
353
354 let u3_reload = User::get_by_email(&mut db, "three@example.com").await?;
355 assert_eq!(u3_reload.id, u3.id);
356
357 u1.update().email("one@example.com").exec(&mut db).await?;
359 assert_eq!(u1.email, Some("one@example.com".to_string()));
360
361 let u1_reload = User::get_by_email(&mut db, "one@example.com").await?;
363 assert_eq!(u1.id, u1_reload.id);
364
365 assert_err!(u2.update().email("three@example.com").exec(&mut db).await);
367
368 let u3_reload = User::get_by_email(&mut db, "three@example.com").await?;
370 assert_eq!(u3_reload.id, u3.id);
371
372 u2.update().email("two@example.com").exec(&mut db).await?;
374 let u2_reload = User::get_by_email(&mut db, "two@example.com").await?;
375 assert_eq!(u2_reload.id, u2.id);
376
377 let mut update = u3.update();
379 update.set_email(None);
380 update.exec(&mut db).await?;
381 assert!(u3.email.is_none());
382
383 let u4 = User::create()
385 .email("three@example.com")
386 .exec(&mut db)
387 .await?;
388 let u4_reload = User::filter_by_email("three@example.com")
389 .get(&mut db)
390 .await?;
391 assert_eq!(u4_reload.id, u4.id);
392 Ok(())
393}
394
395#[driver_test(id(ID), scenario(crate::scenarios::user_unique_email_with_name))]
396pub async fn unique_index_no_update(test: &mut Test) -> Result<()> {
397 let mut db = setup(test).await;
398
399 let mut user = User::create()
400 .email("user@example.com")
401 .name("John Doe")
402 .exec(&mut db)
403 .await?;
404
405 let u = User::filter_by_id(user.id).get(&mut db).await?;
406 assert_eq!(user.name, u.name);
407
408 user.update().name("Jane Doe").exec(&mut db).await?;
410
411 assert_eq!("Jane Doe", user.name);
412
413 let u = User::get_by_id(&mut db, &user.id).await?;
414 assert_eq!(user.name, u.name);
415
416 let u = User::get_by_email(&mut db, &user.email).await?;
418 assert_eq!(user.name, u.name);
419 Ok(())
420}
421
422#[driver_test(id(ID), scenario(crate::scenarios::user_unique_email_with_name))]
423pub async fn unique_index_set_same_value(test: &mut Test) -> Result<()> {
424 let mut db = setup(test).await;
425
426 let mut user = toasty::create!(User {
427 email: "user@example.com",
428 name: "John Doe",
429 })
430 .exec(&mut db)
431 .await?;
432
433 user.update()
437 .email("user@example.com")
438 .name("Jane Doe")
439 .exec(&mut db)
440 .await?;
441
442 assert_eq!("user@example.com", user.email);
443 assert_eq!("Jane Doe", user.name);
444
445 let u = User::get_by_id(&mut db, &user.id).await?;
446 assert_eq!(user.email, u.email);
447 assert_eq!(user.name, u.name);
448
449 let u = User::get_by_email(&mut db, &user.email).await?;
451 assert_eq!(user.name, u.name);
452
453 Ok(())
454}
455
456#[driver_test(id(ID), scenario(crate::scenarios::user_name_email))]
457pub async fn update_multiple_fields(test: &mut Test) -> Result<()> {
458 let mut db = setup(test).await;
459
460 let mut user = User::create()
461 .name("John Doe")
462 .email("john@example.com")
463 .exec(&mut db)
464 .await?;
465
466 user.update()
468 .name("Jane Doe")
469 .email("jane@example.com")
470 .exec(&mut db)
471 .await?;
472
473 assert_eq!("Jane Doe", user.name);
474 assert_eq!("jane@example.com", user.email);
475
476 let user = User::get_by_id(&mut db, &user.id).await?;
477 assert_eq!("Jane Doe", user.name);
478 assert_eq!("jane@example.com", user.email);
479
480 User::filter_by_id(user.id)
482 .update()
483 .name("John2 Doe")
484 .email("john2@example.com")
485 .exec(&mut db)
486 .await?;
487
488 let user = User::get_by_id(&mut db, &user.id).await?;
489 assert_eq!("John2 Doe", user.name);
490 assert_eq!("john2@example.com", user.email);
491 Ok(())
492}
493
494#[driver_test(id(ID), scenario(crate::scenarios::two_models))]
495pub async fn update_and_delete_snippets(test: &mut Test) -> Result<()> {
496 let mut db = setup(test).await;
497
498 let user = User::create().name("John Doe").exec(&mut db).await?;
499
500 User::update_by_id(user.id)
501 .name("John Doe2")
502 .exec(&mut db)
503 .await?;
504
505 let new_user = User::get_by_id(&mut db, user.id).await?;
506 assert!(new_user.name == "John Doe2");
507
508 User::delete_by_id(&mut db, user.id).await?;
509
510 assert_err!(User::get_by_id(&mut db, user.id).await);
511 Ok(())
512}