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(id(ID))]
94#[should_panic]
95pub async fn crud_has_one_required_belongs_to_optional(test: &mut Test) -> Result<()> {
96 #[derive(Debug, toasty::Model)]
97 struct User {
98 #[key]
99 #[auto]
100 id: ID,
101
102 #[has_one]
103 profile: toasty::Deferred<Profile>,
104 }
105
106 #[derive(Debug, toasty::Model)]
107 struct Profile {
108 #[key]
109 #[auto]
110 id: ID,
111
112 #[unique]
113 user_id: Option<ID>,
114
115 #[belongs_to(key = user_id, references = id)]
116 user: toasty::Deferred<Option<User>>,
117
118 bio: String,
119 }
120
121 let mut db = test.setup_db(models!(User, Profile)).await;
122
123 let user = User::create()
125 .profile(Profile::create().bio("an apple a day"))
126 .exec(&mut db)
127 .await?;
128
129 let profile = user.profile().exec(&mut db).await?;
130 assert_eq!(profile.bio, "an apple a day");
131
132 assert_eq!(user.id, profile.user().exec(&mut db).await?.unwrap().id);
134
135 user.delete().exec(&mut db).await?;
137 let profile_reloaded = Profile::get_by_id(&mut db, &profile.id).await?;
138 assert_none!(profile_reloaded.user_id);
139
140 assert_err!(User::create().exec(&mut db).await);
142 Ok(())
143}
144
145#[driver_test(id(ID))]
146pub async fn update_belongs_to_with_required_has_one_pair(test: &mut Test) -> Result<()> {
147 #[derive(Debug, toasty::Model)]
148 struct User {
149 #[key]
150 #[auto]
151 id: ID,
152
153 #[has_one]
154 profile: toasty::Deferred<Profile>,
155 }
156
157 #[derive(Debug, toasty::Model)]
158 struct Profile {
159 #[key]
160 #[auto]
161 id: ID,
162
163 #[unique]
164 user_id: Option<ID>,
165
166 #[belongs_to(key = user_id, references = id)]
167 user: toasty::Deferred<Option<User>>,
168
169 bio: String,
170 }
171
172 let mut db = test.setup_db(models!(User, Profile)).await;
173
174 let u1 = User::create()
176 .profile(Profile::create().bio("an apple a day"))
177 .exec(&mut db)
178 .await?;
179
180 let mut p1 = u1.profile().exec(&mut db).await?;
181 assert_eq!(p1.bio, "an apple a day");
182
183 let u2 = User::create()
185 .profile(Profile::create().bio("I plant trees"))
186 .exec(&mut db)
187 .await?;
188
189 let p2 = u2.profile().exec(&mut db).await?;
190 assert_eq!(p2.bio, "I plant trees");
191
192 p1.update().user(&u2).exec(&mut db).await?;
194
195 assert_err!(User::get_by_id(&mut db, &u1.id).await);
198 let p2_reloaded = Profile::get_by_id(&mut db, &p2.id).await?;
200 assert_none!(p2_reloaded.user_id);
201
202 Ok(())
249}
250
251#[driver_test(id(ID))]
252pub async fn crud_has_one_optional_belongs_to_required(test: &mut Test) -> Result<()> {
253 #[derive(Debug, toasty::Model)]
254 struct User {
255 #[key]
256 #[auto]
257 id: ID,
258
259 #[has_one]
260 profile: toasty::Deferred<Option<Profile>>,
261 }
262
263 #[derive(Debug, toasty::Model)]
264 struct Profile {
265 #[key]
266 #[auto]
267 id: ID,
268
269 #[unique]
270 user_id: ID,
271
272 #[belongs_to(key = user_id, references = id)]
273 user: toasty::Deferred<User>,
274
275 bio: String,
276 }
277
278 let mut db = test.setup_db(models!(User, Profile)).await;
279
280 let user = User::create()
282 .profile(Profile::create().bio("an apple a day"))
283 .exec(&mut db)
284 .await?;
285
286 let profile = user.profile().exec(&mut db).await?.unwrap();
287 assert_eq!(profile.bio, "an apple a day");
288
289 assert_eq!(user.id, profile.user().exec(&mut db).await?.id);
291
292 user.delete().exec(&mut db).await?;
294 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
295 Ok(())
296}
297
298#[driver_test(id(ID), scenario(crate::scenarios::has_one_optional_belongs_to))]
299pub async fn set_has_one_by_value_in_update_query(test: &mut Test) -> Result<()> {
300 let mut db = setup(test).await;
301
302 let user = User::create().name("Jane Doe").exec(&mut db).await?;
303 let profile = Profile::create().bio("a person").exec(&mut db).await?;
304
305 User::filter_by_id(user.id)
306 .update()
307 .profile(&profile)
308 .exec(&mut db)
309 .await?;
310
311 let profile_reload = user.profile().exec(&mut db).await?.unwrap();
312 assert_eq!(profile_reload.id, profile.id);
313
314 assert_eq!(profile_reload.user_id.as_ref().unwrap(), &user.id);
315 Ok(())
316}
317
318#[driver_test(id(ID))]
319pub async fn unset_has_one_in_batch_update(test: &mut Test) -> Result<()> {
320 #[derive(Debug, toasty::Model)]
321 struct User {
322 #[key]
323 #[auto]
324 id: ID,
325
326 #[index]
327 name: String,
328
329 #[has_one]
330 profile: toasty::Deferred<Option<Profile>>,
331 }
332
333 #[derive(Debug, toasty::Model)]
334 struct Profile {
335 #[key]
336 #[auto]
337 id: ID,
338
339 #[unique]
340 user_id: ID,
341
342 #[belongs_to(key = user_id, references = id)]
343 user: toasty::Deferred<User>,
344 }
345
346 let mut db = test.setup_db(models!(User, Profile)).await;
347
348 let u1 = User::create()
350 .name("alice")
351 .profile(Profile::create())
352 .exec(&mut db)
353 .await?;
354 let p1 = u1.profile().exec(&mut db).await?.unwrap();
355
356 let u2 = User::create()
357 .name("alice")
358 .profile(Profile::create())
359 .exec(&mut db)
360 .await?;
361 let p2 = u2.profile().exec(&mut db).await?.unwrap();
362
363 let u3 = User::create()
365 .name("bob")
366 .profile(Profile::create())
367 .exec(&mut db)
368 .await?;
369
370 User::filter_by_name("alice")
372 .update()
373 .profile(None)
374 .exec(&mut db)
375 .await?;
376
377 assert_err!(Profile::get_by_id(&mut db, &p1.id).await);
379 assert_err!(Profile::get_by_id(&mut db, &p2.id).await);
380
381 let p3 = u3.profile().exec(&mut db).await?.unwrap();
383 assert_eq!(p3.user_id, u3.id);
384
385 Ok(())
386}
387
388#[driver_test(id(ID))]
389pub async fn unset_has_one_with_required_pair_in_pk_query_update(test: &mut Test) -> Result<()> {
390 #[derive(Debug, toasty::Model)]
391 struct User {
392 #[key]
393 #[auto]
394 id: ID,
395
396 #[has_one]
397 profile: toasty::Deferred<Option<Profile>>,
398 }
399
400 #[derive(Debug, toasty::Model)]
401 struct Profile {
402 #[key]
403 #[auto]
404 id: ID,
405
406 #[unique]
407 user_id: ID,
408
409 #[belongs_to(key = user_id, references = id)]
410 user: toasty::Deferred<User>,
411 }
412
413 let mut db = test.setup_db(models!(User, Profile)).await;
414
415 let user = User::create()
416 .profile(Profile::create())
417 .exec(&mut db)
418 .await?;
419 let profile = user.profile().exec(&mut db).await?.unwrap();
420
421 assert_eq!(user.id, profile.user_id);
422
423 User::filter_by_id(user.id)
424 .update()
425 .profile(None)
426 .exec(&mut db)
427 .await?;
428
429 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
431 Ok(())
432}
433
434#[driver_test(id(ID))]
435pub async fn unset_has_one_with_required_pair_in_non_pk_query_update(
436 test: &mut Test,
437) -> Result<()> {
438 #[derive(Debug, toasty::Model)]
439 struct User {
440 #[key]
441 #[auto]
442 id: ID,
443
444 #[unique]
445 email: String,
446
447 #[has_one]
448 profile: toasty::Deferred<Option<Profile>>,
449 }
450
451 #[derive(Debug, toasty::Model)]
452 struct Profile {
453 #[key]
454 #[auto]
455 id: ID,
456
457 #[unique]
458 user_id: ID,
459
460 #[belongs_to(key = user_id, references = id)]
461 user: toasty::Deferred<User>,
462 }
463
464 let mut db = test.setup_db(models!(User, Profile)).await;
465
466 let user = User::create()
467 .email("foo@example.com")
468 .profile(Profile::create())
469 .exec(&mut db)
470 .await?;
471 let profile = user.profile().exec(&mut db).await?.unwrap();
472 assert_eq!(profile.user_id, user.id);
473
474 User::filter_by_email(&user.email)
475 .update()
476 .profile(None)
477 .exec(&mut db)
478 .await?;
479
480 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
482 Ok(())
483}
484
485#[driver_test(id(ID))]
486pub async fn associate_has_one_by_val_on_insert(test: &mut Test) -> Result<()> {
487 #[derive(Debug, toasty::Model)]
488 struct User {
489 #[key]
490 #[auto]
491 id: ID,
492
493 #[has_one]
494 profile: toasty::Deferred<Profile>,
495 }
496
497 #[derive(Debug, toasty::Model)]
498 struct Profile {
499 #[key]
500 #[auto]
501 id: ID,
502
503 #[unique]
504 user_id: Option<ID>,
505
506 #[belongs_to(key = user_id, references = id)]
507 user: toasty::Deferred<Option<User>>,
508
509 bio: String,
510 }
511
512 let mut db = test.setup_db(models!(User, Profile)).await;
513
514 let profile = Profile::create().bio("hello world").exec(&mut db).await?;
516
517 let u1 = User::create().profile(&profile).exec(&mut db).await?;
519
520 let profile_reloaded = u1.profile().exec(&mut db).await?;
521 assert_eq!(profile.id, profile_reloaded.id);
522 assert_eq!(Some(&u1.id), profile_reloaded.user_id.as_ref());
523 assert_eq!(profile.bio, profile_reloaded.bio);
524 Ok(())
525}
526
527#[driver_test(id(ID), scenario(crate::scenarios::has_one_optional_belongs_to))]
528pub async fn associate_has_one_by_val_on_update_query_with_filter_1(test: &mut Test) -> Result<()> {
529 let mut db = setup(test).await;
530
531 let u1 = User::create().name("user 1").exec(&mut db).await?;
532 let p1 = Profile::create().bio("hello world").exec(&mut db).await?;
533
534 User::filter_by_id(u1.id)
536 .update()
537 .profile(&p1)
538 .exec(&mut db)
539 .await?;
540
541 let u1_reloaded = User::get_by_id(&mut db, &u1.id).await?;
542 let p1_reloaded = u1_reloaded.profile().exec(&mut db).await?.unwrap();
543 assert_eq!(p1.id, p1_reloaded.id);
544 assert_eq!(p1.bio, p1_reloaded.bio);
545 assert_eq!(p1_reloaded.user_id.as_ref(), Some(&u1.id));
546
547 User::filter_by_id(u1.id)
549 .update()
550 .profile(None)
551 .exec(&mut db)
552 .await?;
553
554 User::filter_by_id(u1.id)
555 .filter(User::fields().name().eq("anon"))
556 .update()
557 .profile(&p1)
558 .exec(&mut db)
559 .await?;
560
561 let p1_reloaded = Profile::get_by_id(&mut db, &p1.id).await?;
563 assert!(p1_reloaded.user_id.is_none());
564
565 Ok(())
566}
567
568#[driver_test(id(ID), scenario(crate::scenarios::has_one_optional_belongs_to))]
569pub async fn associate_has_one_by_val_on_update_query_with_filter_2(test: &mut Test) -> Result<()> {
570 let mut db = setup(test).await;
571
572 let u1 = toasty::create!(User {
573 name: "User 1",
574 profile: {
575 bio: "hello world"
576 }
577 })
578 .exec(&mut db)
579 .await?;
580
581 let u2 = toasty::create!(User { name: "User 2" })
582 .exec(&mut db)
583 .await?;
584
585 let p1 = u1.profile().exec(&mut db).await?.unwrap();
586 assert_eq!(p1.user_id.as_ref(), Some(&u1.id));
587
588 User::filter_by_id(u2.id)
589 .filter(User::fields().name().eq("anon"))
590 .update()
591 .profile(&p1)
592 .exec(&mut db)
593 .await?;
594
595 let p1_reloaded = Profile::get_by_id(&mut db, &p1.id).await?;
597 assert_eq!(p1_reloaded.user_id.as_ref(), Some(&u1.id));
598
599 Ok(())
600}