toasty_driver_integration_suite/tests/
has_many_scoped_query.rs

1//! Test scoped queries on has_many associations
2
3use crate::prelude::*;
4use std::collections::HashSet;
5
6#[driver_test(id(ID), matrix(single, composite), requires(or(single, not(id_u64))))]
7pub async fn scoped_query_eq(test: &mut Test) -> Result<()> {
8    #[derive(Debug, toasty::Model)]
9    struct User {
10        #[key]
11        #[auto]
12        id: ID,
13
14        #[has_many]
15        todos: toasty::HasMany<Todo>,
16    }
17
18    #[derive(Debug, toasty::Model)]
19    #[driver_test_cfg(composite, key(partition = user_id, local = id))]
20    struct Todo {
21        #[auto]
22        #[driver_test_cfg(single, key)]
23        id: ID,
24
25        #[driver_test_cfg(single, index)]
26        user_id: ID,
27
28        #[belongs_to(key = user_id, references = id)]
29        user: toasty::BelongsTo<User>,
30
31        title: String,
32
33        order: i64,
34    }
35
36    let mut db = test.setup_db(models!(User, Todo)).await;
37
38    // Create some users
39    let u1 = User::create().exec(&mut db).await?;
40    let u2 = User::create().exec(&mut db).await?;
41
42    let mut u1_todo_ids = vec![];
43
44    // Create some TODOs for user 1
45    for (order, title) in [
46        "write more tests",
47        "finish Toasty",
48        "remove all todo! items",
49        "retire",
50    ]
51    .into_iter()
52    .enumerate()
53    {
54        let todo = u1
55            .todos()
56            .create()
57            .title(title)
58            .order(order as i64)
59            .exec(&mut db)
60            .await?;
61        u1_todo_ids.push(todo.id);
62    }
63
64    // Create a TODO for user 2
65    let u2_todo = u2
66        .todos()
67        .create()
68        .title("attend world cup")
69        .order(0)
70        .exec(&mut db)
71        .await?;
72
73    // Query todos scoped by user 1
74    let todos = u1
75        .todos()
76        .query(Todo::fields().order().eq(0))
77        .exec(&mut db)
78        .await?;
79
80    assert_eq!(1, todos.len());
81    assert_eq!(todos[0].id, u1_todo_ids[0]);
82    assert_eq!(todos[0].order, 0);
83    assert_eq!(todos[0].title, "write more tests");
84
85    // Querying todos scoped by user 2
86    let todos = u2
87        .todos()
88        .query(Todo::fields().order().eq(0))
89        .exec(&mut db)
90        .await?;
91
92    assert_eq!(1, todos.len());
93    assert_eq!(todos[0].id, u2_todo.id);
94
95    // Add a second TODO w/ order 0
96    let order_0_todo = u1
97        .todos()
98        .create()
99        .title("another order 0 TODO")
100        .order(0)
101        .exec(&mut db)
102        .await?;
103
104    let mut actual = HashSet::new();
105
106    // Query for order 0 todos again
107    let todos = u1
108        .todos()
109        .query(Todo::fields().order().eq(0))
110        .exec(&mut db)
111        .await?;
112
113    for todo in todos {
114        assert!(actual.insert(todo.id));
115    }
116
117    let expect: HashSet<_> = [u1_todo_ids[0], order_0_todo.id].into_iter().collect();
118
119    assert_eq!(expect, actual);
120
121    // Query for non-existent TODOs
122    let todos = u2
123        .todos()
124        .query(Todo::fields().order().eq(1))
125        .exec(&mut db)
126        .await?;
127
128    assert!(todos.is_empty());
129    Ok(())
130}
131
132#[driver_test(id(ID), matrix(single, composite), requires(or(single, not(id_u64))))]
133pub async fn scoped_query_gt(test: &mut Test) -> Result<()> {
134    #[derive(Debug, toasty::Model)]
135    struct User {
136        #[key]
137        #[auto]
138        id: ID,
139
140        #[has_many]
141        todos: toasty::HasMany<Todo>,
142    }
143
144    #[derive(Debug, toasty::Model)]
145    #[driver_test_cfg(composite, key(partition = user_id, local = id))]
146    struct Todo {
147        #[auto]
148        #[driver_test_cfg(single, key)]
149        id: ID,
150
151        #[driver_test_cfg(single, index)]
152        user_id: ID,
153
154        #[belongs_to(key = user_id, references = id)]
155        user: toasty::BelongsTo<User>,
156
157        title: String,
158
159        order: i64,
160    }
161
162    let mut db = test.setup_db(models!(User, Todo)).await;
163
164    let user = User::create().exec(&mut db).await?;
165
166    let todos = Todo::create_many()
167        .item(Todo::create().user(&user).title("First").order(0))
168        .item(Todo::create().user(&user).title("Second").order(1))
169        .item(Todo::create().user(&user).title("Third").order(2))
170        .item(Todo::create().user(&user).title("Fourth").order(3))
171        .item(Todo::create().user(&user).title("Fifth").order(4))
172        .exec(&mut db)
173        .await?;
174
175    assert_eq!(5, todos.len());
176
177    // Find all != 2
178    let todos: Vec<_> = user
179        .todos()
180        .query(Todo::fields().order().ne(2))
181        .exec(&mut db)
182        .await?;
183
184    assert_eq_unordered!(
185        todos.iter().map(|todo| &todo.title[..]),
186        ["First", "Second", "Fourth", "Fifth"]
187    );
188
189    for todo in &todos {
190        assert_ne!(todo.order, 2);
191    }
192
193    // Find all greater than 2
194    let todos: Vec<_> = user
195        .todos()
196        .query(Todo::fields().order().gt(2))
197        .exec(&mut db)
198        .await?;
199
200    assert_eq_unordered!(
201        todos.iter().map(|todo| &todo.title[..]),
202        ["Fourth", "Fifth"]
203    );
204
205    // Find all greater than or equal to 2
206    let todos: Vec<_> = user
207        .todos()
208        .query(Todo::fields().order().ge(2))
209        .exec(&mut db)
210        .await?;
211
212    assert_eq_unordered!(
213        todos.iter().map(|todo| &todo.title[..]),
214        ["Third", "Fourth", "Fifth"]
215    );
216
217    // Find all less than to 2
218    let todos: Vec<_> = user
219        .todos()
220        .query(Todo::fields().order().lt(2))
221        .exec(&mut db)
222        .await?;
223
224    assert_eq_unordered!(
225        todos.iter().map(|todo| &todo.title[..]),
226        ["First", "Second"]
227    );
228
229    // Find all less than or equal to 2
230    let todos: Vec<_> = user
231        .todos()
232        .query(Todo::fields().order().le(2))
233        .exec(&mut db)
234        .await?;
235
236    assert_eq_unordered!(
237        todos.iter().map(|todo| &todo.title[..]),
238        ["First", "Second", "Third"]
239    );
240    Ok(())
241}