this repo has no description
1mod common;
2use common::*;
3use reqwest::StatusCode;
4use serde_json::{Value, json};
5
6#[tokio::test]
7async fn test_create_invite_code_success() {
8 let client = client();
9 let (access_jwt, _did) = create_admin_account_and_login(&client).await;
10 let payload = json!({
11 "useCount": 5
12 });
13 let res = client
14 .post(format!(
15 "{}/xrpc/com.atproto.server.createInviteCode",
16 base_url().await
17 ))
18 .bearer_auth(&access_jwt)
19 .json(&payload)
20 .send()
21 .await
22 .expect("Failed to send request");
23 assert_eq!(res.status(), StatusCode::OK);
24 let body: Value = res.json().await.expect("Response was not valid JSON");
25 assert!(body["code"].is_string());
26 let code = body["code"].as_str().unwrap();
27 assert!(!code.is_empty());
28 assert!(code.contains('-'), "Code should be in hostname-xxxxx-xxxxx format");
29 let parts: Vec<&str> = code.split('-').collect();
30 assert!(parts.len() >= 3, "Code should have at least 3 parts (hostname + 2 random parts)");
31}
32
33#[tokio::test]
34async fn test_create_invite_code_no_auth() {
35 let client = client();
36 let payload = json!({
37 "useCount": 5
38 });
39 let res = client
40 .post(format!(
41 "{}/xrpc/com.atproto.server.createInviteCode",
42 base_url().await
43 ))
44 .json(&payload)
45 .send()
46 .await
47 .expect("Failed to send request");
48 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
49 let body: Value = res.json().await.expect("Response was not valid JSON");
50 assert_eq!(body["error"], "AuthenticationRequired");
51}
52
53#[tokio::test]
54async fn test_create_invite_code_non_admin() {
55 let client = client();
56 let (access_jwt, _did) = create_account_and_login(&client).await;
57 let payload = json!({
58 "useCount": 5
59 });
60 let res = client
61 .post(format!(
62 "{}/xrpc/com.atproto.server.createInviteCode",
63 base_url().await
64 ))
65 .bearer_auth(&access_jwt)
66 .json(&payload)
67 .send()
68 .await
69 .expect("Failed to send request");
70 assert_eq!(res.status(), StatusCode::FORBIDDEN);
71 let body: Value = res.json().await.expect("Response was not valid JSON");
72 assert_eq!(body["error"], "AdminRequired");
73}
74
75#[tokio::test]
76async fn test_create_invite_code_invalid_use_count() {
77 let client = client();
78 let (access_jwt, _did) = create_admin_account_and_login(&client).await;
79 let payload = json!({
80 "useCount": 0
81 });
82 let res = client
83 .post(format!(
84 "{}/xrpc/com.atproto.server.createInviteCode",
85 base_url().await
86 ))
87 .bearer_auth(&access_jwt)
88 .json(&payload)
89 .send()
90 .await
91 .expect("Failed to send request");
92 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
93 let body: Value = res.json().await.expect("Response was not valid JSON");
94 assert_eq!(body["error"], "InvalidRequest");
95}
96
97#[tokio::test]
98async fn test_create_invite_code_for_another_account() {
99 let client = client();
100 let (access_jwt1, _did1) = create_admin_account_and_login(&client).await;
101 let (_access_jwt2, did2) = create_account_and_login(&client).await;
102 let payload = json!({
103 "useCount": 3,
104 "forAccount": did2
105 });
106 let res = client
107 .post(format!(
108 "{}/xrpc/com.atproto.server.createInviteCode",
109 base_url().await
110 ))
111 .bearer_auth(&access_jwt1)
112 .json(&payload)
113 .send()
114 .await
115 .expect("Failed to send request");
116 assert_eq!(res.status(), StatusCode::OK);
117 let body: Value = res.json().await.expect("Response was not valid JSON");
118 assert!(body["code"].is_string());
119}
120
121#[tokio::test]
122async fn test_create_invite_codes_success() {
123 let client = client();
124 let (access_jwt, _did) = create_admin_account_and_login(&client).await;
125 let payload = json!({
126 "useCount": 2,
127 "codeCount": 3
128 });
129 let res = client
130 .post(format!(
131 "{}/xrpc/com.atproto.server.createInviteCodes",
132 base_url().await
133 ))
134 .bearer_auth(&access_jwt)
135 .json(&payload)
136 .send()
137 .await
138 .expect("Failed to send request");
139 assert_eq!(res.status(), StatusCode::OK);
140 let body: Value = res.json().await.expect("Response was not valid JSON");
141 assert!(body["codes"].is_array());
142 let codes = body["codes"].as_array().unwrap();
143 assert_eq!(codes.len(), 1);
144 assert_eq!(codes[0]["account"], "admin");
145 assert_eq!(codes[0]["codes"].as_array().unwrap().len(), 3);
146}
147
148#[tokio::test]
149async fn test_create_invite_codes_for_multiple_accounts() {
150 let client = client();
151 let (access_jwt1, did1) = create_admin_account_and_login(&client).await;
152 let (_access_jwt2, did2) = create_account_and_login(&client).await;
153 let payload = json!({
154 "useCount": 1,
155 "codeCount": 2,
156 "forAccounts": [did1, did2]
157 });
158 let res = client
159 .post(format!(
160 "{}/xrpc/com.atproto.server.createInviteCodes",
161 base_url().await
162 ))
163 .bearer_auth(&access_jwt1)
164 .json(&payload)
165 .send()
166 .await
167 .expect("Failed to send request");
168 assert_eq!(res.status(), StatusCode::OK);
169 let body: Value = res.json().await.expect("Response was not valid JSON");
170 let codes = body["codes"].as_array().unwrap();
171 assert_eq!(codes.len(), 2);
172 for code_obj in codes {
173 assert!(code_obj["account"].is_string());
174 assert_eq!(code_obj["codes"].as_array().unwrap().len(), 2);
175 }
176}
177
178#[tokio::test]
179async fn test_create_invite_codes_no_auth() {
180 let client = client();
181 let payload = json!({
182 "useCount": 2
183 });
184 let res = client
185 .post(format!(
186 "{}/xrpc/com.atproto.server.createInviteCodes",
187 base_url().await
188 ))
189 .json(&payload)
190 .send()
191 .await
192 .expect("Failed to send request");
193 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
194}
195
196#[tokio::test]
197async fn test_create_invite_codes_non_admin() {
198 let client = client();
199 let (access_jwt, _did) = create_account_and_login(&client).await;
200 let payload = json!({
201 "useCount": 2
202 });
203 let res = client
204 .post(format!(
205 "{}/xrpc/com.atproto.server.createInviteCodes",
206 base_url().await
207 ))
208 .bearer_auth(&access_jwt)
209 .json(&payload)
210 .send()
211 .await
212 .expect("Failed to send request");
213 assert_eq!(res.status(), StatusCode::FORBIDDEN);
214 let body: Value = res.json().await.expect("Response was not valid JSON");
215 assert_eq!(body["error"], "AdminRequired");
216}
217
218#[tokio::test]
219async fn test_get_account_invite_codes_success() {
220 let client = client();
221 let (admin_jwt, _admin_did) = create_admin_account_and_login(&client).await;
222 let (user_jwt, user_did) = create_account_and_login(&client).await;
223
224 let create_payload = json!({
225 "useCount": 5,
226 "forAccount": user_did
227 });
228 let _ = client
229 .post(format!(
230 "{}/xrpc/com.atproto.server.createInviteCode",
231 base_url().await
232 ))
233 .bearer_auth(&admin_jwt)
234 .json(&create_payload)
235 .send()
236 .await
237 .expect("Failed to create invite code");
238
239 let res = client
240 .get(format!(
241 "{}/xrpc/com.atproto.server.getAccountInviteCodes",
242 base_url().await
243 ))
244 .bearer_auth(&user_jwt)
245 .send()
246 .await
247 .expect("Failed to send request");
248 assert_eq!(res.status(), StatusCode::OK);
249 let body: Value = res.json().await.expect("Response was not valid JSON");
250 assert!(body["codes"].is_array());
251 let codes = body["codes"].as_array().unwrap();
252 assert!(!codes.is_empty());
253 let code = &codes[0];
254 assert!(code["code"].is_string());
255 assert!(code["available"].is_number());
256 assert!(code["disabled"].is_boolean());
257 assert!(code["createdAt"].is_string());
258 assert!(code["uses"].is_array());
259 assert_eq!(code["forAccount"], user_did);
260 assert_eq!(code["createdBy"], "admin");
261}
262
263#[tokio::test]
264async fn test_get_account_invite_codes_no_auth() {
265 let client = client();
266 let res = client
267 .get(format!(
268 "{}/xrpc/com.atproto.server.getAccountInviteCodes",
269 base_url().await
270 ))
271 .send()
272 .await
273 .expect("Failed to send request");
274 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
275}
276
277#[tokio::test]
278async fn test_get_account_invite_codes_include_used_filter() {
279 let client = client();
280 let (admin_jwt, _admin_did) = create_admin_account_and_login(&client).await;
281 let (user_jwt, user_did) = create_account_and_login(&client).await;
282
283 let create_payload = json!({
284 "useCount": 5,
285 "forAccount": user_did
286 });
287 let _ = client
288 .post(format!(
289 "{}/xrpc/com.atproto.server.createInviteCode",
290 base_url().await
291 ))
292 .bearer_auth(&admin_jwt)
293 .json(&create_payload)
294 .send()
295 .await
296 .expect("Failed to create invite code");
297
298 let res = client
299 .get(format!(
300 "{}/xrpc/com.atproto.server.getAccountInviteCodes",
301 base_url().await
302 ))
303 .bearer_auth(&user_jwt)
304 .query(&[("includeUsed", "false")])
305 .send()
306 .await
307 .expect("Failed to send request");
308 assert_eq!(res.status(), StatusCode::OK);
309 let body: Value = res.json().await.expect("Response was not valid JSON");
310 assert!(body["codes"].is_array());
311 for code in body["codes"].as_array().unwrap() {
312 assert!(code["available"].as_i64().unwrap() > 0);
313 }
314}
315
316#[tokio::test]
317async fn test_get_account_invite_codes_filters_disabled() {
318 let client = client();
319 let (admin_jwt, admin_did) = create_admin_account_and_login(&client).await;
320
321 let create_payload = json!({
322 "useCount": 5,
323 "forAccount": admin_did
324 });
325 let create_res = client
326 .post(format!(
327 "{}/xrpc/com.atproto.server.createInviteCode",
328 base_url().await
329 ))
330 .bearer_auth(&admin_jwt)
331 .json(&create_payload)
332 .send()
333 .await
334 .expect("Failed to create invite code");
335 let create_body: Value = create_res.json().await.unwrap();
336 let code = create_body["code"].as_str().unwrap();
337
338 let disable_payload = json!({
339 "codes": [code]
340 });
341 let _ = client
342 .post(format!(
343 "{}/xrpc/com.atproto.admin.disableInviteCodes",
344 base_url().await
345 ))
346 .bearer_auth(&admin_jwt)
347 .json(&disable_payload)
348 .send()
349 .await
350 .expect("Failed to disable invite code");
351
352 let res = client
353 .get(format!(
354 "{}/xrpc/com.atproto.server.getAccountInviteCodes",
355 base_url().await
356 ))
357 .bearer_auth(&admin_jwt)
358 .send()
359 .await
360 .expect("Failed to send request");
361 assert_eq!(res.status(), StatusCode::OK);
362 let body: Value = res.json().await.expect("Response was not valid JSON");
363 let codes = body["codes"].as_array().unwrap();
364 for c in codes {
365 assert_ne!(c["code"].as_str().unwrap(), code, "Disabled code should be filtered out");
366 }
367}