toasty_driver_integration_suite/tests/
default_and_update.rs1use crate::prelude::*;
2
3#[driver_test(id(ID))]
4pub async fn default_expr_on_create(test: &mut Test) -> Result<()> {
5 #[derive(Debug, toasty::Model)]
6 struct Item {
7 #[key]
8 #[auto]
9 id: ID,
10
11 title: String,
12
13 #[default(5)]
14 view_count: i64,
15 }
16
17 let mut db = test.setup_db(models!(Item)).await;
18
19 let created = Item::create().title("hello").exec(&mut db).await?;
21 assert_eq!(created.view_count, 5);
22
23 let read = Item::get_by_id(&mut db, &created.id).await?;
25 assert_eq!(read.view_count, 5);
26
27 Ok(())
28}
29
30#[driver_test(id(ID))]
31pub async fn default_expr_override(test: &mut Test) -> Result<()> {
32 #[derive(Debug, toasty::Model)]
33 struct Item {
34 #[key]
35 #[auto]
36 id: ID,
37
38 title: String,
39
40 #[default(5)]
41 view_count: i64,
42 }
43
44 let mut db = test.setup_db(models!(Item)).await;
45
46 let created = Item::create()
48 .title("hello")
49 .view_count(42)
50 .exec(&mut db)
51 .await?;
52 assert_eq!(created.view_count, 42);
53
54 let read = Item::get_by_id(&mut db, &created.id).await?;
55 assert_eq!(read.view_count, 42);
56
57 Ok(())
58}
59
60#[driver_test(id(ID))]
61pub async fn update_expr_on_create(test: &mut Test) -> Result<()> {
62 use jiff::Timestamp;
63
64 #[derive(Debug, toasty::Model)]
65 struct Item {
66 #[key]
67 #[auto]
68 id: ID,
69
70 title: String,
71
72 #[update(jiff::Timestamp::now())]
73 updated_at: Timestamp,
74 }
75
76 let mut db = test.setup_db(models!(Item)).await;
77
78 let before = Timestamp::now();
79 let created = Item::create().title("hello").exec(&mut db).await?;
80 let after = Timestamp::now();
81
82 assert!(created.updated_at >= before);
84 assert!(created.updated_at <= after);
85
86 Ok(())
87}
88
89#[driver_test(id(ID))]
90pub async fn update_expr_on_update(test: &mut Test) -> Result<()> {
91 use jiff::Timestamp;
92
93 #[derive(Debug, toasty::Model)]
94 struct Item {
95 #[key]
96 #[auto]
97 id: ID,
98
99 title: String,
100
101 #[update(jiff::Timestamp::now())]
102 updated_at: Timestamp,
103 }
104
105 let mut db = test.setup_db(models!(Item)).await;
106
107 let mut item = Item::create().title("hello").exec(&mut db).await?;
108 let created_ts = item.updated_at;
109
110 tokio::time::sleep(std::time::Duration::from_millis(10)).await;
112
113 let before = Timestamp::now();
114 item.update().title("updated").exec(&mut db).await?;
115 let after = Timestamp::now();
116
117 assert!(item.updated_at >= before);
119 assert!(item.updated_at <= after);
120 assert!(item.updated_at > created_ts);
121
122 Ok(())
123}
124
125#[driver_test(id(ID))]
126pub async fn update_expr_override_on_update(test: &mut Test) -> Result<()> {
127 use jiff::Timestamp;
128
129 #[derive(Debug, toasty::Model)]
130 struct Item {
131 #[key]
132 #[auto]
133 id: ID,
134
135 title: String,
136
137 #[update(jiff::Timestamp::now())]
138 updated_at: Timestamp,
139 }
140
141 let mut db = test.setup_db(models!(Item)).await;
142
143 let mut item = Item::create().title("hello").exec(&mut db).await?;
144
145 let explicit_ts = Timestamp::from_second(946684800).unwrap(); item.update()
148 .title("updated")
149 .updated_at(explicit_ts)
150 .exec(&mut db)
151 .await?;
152
153 assert_eq!(item.updated_at, explicit_ts);
154
155 let read = Item::get_by_id(&mut db, &item.id).await?;
156 assert_eq!(read.updated_at, explicit_ts);
157
158 Ok(())
159}
160
161#[driver_test(id(ID))]
162pub async fn default_and_update_on_same_field(test: &mut Test) -> Result<()> {
163 #[derive(Debug, toasty::Model)]
164 struct Item {
165 #[key]
166 #[auto]
167 id: ID,
168
169 title: String,
170
171 #[default("draft".to_string())]
173 #[update("edited".to_string())]
174 status: String,
175 }
176
177 let mut db = test.setup_db(models!(Item)).await;
178
179 let mut item = Item::create().title("hello").exec(&mut db).await?;
181 assert_eq!(item.status, "draft");
182
183 item.update().title("updated").exec(&mut db).await?;
185 assert_eq!(item.status, "edited");
186
187 let mut item2 = Item::create()
189 .title("hello")
190 .status("published".to_string())
191 .exec(&mut db)
192 .await?;
193 assert_eq!(item2.status, "published");
194
195 item2
197 .update()
198 .title("updated")
199 .status("archived".to_string())
200 .exec(&mut db)
201 .await?;
202 assert_eq!(item2.status, "archived");
203
204 Ok(())
205}
206
207#[driver_test(id(ID))]
208pub async fn auto_on_timestamp_fields(test: &mut Test) -> Result<()> {
209 use jiff::Timestamp;
210
211 #[derive(Debug, toasty::Model)]
212 struct Item {
213 #[key]
214 #[auto]
215 id: ID,
216
217 title: String,
218
219 #[auto]
220 created_at: Timestamp,
221
222 #[auto]
223 updated_at: Timestamp,
224 }
225
226 let mut db = test.setup_db(models!(Item)).await;
227
228 let before = Timestamp::now();
229 let mut item = Item::create().title("hello").exec(&mut db).await?;
230 let after = Timestamp::now();
231
232 assert!(item.created_at >= before);
233 assert!(item.created_at <= after);
234 assert!(item.updated_at >= before);
235 assert!(item.updated_at <= after);
236
237 tokio::time::sleep(std::time::Duration::from_millis(10)).await;
238
239 let before_update = Timestamp::now();
240 item.update().title("updated").exec(&mut db).await?;
241 let after_update = Timestamp::now();
242
243 assert!(item.created_at <= after);
245 assert!(item.updated_at >= before_update);
246 assert!(item.updated_at <= after_update);
247
248 Ok(())
249}