Skip to main content

max / makenotwork

8.1 KB · 241 lines History Blame Raw
1 //! Cart workflow tests — toggle, remove, count, PWYW amount update.
2
3 use crate::harness::TestHarness;
4 use serde_json::Value;
5
6 /// Helper: create a seller with a published paid item. Returns (seller_user_id, project_id, item_id).
7 /// Logs out the seller afterward.
8 async fn setup_seller_with_item(h: &mut TestHarness, price_cents: i64) -> (String, String, String) {
9 let setup = h.create_creator_with_item("cartseller", "digital", price_cents).await;
10 h.publish_project_and_item(&setup.project_id, &setup.item_id).await;
11 let seller_id = setup.user_id.to_string();
12 h.client.post_form("/logout", "").await;
13 (seller_id, setup.project_id, setup.item_id)
14 }
15
16 // ---------------------------------------------------------------------------
17 // Toggle
18 // ---------------------------------------------------------------------------
19
20 #[tokio::test]
21 async fn toggle_cart_adds_and_removes() {
22 let mut h = TestHarness::new().await;
23 let (_, _, item_id) = setup_seller_with_item(&mut h, 500).await;
24
25 h.signup("cartbuyer", "cartbuyer@test.com", "password123").await;
26 h.login("cartbuyer", "password123").await;
27
28 // Add to cart
29 let resp = h.client.post_form(&format!("/api/cart/{}", item_id), "").await;
30 assert!(resp.status.is_success(), "Toggle add failed: {} {}", resp.status, resp.text);
31 let data: Value = resp.json();
32 assert_eq!(data["in_cart"], true, "First toggle should add to cart");
33
34 // Toggle again to remove
35 let resp = h.client.post_form(&format!("/api/cart/{}", item_id), "").await;
36 assert!(resp.status.is_success(), "Toggle remove failed: {} {}", resp.status, resp.text);
37 let data: Value = resp.json();
38 assert_eq!(data["in_cart"], false, "Second toggle should remove from cart");
39 }
40
41 #[tokio::test]
42 async fn toggle_cart_own_item_rejected() {
43 let mut h = TestHarness::new().await;
44 let setup = h.create_creator_with_item("selfcart", "digital", 500).await;
45 h.publish_project_and_item(&setup.project_id, &setup.item_id).await;
46
47 // Creator tries to add own item to cart
48 let resp = h.client.post_form(&format!("/api/cart/{}", setup.item_id), "").await;
49 assert!(
50 resp.status.is_client_error(),
51 "Own item should not be added to cart: {} {}",
52 resp.status, resp.text
53 );
54 }
55
56 #[tokio::test]
57 async fn toggle_cart_unpublished_item_rejected() {
58 let mut h = TestHarness::new().await;
59 let setup = h.create_creator_with_item("draftcart", "digital", 500).await;
60 // Items default to is_public=true; explicitly unpublish
61 h.client
62 .put_form(&format!("/api/items/{}", setup.item_id), "is_public=false")
63 .await;
64 h.client.post_form("/logout", "").await;
65
66 h.signup("draftbuyer", "draftbuyer@test.com", "password123").await;
67 h.login("draftbuyer", "password123").await;
68
69 let resp = h.client.post_form(&format!("/api/cart/{}", setup.item_id), "").await;
70 assert!(
71 resp.status.is_client_error() || resp.status == 404,
72 "Unpublished item should not be added to cart: {} {}",
73 resp.status, resp.text
74 );
75 }
76
77 // ---------------------------------------------------------------------------
78 // Count
79 // ---------------------------------------------------------------------------
80
81 #[tokio::test]
82 async fn cart_count_empty() {
83 let mut h = TestHarness::new().await;
84 h.signup("emptycount", "emptycount@test.com", "password123").await;
85 h.login("emptycount", "password123").await;
86
87 let resp = h.client.get("/api/cart/count").await;
88 assert!(resp.status.is_success(), "Cart count failed: {} {}", resp.status, resp.text);
89 let data: Value = resp.json();
90 assert_eq!(data["count"], 0);
91 }
92
93 #[tokio::test]
94 async fn cart_count_after_add() {
95 let mut h = TestHarness::new().await;
96 let (_, _, item_id) = setup_seller_with_item(&mut h, 500).await;
97
98 h.signup("countbuyer", "countbuyer@test.com", "password123").await;
99 h.login("countbuyer", "password123").await;
100
101 // Add item
102 h.client.post_form(&format!("/api/cart/{}", item_id), "").await;
103
104 let resp = h.client.get("/api/cart/count").await;
105 assert!(resp.status.is_success());
106 let data: Value = resp.json();
107 assert_eq!(data["count"], 1);
108 }
109
110 // ---------------------------------------------------------------------------
111 // Remove
112 // ---------------------------------------------------------------------------
113
114 #[tokio::test]
115 async fn remove_from_cart() {
116 let mut h = TestHarness::new().await;
117 let (_, _, item_id) = setup_seller_with_item(&mut h, 500).await;
118
119 h.signup("rmbuyer", "rmbuyer@test.com", "password123").await;
120 h.login("rmbuyer", "password123").await;
121
122 // Add then explicitly remove
123 h.client.post_form(&format!("/api/cart/{}", item_id), "").await;
124 let resp = h.client.delete(&format!("/api/cart/{}", item_id)).await;
125 assert!(
126 resp.status.is_success() || resp.status == 204,
127 "Remove from cart failed: {} {}",
128 resp.status, resp.text
129 );
130
131 // Verify count is 0
132 let resp = h.client.get("/api/cart/count").await;
133 let data: Value = resp.json();
134 assert_eq!(data["count"], 0);
135 }
136
137 // ---------------------------------------------------------------------------
138 // PWYW amount
139 // ---------------------------------------------------------------------------
140
141 #[tokio::test]
142 async fn update_cart_pwyw_amount() {
143 let mut h = TestHarness::new().await;
144 // Create a PWYW item
145 let setup = h.create_creator_with_item("pwywseller", "digital", 0).await;
146 h.client
147 .put_form(
148 &format!("/api/items/{}", setup.item_id),
149 "pwyw_enabled=on&pwyw_min_cents=500",
150 )
151 .await;
152 h.publish_project_and_item(&setup.project_id, &setup.item_id).await;
153 h.client.post_form("/logout", "").await;
154
155 h.signup("pwywbuyer", "pwywbuyer@test.com", "password123").await;
156 h.login("pwywbuyer", "password123").await;
157
158 // Add to cart
159 h.client.post_form(&format!("/api/cart/{}", setup.item_id), "").await;
160
161 // Update PWYW amount
162 let resp = h
163 .client
164 .put_json(
165 &format!("/api/cart/{}", setup.item_id),
166 r#"{"amount_cents": 1000}"#,
167 )
168 .await;
169 assert!(
170 resp.status.is_success(),
171 "PWYW amount update failed: {} {}",
172 resp.status, resp.text
173 );
174 }
175
176 #[tokio::test]
177 async fn update_cart_pwyw_below_minimum_rejected() {
178 let mut h = TestHarness::new().await;
179 let setup = h.create_creator_with_item("pwywmin", "digital", 0).await;
180 h.client
181 .put_form(
182 &format!("/api/items/{}", setup.item_id),
183 "pwyw_enabled=on&pwyw_min_cents=500",
184 )
185 .await;
186 h.publish_project_and_item(&setup.project_id, &setup.item_id).await;
187 h.client.post_form("/logout", "").await;
188
189 h.signup("lowbuyer", "lowbuyer@test.com", "password123").await;
190 h.login("lowbuyer", "password123").await;
191
192 h.client.post_form(&format!("/api/cart/{}", setup.item_id), "").await;
193
194 // Try amount below minimum
195 let resp = h
196 .client
197 .put_json(
198 &format!("/api/cart/{}", setup.item_id),
199 r#"{"amount_cents": 100}"#,
200 )
201 .await;
202 assert!(
203 resp.status.is_client_error(),
204 "Below-minimum PWYW should be rejected: {} {}",
205 resp.status, resp.text
206 );
207 }
208
209 #[tokio::test]
210 async fn update_cart_pwyw_above_cap_rejected() {
211 let mut h = TestHarness::new().await;
212 let setup = h.create_creator_with_item("pwywcap", "digital", 0).await;
213 h.client
214 .put_form(
215 &format!("/api/items/{}", setup.item_id),
216 "pwyw_enabled=on&pwyw_min_cents=0",
217 )
218 .await;
219 h.publish_project_and_item(&setup.project_id, &setup.item_id).await;
220 h.client.post_form("/logout", "").await;
221
222 h.signup("capbuyer", "capbuyer@test.com", "password123").await;
223 h.login("capbuyer", "password123").await;
224
225 h.client.post_form(&format!("/api/cart/{}", setup.item_id), "").await;
226
227 // Try amount above $10,000 cap
228 let resp = h
229 .client
230 .put_json(
231 &format!("/api/cart/{}", setup.item_id),
232 r#"{"amount_cents": 1000001}"#,
233 )
234 .await;
235 assert!(
236 resp.status.is_client_error(),
237 "Above-cap PWYW should be rejected: {} {}",
238 resp.status, resp.text
239 );
240 }
241