toasty_driver_integration_suite/tests/
has_one_crud_basic.rs1use crate::prelude::*;
2
3#[driver_test(id(ID))]
4pub async fn crud_has_one_bi_direction_optional(test: &mut Test) -> Result<()> {
5 #[derive(Debug, toasty::Model)]
6 struct User {
7 #[key]
8 #[auto]
9 id: ID,
10
11 name: String,
12
13 #[has_one]
14 profile: toasty::HasOne<Option<Profile>>,
15 }
16
17 #[derive(Debug, toasty::Model)]
18 struct Profile {
19 #[key]
20 #[auto]
21 id: ID,
22
23 #[unique]
24 user_id: Option<ID>,
25
26 #[belongs_to(key = user_id, references = id)]
27 user: toasty::BelongsTo<Option<User>>,
28
29 bio: String,
30 }
31
32 let mut db = test.setup_db(models!(User, Profile)).await;
33
34 let user = User::create().name("Jane Doe").exec(&mut db).await?;
36
37 assert_none!(user.profile().get(&mut db).await?);
39
40 let profile = user
42 .profile()
43 .create()
44 .bio("a person")
45 .exec(&mut db)
46 .await?;
47
48 let profile_reload = user.profile().get(&mut db).await?.unwrap();
50 assert_eq!(profile.id, profile_reload.id);
51
52 let user_reload = profile.user().get(&mut db).await?.unwrap();
54 assert_eq!(user.id, user_reload.id);
55
56 let mut user = User::create()
58 .name("Tim Apple")
59 .profile(Profile::create().bio("an apple a day"))
60 .exec(&mut db)
61 .await?;
62
63 let profile = user.profile().get(&mut db).await?.unwrap();
64 assert_eq!(profile.bio, "an apple a day");
65
66 assert_eq!(user.id, profile.user().get(&mut db).await?.unwrap().id);
68
69 user.update()
71 .profile(Profile::create().bio("keeps the doctor away"))
72 .exec(&mut db)
73 .await?;
74
75 let profile = user.profile().get(&mut db).await?.unwrap();
77 assert_eq!(profile.bio, "keeps the doctor away");
78 assert_eq!(user.id, profile.user().get(&mut db).await?.unwrap().id);
79
80 user.update().profile(None).exec(&mut db).await?;
82
83 assert!(user.profile().get(&mut db).await?.is_none());
85
86 let profile_reloaded = Profile::filter_by_id(profile.id).get(&mut db).await?;
87 assert_none!(profile_reloaded.user_id);
88
89 user.update()
90 .profile(&profile_reloaded)
91 .exec(&mut db)
92 .await?;
93
94 let profile_reloaded = Profile::get_by_id(&mut db, &profile.id).await?;
95 assert_eq!(&user.id, profile_reloaded.user_id.as_ref().unwrap());
96
97 profile_reloaded.delete().exec(&mut db).await?;
99
100 let mut user_reloaded = User::get_by_id(&mut db, &user.id).await?;
101 assert_none!(user_reloaded.profile().get(&mut db).await?);
102
103 user_reloaded
105 .update()
106 .profile(Profile::create().bio("hello"))
107 .exec(&mut db)
108 .await?;
109
110 let profile_id = user_reloaded.profile().get(&mut db).await?.unwrap().id;
111
112 user_reloaded.delete().exec(&mut db).await?;
114
115 let profile_reloaded = Profile::get_by_id(&mut db, &profile_id).await?;
116 assert_none!(profile_reloaded.user_id);
117 Ok(())
118}
119
120#[driver_test(id(ID))]
121#[should_panic]
122pub async fn crud_has_one_required_belongs_to_optional(test: &mut Test) -> Result<()> {
123 #[derive(Debug, toasty::Model)]
124 struct User {
125 #[key]
126 #[auto]
127 id: ID,
128
129 #[has_one]
130 profile: toasty::HasOne<Profile>,
131 }
132
133 #[derive(Debug, toasty::Model)]
134 struct Profile {
135 #[key]
136 #[auto]
137 id: ID,
138
139 #[unique]
140 user_id: Option<ID>,
141
142 #[belongs_to(key = user_id, references = id)]
143 user: toasty::BelongsTo<Option<User>>,
144
145 bio: String,
146 }
147
148 let mut db = test.setup_db(models!(User, Profile)).await;
149
150 let user = User::create()
152 .profile(Profile::create().bio("an apple a day"))
153 .exec(&mut db)
154 .await?;
155
156 let profile = user.profile().get(&mut db).await?;
157 assert_eq!(profile.bio, "an apple a day");
158
159 assert_eq!(user.id, profile.user().get(&mut db).await?.unwrap().id);
161
162 user.delete().exec(&mut db).await?;
164 let profile_reloaded = Profile::get_by_id(&mut db, &profile.id).await?;
165 assert_none!(profile_reloaded.user_id);
166
167 assert_err!(User::create().exec(&mut db).await);
169 Ok(())
170}
171
172#[driver_test(id(ID))]
173pub async fn update_belongs_to_with_required_has_one_pair(test: &mut Test) -> Result<()> {
174 #[derive(Debug, toasty::Model)]
175 struct User {
176 #[key]
177 #[auto]
178 id: ID,
179
180 #[has_one]
181 profile: toasty::HasOne<Profile>,
182 }
183
184 #[derive(Debug, toasty::Model)]
185 struct Profile {
186 #[key]
187 #[auto]
188 id: ID,
189
190 #[unique]
191 user_id: Option<ID>,
192
193 #[belongs_to(key = user_id, references = id)]
194 user: toasty::BelongsTo<Option<User>>,
195
196 bio: String,
197 }
198
199 let mut db = test.setup_db(models!(User, Profile)).await;
200
201 let u1 = User::create()
203 .profile(Profile::create().bio("an apple a day"))
204 .exec(&mut db)
205 .await?;
206
207 let mut p1 = u1.profile().get(&mut db).await?;
208 assert_eq!(p1.bio, "an apple a day");
209
210 let u2 = User::create()
212 .profile(Profile::create().bio("I plant trees"))
213 .exec(&mut db)
214 .await?;
215
216 let p2 = u2.profile().get(&mut db).await?;
217 assert_eq!(p2.bio, "I plant trees");
218
219 p1.update().user(&u2).exec(&mut db).await?;
221
222 assert_err!(User::get_by_id(&mut db, &u1.id).await);
225 let p2_reloaded = Profile::get_by_id(&mut db, &p2.id).await?;
227 assert_none!(p2_reloaded.user_id);
228
229 Ok(())
276}
277
278#[driver_test(id(ID))]
279pub async fn crud_has_one_optional_belongs_to_required(test: &mut Test) -> Result<()> {
280 #[derive(Debug, toasty::Model)]
281 struct User {
282 #[key]
283 #[auto]
284 id: ID,
285
286 #[has_one]
287 profile: toasty::HasOne<Option<Profile>>,
288 }
289
290 #[derive(Debug, toasty::Model)]
291 struct Profile {
292 #[key]
293 #[auto]
294 id: ID,
295
296 #[unique]
297 user_id: ID,
298
299 #[belongs_to(key = user_id, references = id)]
300 user: toasty::BelongsTo<User>,
301
302 bio: String,
303 }
304
305 let mut db = test.setup_db(models!(User, Profile)).await;
306
307 let user = User::create()
309 .profile(Profile::create().bio("an apple a day"))
310 .exec(&mut db)
311 .await?;
312
313 let profile = user.profile().get(&mut db).await?.unwrap();
314 assert_eq!(profile.bio, "an apple a day");
315
316 assert_eq!(user.id, profile.user().get(&mut db).await?.id);
318
319 user.delete().exec(&mut db).await?;
321 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
322 Ok(())
323}
324
325#[driver_test(id(ID))]
326pub async fn set_has_one_by_value_in_update_query(test: &mut Test) -> Result<()> {
327 #[derive(Debug, toasty::Model)]
328 struct User {
329 #[key]
330 #[auto]
331 id: ID,
332
333 #[has_one]
334 profile: toasty::HasOne<Option<Profile>>,
335 }
336
337 #[derive(Debug, toasty::Model)]
338 struct Profile {
339 #[key]
340 #[auto]
341 id: ID,
342
343 #[unique]
344 user_id: Option<ID>,
345
346 #[belongs_to(key = user_id, references = id)]
347 user: toasty::BelongsTo<Option<User>>,
348 }
349
350 let mut db = test.setup_db(models!(User, Profile)).await;
351
352 let user = User::create().exec(&mut db).await?;
353 let profile = Profile::create().exec(&mut db).await?;
354
355 User::filter_by_id(user.id)
356 .update()
357 .profile(&profile)
358 .exec(&mut db)
359 .await?;
360
361 let profile_reload = user.profile().get(&mut db).await?.unwrap();
362 assert_eq!(profile_reload.id, profile.id);
363
364 assert_eq!(profile_reload.user_id.as_ref().unwrap(), &user.id);
365 Ok(())
366}
367
368#[driver_test(id(ID))]
369pub async fn unset_has_one_in_batch_update(test: &mut Test) -> Result<()> {
370 #[derive(Debug, toasty::Model)]
371 struct User {
372 #[key]
373 #[auto]
374 id: ID,
375
376 #[index]
377 name: String,
378
379 #[has_one]
380 profile: toasty::HasOne<Option<Profile>>,
381 }
382
383 #[derive(Debug, toasty::Model)]
384 struct Profile {
385 #[key]
386 #[auto]
387 id: ID,
388
389 #[unique]
390 user_id: ID,
391
392 #[belongs_to(key = user_id, references = id)]
393 user: toasty::BelongsTo<User>,
394 }
395
396 let mut db = test.setup_db(models!(User, Profile)).await;
397
398 let u1 = User::create()
400 .name("alice")
401 .profile(Profile::create())
402 .exec(&mut db)
403 .await?;
404 let p1 = u1.profile().get(&mut db).await?.unwrap();
405
406 let u2 = User::create()
407 .name("alice")
408 .profile(Profile::create())
409 .exec(&mut db)
410 .await?;
411 let p2 = u2.profile().get(&mut db).await?.unwrap();
412
413 let u3 = User::create()
415 .name("bob")
416 .profile(Profile::create())
417 .exec(&mut db)
418 .await?;
419
420 User::filter_by_name("alice")
422 .update()
423 .profile(None)
424 .exec(&mut db)
425 .await?;
426
427 assert_err!(Profile::get_by_id(&mut db, &p1.id).await);
429 assert_err!(Profile::get_by_id(&mut db, &p2.id).await);
430
431 let p3 = u3.profile().get(&mut db).await?.unwrap();
433 assert_eq!(p3.user_id, u3.id);
434
435 Ok(())
436}
437
438#[driver_test(id(ID))]
439pub async fn unset_has_one_with_required_pair_in_pk_query_update(test: &mut Test) -> Result<()> {
440 #[derive(Debug, toasty::Model)]
441 struct User {
442 #[key]
443 #[auto]
444 id: ID,
445
446 #[has_one]
447 profile: toasty::HasOne<Option<Profile>>,
448 }
449
450 #[derive(Debug, toasty::Model)]
451 struct Profile {
452 #[key]
453 #[auto]
454 id: ID,
455
456 #[unique]
457 user_id: ID,
458
459 #[belongs_to(key = user_id, references = id)]
460 user: toasty::BelongsTo<User>,
461 }
462
463 let mut db = test.setup_db(models!(User, Profile)).await;
464
465 let user = User::create()
466 .profile(Profile::create())
467 .exec(&mut db)
468 .await?;
469 let profile = user.profile().get(&mut db).await?.unwrap();
470
471 assert_eq!(user.id, profile.user_id);
472
473 User::filter_by_id(user.id)
474 .update()
475 .profile(None)
476 .exec(&mut db)
477 .await?;
478
479 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
481 Ok(())
482}
483
484#[driver_test(id(ID))]
485pub async fn unset_has_one_with_required_pair_in_non_pk_query_update(
486 test: &mut Test,
487) -> Result<()> {
488 #[derive(Debug, toasty::Model)]
489 struct User {
490 #[key]
491 #[auto]
492 id: ID,
493
494 #[unique]
495 email: String,
496
497 #[has_one]
498 profile: toasty::HasOne<Option<Profile>>,
499 }
500
501 #[derive(Debug, toasty::Model)]
502 struct Profile {
503 #[key]
504 #[auto]
505 id: ID,
506
507 #[unique]
508 user_id: ID,
509
510 #[belongs_to(key = user_id, references = id)]
511 user: toasty::BelongsTo<User>,
512 }
513
514 let mut db = test.setup_db(models!(User, Profile)).await;
515
516 let user = User::create()
517 .email("foo@example.com")
518 .profile(Profile::create())
519 .exec(&mut db)
520 .await?;
521 let profile = user.profile().get(&mut db).await?.unwrap();
522 assert_eq!(profile.user_id, user.id);
523
524 User::filter_by_email(&user.email)
525 .update()
526 .profile(None)
527 .exec(&mut db)
528 .await?;
529
530 assert_err!(Profile::get_by_id(&mut db, &profile.id).await);
532 Ok(())
533}
534
535#[driver_test(id(ID))]
536pub async fn associate_has_one_by_val_on_insert(test: &mut Test) -> Result<()> {
537 #[derive(Debug, toasty::Model)]
538 struct User {
539 #[key]
540 #[auto]
541 id: ID,
542
543 #[has_one]
544 profile: toasty::HasOne<Profile>,
545 }
546
547 #[derive(Debug, toasty::Model)]
548 struct Profile {
549 #[key]
550 #[auto]
551 id: ID,
552
553 #[unique]
554 user_id: Option<ID>,
555
556 #[belongs_to(key = user_id, references = id)]
557 user: toasty::BelongsTo<Option<User>>,
558
559 bio: String,
560 }
561
562 let mut db = test.setup_db(models!(User, Profile)).await;
563
564 let profile = Profile::create().bio("hello world").exec(&mut db).await?;
566
567 let u1 = User::create().profile(&profile).exec(&mut db).await?;
569
570 let profile_reloaded = u1.profile().get(&mut db).await?;
571 assert_eq!(profile.id, profile_reloaded.id);
572 assert_eq!(Some(&u1.id), profile_reloaded.user_id.as_ref());
573 assert_eq!(profile.bio, profile_reloaded.bio);
574 Ok(())
575}
576
577#[driver_test(id(ID))]
578#[ignore]
579pub async fn associate_has_one_by_val_on_update_query_with_filter(_test: &mut Test) {
580 }