toasty_driver_integration_suite/tests/
index_unique_collection.rs1use crate::prelude::*;
4
5#[driver_test(requires(unique_list_index))]
6pub async fn unique_vec_uses_ordered_complete_value(t: &mut Test) -> Result<()> {
7 #[derive(Debug, toasty::Model)]
8 struct Item {
9 #[key]
10 #[auto]
11 id: uuid::Uuid,
12 #[unique]
13 tags: Vec<String>,
14 }
15
16 let mut db = t.setup_db(models!(Item)).await;
17
18 toasty::create!(Item {
19 tags: ["rust", "toasty"],
20 })
21 .exec(&mut db)
22 .await?;
23
24 assert_err!(
25 toasty::create!(Item {
26 tags: ["rust", "toasty"],
27 })
28 .exec(&mut db)
29 .await
30 );
31
32 toasty::create!(Item {
33 tags: ["toasty", "rust"],
34 })
35 .exec(&mut db)
36 .await?;
37 toasty::create!(Item {
38 tags: ["rust", "rust"],
39 })
40 .exec(&mut db)
41 .await?;
42 toasty::create!(Item {
43 tags: Vec::<String>::new(),
44 })
45 .exec(&mut db)
46 .await?;
47
48 assert_err!(
49 toasty::create!(Item {
50 tags: Vec::<String>::new(),
51 })
52 .exec(&mut db)
53 .await
54 );
55
56 Ok(())
57}
58
59#[driver_test(requires(and(unique_list_index, upsert_unique)))]
60pub async fn unique_vec_generated_operations(t: &mut Test) -> Result<()> {
61 #[derive(Debug, toasty::Model)]
62 struct Item {
63 #[key]
64 #[auto]
65 id: uuid::Uuid,
66 #[unique]
67 tags: Vec<String>,
68 name: String,
69 }
70
71 let mut db = t.setup_db(models!(Item)).await;
72 let item = toasty::create!(Item {
73 tags: ["one", "two"],
74 name: "original",
75 })
76 .exec(&mut db)
77 .await?;
78
79 let found = Item::get_by_tags(&mut db, ["one", "two"]).await?;
80 assert_eq!(found.id, item.id);
81
82 let filtered = Item::filter_by_tags(["one", "two"]).exec(&mut db).await?;
83 assert_eq!(filtered.len(), 1);
84
85 Item::update_by_tags(["one", "two"])
86 .tags(["three"])
87 .exec(&mut db)
88 .await?;
89
90 let updated = Item::upsert_by_tags(["three"])
91 .name("updated")
92 .exec(&mut db)
93 .await?;
94 assert_eq!(updated.id, item.id);
95 assert_eq!(updated.name, "updated");
96
97 Item::delete_by_tags(&mut db, ["three"]).await?;
98 assert_none!(
99 Item::filter_by_tags(["three"])
100 .first()
101 .exec(&mut db)
102 .await?
103 );
104
105 Ok(())
106}
107
108#[driver_test(requires(unique_list_index))]
109pub async fn unique_vec_newtype(t: &mut Test) -> Result<()> {
110 #[derive(Debug, toasty::Embed)]
111 struct Tags(Vec<String>);
112
113 #[derive(Debug, toasty::Model)]
114 struct Item {
115 #[key]
116 #[auto]
117 id: uuid::Uuid,
118 #[unique]
119 tags: Tags,
120 }
121
122 let mut db = t.setup_db(models!(Item)).await;
123
124 toasty::create!(Item {
125 tags: Tags(vec!["rust".into(), "toasty".into()]),
126 })
127 .exec(&mut db)
128 .await?;
129
130 assert_err!(
131 toasty::create!(Item {
132 tags: Tags(vec!["rust".into(), "toasty".into()]),
133 })
134 .exec(&mut db)
135 .await
136 );
137
138 let found = Item::get_by_tags(&mut db, Tags(vec!["rust".into(), "toasty".into()])).await?;
139 assert_eq!(found.tags.0, ["rust", "toasty"]);
140
141 Ok(())
142}
143
144#[driver_test(requires(and(vec_scalar, not(unique_list_index))))]
145pub async fn unique_vec_unsupported_backend(t: &mut Test) {
146 #[derive(Debug, toasty::Model)]
147 struct Item {
148 #[key]
149 #[auto]
150 id: uuid::Uuid,
151 #[unique]
152 tags: Vec<String>,
153 }
154
155 let err = assert_err!(t.try_setup_db(models!(Item)).await);
156 assert!(err.is_unsupported_feature());
157
158 let message = err.to_string();
159 assert!(
160 message.contains("#[unique]")
161 && message.contains("Vec<T>")
162 && message.contains("complete collection values"),
163 "unexpected schema-build error: {message}"
164 );
165}
166
167#[driver_test(requires(vec_scalar))]
168pub async fn non_unique_vec_index_is_rejected(t: &mut Test) {
169 #[derive(Debug, toasty::Model)]
170 struct Item {
171 #[key]
172 #[auto]
173 id: uuid::Uuid,
174 #[index]
175 tags: Vec<String>,
176 }
177
178 let err = assert_err!(t.try_setup_db(models!(Item)).await);
179 assert!(err.is_unsupported_feature());
180
181 let message = err.to_string();
182 assert!(
183 message.contains("#[index]") && message.contains("Vec<T>"),
184 "unexpected schema-build error: {message}"
185 );
186}