toasty_driver_integration_suite/tests/
relation_has_many_multi.rs

1//! Test has_many associations with multiple relations to the same model
2
3use crate::prelude::*;
4use std::collections::HashMap;
5
6#[driver_test(id(ID), scenario(crate::scenarios::has_many_multi_relation))]
7pub async fn crud_user_todos_categories(test: &mut Test) -> Result<()> {
8    let mut db = setup(test).await;
9
10    // Create a user
11    let user = User::create().name("Ann Chovey").exec(&mut db).await?;
12
13    // No TODOs
14    assert!(user.todos().exec(&mut db).await?.is_empty());
15
16    // Create a category
17    let category = Category::create().name("Food").exec(&mut db).await?;
18
19    let mut todos = vec![];
20
21    // Create some TODOs using the different builders
22    todos.push(
23        user.todos()
24            .create()
25            .title("one")
26            .category(&category)
27            .exec(&mut db)
28            .await?,
29    );
30
31    todos.push(
32        Todo::create()
33            .title("two")
34            .user(&user)
35            .category(&category)
36            .exec(&mut db)
37            .await?,
38    );
39
40    todos.push(
41        category
42            .todos()
43            .create()
44            .title("three")
45            .user(&user)
46            .exec(&mut db)
47            .await?,
48    );
49
50    let expect: HashMap<_, _> = todos.into_iter().map(|todo| (todo.id, todo)).collect();
51
52    let lists = [
53        category.todos().exec(&mut db).await?,
54        user.todos().exec(&mut db).await?,
55        Todo::filter_by_user_id(user.id).exec(&mut db).await?,
56    ];
57
58    for list in lists {
59        assert_eq!(3, list.len());
60
61        let actual: HashMap<_, _> = list.into_iter().map(|todo| (todo.id, todo)).collect();
62        assert_eq!(3, actual.len());
63
64        for (id, actual) in actual {
65            assert_eq!(expect[&id].title, actual.title);
66
67            let user = actual.user().exec(&mut db).await?;
68            assert_eq!(user.name, "Ann Chovey");
69        }
70    }
71
72    // Create another user and category
73    let user2 = User::create().name("Not ann").exec(&mut db).await?;
74    let category2 = Category::create().name("drink").exec(&mut db).await?;
75
76    category
77        .todos()
78        .create()
79        .user(&user2)
80        .title("NOPE")
81        .exec(&mut db)
82        .await?;
83    user.todos()
84        .create()
85        .category(&category2)
86        .title("FAIL")
87        .exec(&mut db)
88        .await?;
89
90    async fn check_todo_list(
91        db: &mut toasty::Db,
92        expect: &HashMap<ID, Todo>,
93        list: Vec<Todo>,
94    ) -> Result<()> {
95        assert_eq!(3, list.len(), "list={list:#?}");
96
97        let actual: HashMap<_, _> = list.into_iter().map(|todo| (todo.id, todo)).collect();
98
99        assert_eq!(3, actual.len(), "actual={actual:#?}");
100
101        for (id, actual) in actual {
102            assert_eq!(expect[&id].title, actual.title);
103            let category = actual.category().exec(db).await?;
104            assert_eq!(category.name, "Food");
105        }
106        Ok(())
107    }
108
109    let list = category
110        .todos()
111        .query(Todo::fields().user().eq(&user))
112        .exec(&mut db)
113        .await?;
114    check_todo_list(&mut db, &expect, list).await?;
115
116    let list = user
117        .todos()
118        .query(Todo::fields().category().eq(&category))
119        .exec(&mut db)
120        .await?;
121    check_todo_list(&mut db, &expect, list).await?;
122
123    let list = Todo::filter_by_user_id(user.id)
124        .filter(Todo::fields().category().eq(&category))
125        .exec(&mut db)
126        .await?;
127    check_todo_list(&mut db, &expect, list).await
128}