toasty_driver_integration_suite/tests/
relation_has_one_crud.rs1use crate::prelude::*;
2
3#[driver_test(id(ID), scenario(crate::scenarios::has_one_optional_belongs_to))]
4pub async fn crud_has_one_bi_direction_optional(test: &mut Test) -> Result<()> {
5 let mut db = setup(test).await;
6
7 let user = User::create().name("Jane Doe").exec(&mut db).await?;
9
10 assert_none!(user.profile().exec(&mut db).await?);
12
13 let profile = user
15 .profile()
16 .create()
17 .bio("a person")
18 .exec(&mut db)
19 .await?;
20
21 let profile_reload = user.profile().exec(&mut db).await?.unwrap();
23 assert_eq!(profile.id, profile_reload.id);
24
25 let user_reload = profile.user().exec(&mut db).await?.unwrap();
27 assert_eq!(user.id, user_reload.id);
28
29 let mut user = User::create()
31 .name("Tim Apple")
32 .profile(Profile::create().bio("an apple a day"))
33 .exec(&mut db)
34 .await?;
35
36 let profile = user.profile().exec(&mut db).await?.unwrap();
37 assert_eq!(profile.bio, "an apple a day");
38
39 assert_eq!(user.id, profile.user().exec(&mut db).await?.unwrap().id);
41
42 user.update()
44 .profile(Profile::create().bio("keeps the doctor away"))
45 .exec(&mut db)
46 .await?;
47
48 let profile = user.profile().exec(&mut db).await?.unwrap();
50 assert_eq!(profile.bio, "keeps the doctor away");
51 assert_eq!(user.id, profile.user().exec(&mut db).await?.unwrap().id);
52
53 user.update().profile(None).exec(&mut db).await?;
55
56 assert!(user.profile().exec(&mut db).await?.is_none());
58
59 let profile_reloaded = Profile::filter_by_id(profile.id).get(&mut db).await?;
60 assert_none!(profile_reloaded.user_id);
61
62 user.update()
63 .profile(&profile_reloaded)
64 .exec(&mut db)
65 .await?;
66
67 let profile_reloaded = Profile::get_by_id(&mut db, &profile.id).await?;
68 assert_eq!(&user.id, profile_reloaded.user_id.as_ref().unwrap());
69
70 profile_reloaded.delete().exec(&mut db).await?;
72
73 let mut user_reloaded = User::get_by_id(&mut db, &user.id).await?;
74 assert_none!(user_reloaded.profile().exec(&mut db).await?);
75
76 user_reloaded
78 .update()
79 .profile(Profile::create().bio("hello"))
80 .exec(&mut db)
81 .await?;
82
83 let profile_id = user_reloaded.profile().exec(&mut db).await?.unwrap().id;
84
85 user_reloaded.delete().exec(&mut db).await?;
87
88 let profile_reloaded = Profile::get_by_id(&mut db, &profile_id).await?;
89 assert_none!(profile_reloaded.user_id);
90 Ok(())
91}
92
93#[driver_test]
100pub async fn crud_has_one_required_belongs_to_optional(test: &mut Test) -> Result<()> {
101 #[derive(Debug, toasty::Model)]
102 struct User {
103 #[key]
104 #[auto]
105 id: uuid::Uuid,
106
107 #[has_one]
108 profile: toasty::Deferred<Profile>,
109 }
110
111 #[derive(Debug, toasty::Model)]
112 struct Profile {
113 #[key]
114 #[auto]
115 id: uuid::Uuid,
116
117 #[unique]
118 user_id: Option<uuid::Uuid>,
119
120 #[belongs_to(key = user_id, references = id)]
121 user: toasty::Deferred<Option<User>>,
122
123 bio: String,
124 }
125
126 let mut db = test.setup_db(models!(User, Profile)).await;
127
128 let user = User::create()
130 .profile(Profile::create().bio("an apple a day"))
131 .exec(&mut db)
132 .await?;
133
134 let profile = user.profile().exec(&mut db).await?;
135 assert_eq!(profile.bio, "an apple a day");
136
137 assert_eq!(user.id, profile.user().exec(&mut db).await?.unwrap().id);
139
140 user.delete().exec(&mut db).await?;
142 let profile_reloaded = Profile::get_by_id(&mut db, &profile.id).await?;
143 assert_none!(profile_reloaded.user_id);
144
145 assert_err!(User::create().exec(&mut db).await);
148 Ok(())
149}
150
151#[driver_test]
152pub async fn update_belongs_to_with_required_has_one_pair(test: &mut Test) -> Result<()> {
153 #[derive(Debug, toasty::Model)]
154 struct User {
155 #[key]
156 #[auto]
157 id: uuid::Uuid,
158
159 #[has_one]
160 profile: toasty::Deferred<Profile>,
161 }
162
163 #[derive(Debug, toasty::Model)]
164 struct Profile {
165 #[key]
166 #[auto]
167 id: uuid::Uuid,
168
169 #[unique]
170 user_id: Option<uuid::Uuid>,
171
172 #[belongs_to(key = user_id, references = id)]
173 user: toasty::Deferred<Option<User>>,
174
175 bio: String,
176 }
177
178 let mut db = test.setup_db(models!(User, Profile)).await;
179
180 let u1 = User::create()
182 .profile(Profile::create().bio("an apple a day"))
183 .exec(&mut db)
184 .await?;
185
186 let mut p1 = u1.profile().exec(&mut db).await?;
187 assert_eq!(p1.bio, "an apple a day");
188
189 let u2 = User::create()
191 .profile(Profile::create().bio("I plant trees"))
192 .exec(&mut db)
193 .await?;
194
195 let p2 = u2.profile().exec(&mut db).await?;
196 assert_eq!(p2.bio, "I plant trees");
197
198 p1.update().user(&u2).exec(&mut db).await?;
200
201 assert_err!(User::get_by_id(&mut db, &u1.id).await);
204 let p2_reloaded = Profile::get_by_id(&mut db, &p2.id).await?;
206 assert_none!(p2_reloaded.user_id);
207
208 Ok(())
255}
256
257#[driver_test]
258pub async fn crud_has_one_optional_belongs_to_required(test: &mut Test) -> Result<()> {
259 #[derive(Debug, toasty::Model)]
260 struct User {
261 #[key]
262 #[auto]
263 id: uuid::Uuid,
264
265 #[has_one]
266 profile: toasty::Deferred<Option<Profile>>,
267 }
268
269 #[derive(Debug, toasty::Model)]
270 struct Profile {
271 #[key]
272 #[auto]
273 id: uuid::Uuid,
274
275 #[unique]
276 user_id: uuid::Uuid,
277
278 #[belongs_to(key = user_id, references = id)]
279 user: toasty::Deferred<User>,
280
281 bio: String,
282 }
283
284 let mut db = test.setup_db(models!(User, Profile)).await;
285
286 let user = User::create()
288 .profile(Profile::create().bio("an apple a day"))
289 .exec(&mut db)
290 .await?;
291
292 let profile = user.profile().exec(&mut db).await?.unwrap();
293 assert_eq!(profile.bio, "an apple a day");
294
295 assert_eq!(user.id, profile.user().exec(&mut db).await?.id);
297
298 user.delete().exec(&mut db).await?;
300 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
301 Ok(())
302}
303
304#[driver_test(scenario(crate::scenarios::has_one_optional_belongs_to::id_uuid))]
305pub async fn set_has_one_by_value_in_update_query(test: &mut Test) -> Result<()> {
306 let mut db = setup(test).await;
307
308 let user = User::create().name("Jane Doe").exec(&mut db).await?;
309 let profile = Profile::create().bio("a person").exec(&mut db).await?;
310
311 User::filter_by_id(user.id)
312 .update()
313 .profile(&profile)
314 .exec(&mut db)
315 .await?;
316
317 let profile_reload = user.profile().exec(&mut db).await?.unwrap();
318 assert_eq!(profile_reload.id, profile.id);
319
320 assert_eq!(profile_reload.user_id.as_ref().unwrap(), &user.id);
321 Ok(())
322}
323
324#[driver_test]
325pub async fn unset_has_one_in_batch_update(test: &mut Test) -> Result<()> {
326 #[derive(Debug, toasty::Model)]
327 struct User {
328 #[key]
329 #[auto]
330 id: uuid::Uuid,
331
332 #[index]
333 name: String,
334
335 #[has_one]
336 profile: toasty::Deferred<Option<Profile>>,
337 }
338
339 #[derive(Debug, toasty::Model)]
340 struct Profile {
341 #[key]
342 #[auto]
343 id: uuid::Uuid,
344
345 #[unique]
346 user_id: uuid::Uuid,
347
348 #[belongs_to(key = user_id, references = id)]
349 user: toasty::Deferred<User>,
350 }
351
352 let mut db = test.setup_db(models!(User, Profile)).await;
353
354 let u1 = User::create()
356 .name("alice")
357 .profile(Profile::create())
358 .exec(&mut db)
359 .await?;
360 let p1 = u1.profile().exec(&mut db).await?.unwrap();
361
362 let u2 = User::create()
363 .name("alice")
364 .profile(Profile::create())
365 .exec(&mut db)
366 .await?;
367 let p2 = u2.profile().exec(&mut db).await?.unwrap();
368
369 let u3 = User::create()
371 .name("bob")
372 .profile(Profile::create())
373 .exec(&mut db)
374 .await?;
375
376 User::filter_by_name("alice")
378 .update()
379 .profile(None)
380 .exec(&mut db)
381 .await?;
382
383 assert_err!(Profile::get_by_id(&mut db, &p1.id).await);
385 assert_err!(Profile::get_by_id(&mut db, &p2.id).await);
386
387 let p3 = u3.profile().exec(&mut db).await?.unwrap();
389 assert_eq!(p3.user_id, u3.id);
390
391 Ok(())
392}
393
394#[driver_test]
395pub async fn unset_has_one_with_required_pair_in_pk_query_update(test: &mut Test) -> Result<()> {
396 #[derive(Debug, toasty::Model)]
397 struct User {
398 #[key]
399 #[auto]
400 id: uuid::Uuid,
401
402 #[has_one]
403 profile: toasty::Deferred<Option<Profile>>,
404 }
405
406 #[derive(Debug, toasty::Model)]
407 struct Profile {
408 #[key]
409 #[auto]
410 id: uuid::Uuid,
411
412 #[unique]
413 user_id: uuid::Uuid,
414
415 #[belongs_to(key = user_id, references = id)]
416 user: toasty::Deferred<User>,
417 }
418
419 let mut db = test.setup_db(models!(User, Profile)).await;
420
421 let user = User::create()
422 .profile(Profile::create())
423 .exec(&mut db)
424 .await?;
425 let profile = user.profile().exec(&mut db).await?.unwrap();
426
427 assert_eq!(user.id, profile.user_id);
428
429 User::filter_by_id(user.id)
430 .update()
431 .profile(None)
432 .exec(&mut db)
433 .await?;
434
435 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
437 Ok(())
438}
439
440#[driver_test]
441pub async fn unset_has_one_with_required_pair_in_non_pk_query_update(
442 test: &mut Test,
443) -> Result<()> {
444 #[derive(Debug, toasty::Model)]
445 struct User {
446 #[key]
447 #[auto]
448 id: uuid::Uuid,
449
450 #[unique]
451 email: String,
452
453 #[has_one]
454 profile: toasty::Deferred<Option<Profile>>,
455 }
456
457 #[derive(Debug, toasty::Model)]
458 struct Profile {
459 #[key]
460 #[auto]
461 id: uuid::Uuid,
462
463 #[unique]
464 user_id: uuid::Uuid,
465
466 #[belongs_to(key = user_id, references = id)]
467 user: toasty::Deferred<User>,
468 }
469
470 let mut db = test.setup_db(models!(User, Profile)).await;
471
472 let user = User::create()
473 .email("foo@example.com")
474 .profile(Profile::create())
475 .exec(&mut db)
476 .await?;
477 let profile = user.profile().exec(&mut db).await?.unwrap();
478 assert_eq!(profile.user_id, user.id);
479
480 User::filter_by_email(&user.email)
481 .update()
482 .profile(None)
483 .exec(&mut db)
484 .await?;
485
486 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
488 Ok(())
489}
490
491#[driver_test(id(ID))]
492pub async fn associate_has_one_by_val_on_insert(test: &mut Test) -> Result<()> {
493 #[derive(Debug, toasty::Model)]
494 struct User {
495 #[key]
496 #[auto]
497 id: ID,
498
499 #[has_one]
500 profile: toasty::Deferred<Profile>,
501 }
502
503 #[derive(Debug, toasty::Model)]
504 struct Profile {
505 #[key]
506 #[auto]
507 id: ID,
508
509 #[unique]
510 user_id: Option<ID>,
511
512 #[belongs_to(key = user_id, references = id)]
513 user: toasty::Deferred<Option<User>>,
514
515 bio: String,
516 }
517
518 let mut db = test.setup_db(models!(User, Profile)).await;
519
520 let profile = Profile::create().bio("hello world").exec(&mut db).await?;
522
523 let u1 = User::create().profile(&profile).exec(&mut db).await?;
525
526 let profile_reloaded = u1.profile().exec(&mut db).await?;
527 assert_eq!(profile.id, profile_reloaded.id);
528 assert_eq!(Some(&u1.id), profile_reloaded.user_id.as_ref());
529 assert_eq!(profile.bio, profile_reloaded.bio);
530 Ok(())
531}
532
533#[driver_test(scenario(crate::scenarios::has_one_optional_belongs_to::id_uuid))]
534pub async fn associate_has_one_by_val_on_update_query_with_filter_1(test: &mut Test) -> Result<()> {
535 let mut db = setup(test).await;
536
537 let u1 = User::create().name("user 1").exec(&mut db).await?;
538 let p1 = Profile::create().bio("hello world").exec(&mut db).await?;
539
540 User::filter_by_id(u1.id)
542 .update()
543 .profile(&p1)
544 .exec(&mut db)
545 .await?;
546
547 let u1_reloaded = User::get_by_id(&mut db, &u1.id).await?;
548 let p1_reloaded = u1_reloaded.profile().exec(&mut db).await?.unwrap();
549 assert_eq!(p1.id, p1_reloaded.id);
550 assert_eq!(p1.bio, p1_reloaded.bio);
551 assert_eq!(p1_reloaded.user_id.as_ref(), Some(&u1.id));
552
553 User::filter_by_id(u1.id)
555 .update()
556 .profile(None)
557 .exec(&mut db)
558 .await?;
559
560 User::filter_by_id(u1.id)
561 .filter(User::fields().name().eq("anon"))
562 .update()
563 .profile(&p1)
564 .exec(&mut db)
565 .await?;
566
567 let p1_reloaded = Profile::get_by_id(&mut db, &p1.id).await?;
569 assert!(p1_reloaded.user_id.is_none());
570
571 Ok(())
572}
573
574#[driver_test(scenario(crate::scenarios::has_one_optional_belongs_to::id_uuid))]
575pub async fn associate_has_one_by_val_on_update_query_with_filter_2(test: &mut Test) -> Result<()> {
576 let mut db = setup(test).await;
577
578 let u1 = toasty::create!(User {
579 name: "User 1",
580 profile: {
581 bio: "hello world"
582 }
583 })
584 .exec(&mut db)
585 .await?;
586
587 let u2 = toasty::create!(User { name: "User 2" })
588 .exec(&mut db)
589 .await?;
590
591 let p1 = u1.profile().exec(&mut db).await?.unwrap();
592 assert_eq!(p1.user_id.as_ref(), Some(&u1.id));
593
594 User::filter_by_id(u2.id)
595 .filter(User::fields().name().eq("anon"))
596 .update()
597 .profile(&p1)
598 .exec(&mut db)
599 .await?;
600
601 let p1_reloaded = Profile::get_by_id(&mut db, &p1.id).await?;
603 assert_eq!(p1_reloaded.user_id.as_ref(), Some(&u1.id));
604
605 Ok(())
606}