toasty_driver_integration_suite/tests/
serialize.rs1use crate::prelude::*;
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use toasty_core::{
6 driver::{Operation, Rows},
7 stmt::{ExprSet, Statement, Value},
8};
9
10#[driver_test(id(ID))]
11pub async fn serialize_vec_string(t: &mut Test) -> Result<(), BoxError> {
12 #[derive(Debug, toasty::Model)]
13 struct Item {
14 #[key]
15 #[auto]
16 id: ID,
17 #[serialize(json)]
18 tags: Vec<String>,
19 }
20
21 let mut db = t.setup_db(models!(Item)).await;
22
23 t.log().clear();
25 let tags = vec!["rust".to_string(), "toasty".to_string()];
26 let expected_json = serde_json::to_string(&tags).unwrap();
27 let mut record = Item::create().tags(tags.clone()).exec(&mut db).await?;
28
29 let (op, _) = t.log().pop();
30 assert_struct!(op, Operation::QuerySql(_ {
31 stmt: Statement::Insert(_ {
32 source.body: ExprSet::Values(_ {
33 rows: [=~ (Any, expected_json)],
34 ..
35 }),
36 ..
37 }),
38 ..
39 }));
40
41 assert_eq!(Item::get_by_id(&mut db, &record.id).await?.tags, tags);
42
43 t.log().clear();
45 let new_tags = vec!["b".to_string(), "c".to_string()];
46 let expected_json = serde_json::to_string(&new_tags).unwrap();
47 record.update().tags(new_tags.clone()).exec(&mut db).await?;
48
49 let (op, resp) = t.log().pop();
50 if t.capability().sql {
51 assert_struct!(op, Operation::QuerySql(_ {
52 stmt: Statement::Update(_ {
53 assignments: #{ 1: _ { expr: == expected_json, .. }},
54 ..
55 }),
56 ..
57 }));
58 } else {
59 assert_struct!(op, Operation::UpdateByKey(_ {
60 assignments: #{ 1: _ { expr: == expected_json, .. }},
61 ..
62 }));
63 }
64 assert_struct!(resp, _ { rows: Rows::Count(1), .. });
65
66 assert_eq!(Item::get_by_id(&mut db, &record.id).await?.tags, new_tags);
67
68 Ok(())
69}
70
71#[driver_test(id(ID))]
72pub async fn serialize_nullable(t: &mut Test) -> Result<(), BoxError> {
73 #[derive(Debug, toasty::Model)]
74 struct Item {
75 #[key]
76 #[auto]
77 id: ID,
78 #[serialize(json, nullable)]
79 data: Option<HashMap<String, String>>,
80 }
81
82 let mut db = t.setup_db(models!(Item)).await;
83
84 t.log().clear();
86 let map = HashMap::from([("key".to_string(), "value".to_string())]);
87 let expected_json = serde_json::to_string(&map).unwrap();
88 let record = Item::create().data(Some(map.clone())).exec(&mut db).await?;
89
90 let (op, _) = t.log().pop();
91 assert_struct!(op, Operation::QuerySql(_ {
92 stmt: Statement::Insert(_ {
93 source.body: ExprSet::Values(_ {
94 rows: [=~ (Any, expected_json)],
95 ..
96 }),
97 ..
98 }),
99 ..
100 }));
101
102 assert_eq!(Item::get_by_id(&mut db, &record.id).await?.data, Some(map));
103
104 t.log().clear();
106 let empty_record = Item::create().data(None).exec(&mut db).await?;
107
108 let (op, _) = t.log().pop();
109 assert_struct!(op, Operation::QuerySql(_ {
110 stmt: Statement::Insert(_ {
111 source.body: ExprSet::Values(_ {
112 rows: [=~ (Any, Value::Null)],
113 ..
114 }),
115 ..
116 }),
117 ..
118 }));
119
120 assert_eq!(Item::get_by_id(&mut db, &empty_record.id).await?.data, None);
121
122 Ok(())
123}
124
125#[driver_test(id(ID))]
126pub async fn serialize_non_nullable_option(t: &mut Test) -> Result<(), BoxError> {
127 #[derive(Debug, toasty::Model)]
128 struct Item {
129 #[key]
130 #[auto]
131 id: ID,
132 #[serialize(json)]
133 extra: Option<String>,
134 }
135
136 let mut db = t.setup_db(models!(Item)).await;
137
138 t.log().clear();
140 let empty_record = Item::create().extra(None).exec(&mut db).await?;
141
142 let (op, _) = t.log().pop();
143 assert_struct!(op, Operation::QuerySql(_ {
144 stmt: Statement::Insert(_ {
145 source.body: ExprSet::Values(_ {
146 rows: [=~ (Any, "null")],
147 ..
148 }),
149 ..
150 }),
151 ..
152 }));
153
154 assert_eq!(
155 Item::get_by_id(&mut db, &empty_record.id).await?.extra,
156 None
157 );
158
159 t.log().clear();
161 let expected_json = serde_json::to_string(&Some("hello")).unwrap();
162 let record = Item::create()
163 .extra(Some("hello".to_string()))
164 .exec(&mut db)
165 .await?;
166
167 let (op, _) = t.log().pop();
168 assert_struct!(op, Operation::QuerySql(_ {
169 stmt: Statement::Insert(_ {
170 source.body: ExprSet::Values(_ {
171 rows: [=~ (Any, expected_json)],
172 ..
173 }),
174 ..
175 }),
176 ..
177 }));
178
179 assert_eq!(
180 Item::get_by_id(&mut db, &record.id).await?.extra,
181 Some("hello".to_string())
182 );
183
184 Ok(())
185}
186
187#[driver_test(id(ID))]
188pub async fn serialize_custom_struct(t: &mut Test) -> Result<(), BoxError> {
189 #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
190 struct Metadata {
191 version: u32,
192 labels: Vec<String>,
193 }
194
195 #[derive(Debug, toasty::Model)]
196 struct Item {
197 #[key]
198 #[auto]
199 id: ID,
200 #[serialize(json)]
201 meta: Metadata,
202 }
203
204 let mut db = t.setup_db(models!(Item)).await;
205 t.log().clear();
206
207 let meta = Metadata {
208 version: 42,
209 labels: vec!["alpha".to_string(), "beta".to_string()],
210 };
211 let expected_json = serde_json::to_string(&meta).unwrap();
212 let record = Item::create().meta(meta.clone()).exec(&mut db).await?;
213
214 let (op, _) = t.log().pop();
215 assert_struct!(op, Operation::QuerySql(_ {
216 stmt: Statement::Insert(_ {
217 source.body: ExprSet::Values(_ {
218 rows: [=~ (Any, expected_json)],
219 ..
220 }),
221 ..
222 }),
223 ..
224 }));
225
226 assert_eq!(Item::get_by_id(&mut db, &record.id).await?.meta, meta);
227
228 Ok(())
229}