Skip to main content

toasty_driver_integration_suite/tests/
relation_has_many_link_unlink.rs

1//! Test linking and unlinking has_many associations
2
3use crate::prelude::*;
4
5#[driver_test(id(ID), scenario(crate::scenarios::has_many_nullable_fk))]
6pub async fn remove_add_single_relation_option_belongs_to(test: &mut Test) -> Result<()> {
7    let mut db = setup(test).await;
8
9    // Create a user with some todos
10    let user = User::create()
11        .todos([Todo::create().title("todo")])
12        .todos([Todo::create().title("todo")])
13        .exec(&mut db)
14        .await?;
15
16    let todos: Vec<_> = user.todos().exec(&mut db).await?;
17    assert_eq!(2, todos.len());
18
19    // Remove a todo from the list.
20    user.todos().remove(&mut db, &todos[0]).await?;
21
22    let todos_reloaded: Vec<_> = user.todos().exec(&mut db).await?;
23    assert_eq!(1, todos_reloaded.len());
24    assert_eq!(todos[1].id, todos_reloaded[0].id);
25
26    // Can't find the TODO via a scoped query either
27    assert_err!(user.todos().get_by_id(&mut db, &todos[0].id).await);
28
29    // The todo is not deleted, but user is now None
30    let todo = Todo::get_by_id(&mut db, todos[0].id).await?;
31    assert_none!(todo.user_id);
32
33    // Create a second user w/ a TODO. We will ensure that unlinking *only*
34    // unlinks records currently associated with the base model.
35    let u2 = User::create()
36        .todos([Todo::create().title("todo")])
37        .exec(&mut db)
38        .await?;
39    let u2_todos = u2.todos().exec(&mut db).await?;
40
41    // Try unlinking u2's todo via user. This should fail
42    assert_err!(user.todos().remove(&mut db, &u2_todos[0]).await);
43
44    // Reload u2's todo
45    let u2_todo = Todo::get_by_id(&mut db, u2_todos[0].id).await?;
46    assert_eq!(*u2_todo.user_id.as_ref().unwrap(), u2.id);
47
48    // Link the TODO back up
49    user.todos().insert(&mut db, &todos[0]).await?;
50
51    // The TODO is in the association again
52    let todos_reloaded: Vec<_> = user.todos().exec(&mut db).await?;
53    assert!(todos_reloaded.iter().any(|t| t.id == todos[0].id));
54    assert_ok!(user.todos().get_by_id(&mut db, todos[0].id).await);
55    Ok(())
56}
57
58#[driver_test(id(ID), scenario(crate::scenarios::has_many_belongs_to))]
59pub async fn add_remove_single_relation_required_belongs_to(test: &mut Test) -> Result<()> {
60    let mut db = setup(test).await;
61
62    // Create a user with no todos
63    let user = User::create().name("User 1").exec(&mut db).await?;
64
65    // Create some TODOs
66    let t1 = user.todos().create().title("todo 1").exec(&mut db).await?;
67    let t2 = user.todos().create().title("todo 2").exec(&mut db).await?;
68    let t3 = user.todos().create().title("todo 3").exec(&mut db).await?;
69
70    let ids = vec![t1.id, t2.id, t3.id];
71
72    let todos_reloaded: Vec<_> = user.todos().exec(&mut db).await?;
73    assert_eq!(todos_reloaded.len(), 3);
74
75    for id in ids {
76        assert!(todos_reloaded.iter().any(|t| t.id == id));
77    }
78
79    // Unlinking a todo deletes it
80    user.todos().remove(&mut db, &todos_reloaded[0]).await?;
81
82    // The TODO no longer exists
83    assert_err!(Todo::get_by_id(&mut db, todos_reloaded[0].id).await);
84
85    // Rest of the todos exist
86    let todos_reloaded: Vec<_> = user.todos().exec(&mut db).await?;
87    assert_eq!(todos_reloaded.len(), 2);
88    Ok(())
89}
90
91#[driver_test(id(ID), scenario(crate::scenarios::has_many_belongs_to))]
92pub async fn reassign_relation_required_belongs_to(test: &mut Test) -> Result<()> {
93    let mut db = setup(test).await;
94
95    // Create users with no todos
96    let u1 = User::create().name("User 1").exec(&mut db).await?;
97    let u2 = User::create().name("User 2").exec(&mut db).await?;
98
99    // Create a TODO associated with user 1
100    let t1 = u1.todos().create().title("a todo").exec(&mut db).await?;
101
102    // Associate the todo with user 2
103    u2.todos().insert(&mut db, &t1).await?;
104
105    // The TODO is no longer associated with user 1
106    assert!(u1.todos().exec(&mut db).await?.is_empty());
107
108    // The TODO is assiated with user 2
109    let todos = u2.todos().exec(&mut db).await?;
110    assert_eq!(1, todos.len());
111    assert_eq!(t1.id, todos[0].id);
112    Ok(())
113}
114
115#[driver_test(id(ID), scenario(crate::scenarios::has_many_nullable_fk))]
116pub async fn add_remove_multiple_relation_option_belongs_to(test: &mut Test) -> Result<()> {
117    let mut db = setup(test).await;
118
119    // Create a user with no todos
120    let user = User::create().exec(&mut db).await?;
121
122    // Create some TODOs
123    let t1 = Todo::create().title("todo").exec(&mut db).await?;
124    let t2 = Todo::create().title("todo").exec(&mut db).await?;
125    let t3 = Todo::create().title("todo").exec(&mut db).await?;
126
127    let ids = vec![t1.id, t2.id, t3.id];
128
129    // Associate the todos with the user
130    user.todos().insert(&mut db, &t1).await?;
131    user.todos().insert(&mut db, &t2).await?;
132    user.todos().insert(&mut db, &t3).await?;
133
134    let todos_reloaded: Vec<_> = user.todos().exec(&mut db).await?;
135    assert_eq!(todos_reloaded.len(), 3);
136
137    for id in ids {
138        assert!(todos_reloaded.iter().any(|t| t.id == id));
139    }
140    Ok(())
141}