toasty_driver_integration_suite/tests/
has_many_n_1.rs1use crate::prelude::*;
4use std::collections::HashSet;
5
6#[driver_test(id(ID))]
7pub async fn hello_world(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 struct Todo {
20 #[key]
21 #[auto]
22 id: ID,
23
24 #[index]
25 user_id: ID,
26
27 #[belongs_to(key = user_id, references = id)]
28 user: toasty::BelongsTo<User>,
29
30 #[index]
31 category_id: ID,
32
33 #[belongs_to(key = category_id, references = id)]
34 category: toasty::BelongsTo<Category>,
35
36 title: String,
37 }
38
39 #[derive(Debug, toasty::Model)]
40 struct Category {
41 #[key]
42 #[auto]
43 id: ID,
44
45 #[has_many]
46 #[allow(dead_code)]
47 todos: toasty::HasMany<Todo>,
48
49 #[allow(dead_code)]
50 name: String,
51 }
52
53 let mut db = test.setup_db(models!(User, Todo, Category)).await;
54
55 let cat1 = Category::create().name("a").exec(&mut db).await?;
56 let cat2 = Category::create().name("b").exec(&mut db).await?;
57
58 let user = User::create()
60 .todo(Todo::create().category(&cat1).title("one"))
61 .todo(Todo::create().category(&cat2).title("two"))
62 .todo(Todo::create().category(&cat2).title("three"))
63 .exec(&mut db)
64 .await?;
65
66 let todos = user.todos().exec(&mut db).await?;
67
68 assert_eq!(3, todos.len());
69 Ok(())
70}
71
72#[driver_test(id(ID))]
73pub async fn query_by_index_optimization(test: &mut Test) -> Result<()> {
74 #[derive(Debug, toasty::Model)]
75 struct Board {
76 #[key]
77 #[auto]
78 id: ID,
79
80 name: String,
81
82 #[has_many]
83 users: toasty::HasMany<User>,
84 }
85
86 #[derive(Debug, toasty::Model)]
87 struct User {
88 #[key]
89 #[auto]
90 id: ID,
91
92 name: String,
93
94 #[index]
95 board_id: ID,
96
97 #[belongs_to(key = board_id, references = id)]
98 board: toasty::BelongsTo<Board>,
99 }
100
101 let mut db = test.setup_db(models!(Board, User)).await;
102 if db.capability().sql {
103 return Ok(());
105 }
106 let board = Board::create()
108 .name("Test Board")
109 .user(User::create().name("User 1"))
110 .user(User::create().name("User 2"))
111 .user(User::create().name("User 3"))
112 .user(User::create().name("User 4"))
113 .user(User::create().name("User 5"))
114 .exec(&mut db)
115 .await?;
116
117 Board::create()
118 .name("Test Board2")
119 .user(User::create().name("User 6"))
120 .exec(&mut db)
121 .await?;
122
123 test.log().clear();
125
126 let board_from_db = Board::filter_by_id(board.id)
128 .include(Board::fields().users())
129 .get(&mut db)
130 .await?;
131
132 let log = test.log();
134 let operation_count = log.len();
135
136 assert_eq!(
137 operation_count, 2,
138 "Expected 2 DynamoDB operations (GetByKey + QueryPk with index), got {:?}",
139 log
140 );
141
142 let from_db = board_from_db
144 .users
145 .get()
146 .iter()
147 .map(|u| u.id)
148 .collect::<HashSet<_>>();
149 let expected = board
150 .users
151 .get()
152 .iter()
153 .map(|u| u.id)
154 .collect::<HashSet<_>>();
155 assert_eq!(from_db, expected);
156
157 Ok(())
158}