this repo has no description
1mod common;
2mod helpers;
3use common::*;
4use helpers::verify_new_account;
5
6use reqwest::StatusCode;
7use serde_json::{Value, json};
8
9#[tokio::test]
10async fn test_health() {
11 let client = client();
12 let res = client
13 .get(format!("{}/health", base_url().await))
14 .send()
15 .await
16 .expect("Failed to send request");
17
18 assert_eq!(res.status(), StatusCode::OK);
19 assert_eq!(res.text().await.unwrap(), "OK");
20}
21
22#[tokio::test]
23async fn test_describe_server() {
24 let client = client();
25 let res = client
26 .get(format!(
27 "{}/xrpc/com.atproto.server.describeServer",
28 base_url().await
29 ))
30 .send()
31 .await
32 .expect("Failed to send request");
33
34 assert_eq!(res.status(), StatusCode::OK);
35 let body: Value = res.json().await.expect("Response was not valid JSON");
36 assert!(body.get("availableUserDomains").is_some());
37}
38
39#[tokio::test]
40async fn test_create_session() {
41 let client = client();
42
43 let handle = format!("user_{}", uuid::Uuid::new_v4());
44 let payload = json!({
45 "handle": handle,
46 "email": format!("{}@example.com", handle),
47 "password": "password"
48 });
49 let create_res = client
50 .post(format!(
51 "{}/xrpc/com.atproto.server.createAccount",
52 base_url().await
53 ))
54 .json(&payload)
55 .send()
56 .await
57 .expect("Failed to create account");
58
59 assert_eq!(create_res.status(), StatusCode::OK);
60 let create_body: Value = create_res.json().await.unwrap();
61 let did = create_body["did"].as_str().unwrap();
62
63 let _ = verify_new_account(&client, did).await;
64
65 let payload = json!({
66 "identifier": handle,
67 "password": "password"
68 });
69
70 let res = client
71 .post(format!(
72 "{}/xrpc/com.atproto.server.createSession",
73 base_url().await
74 ))
75 .json(&payload)
76 .send()
77 .await
78 .expect("Failed to send request");
79
80 assert_eq!(res.status(), StatusCode::OK);
81 let body: Value = res.json().await.expect("Response was not valid JSON");
82 assert!(body.get("accessJwt").is_some());
83}
84
85#[tokio::test]
86async fn test_create_session_missing_identifier() {
87 let client = client();
88 let payload = json!({
89 "password": "password"
90 });
91
92 let res = client
93 .post(format!(
94 "{}/xrpc/com.atproto.server.createSession",
95 base_url().await
96 ))
97 .json(&payload)
98 .send()
99 .await
100 .expect("Failed to send request");
101
102 assert!(
103 res.status() == StatusCode::BAD_REQUEST || res.status() == StatusCode::UNPROCESSABLE_ENTITY,
104 "Expected 400 or 422 for missing identifier, got {}",
105 res.status()
106 );
107}
108
109#[tokio::test]
110async fn test_create_account_invalid_handle() {
111 let client = client();
112 let payload = json!({
113 "handle": "invalid!handle.com",
114 "email": "test@example.com",
115 "password": "password"
116 });
117
118 let res = client
119 .post(format!(
120 "{}/xrpc/com.atproto.server.createAccount",
121 base_url().await
122 ))
123 .json(&payload)
124 .send()
125 .await
126 .expect("Failed to send request");
127
128 assert_eq!(
129 res.status(),
130 StatusCode::BAD_REQUEST,
131 "Expected 400 for invalid handle chars"
132 );
133}
134
135#[tokio::test]
136async fn test_get_session() {
137 let client = client();
138 let res = client
139 .get(format!(
140 "{}/xrpc/com.atproto.server.getSession",
141 base_url().await
142 ))
143 .bearer_auth(AUTH_TOKEN)
144 .send()
145 .await
146 .expect("Failed to send request");
147
148 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
149}
150
151#[tokio::test]
152async fn test_refresh_session() {
153 let client = client();
154
155 let handle = format!("refresh_user_{}", uuid::Uuid::new_v4());
156 let payload = json!({
157 "handle": handle,
158 "email": format!("{}@example.com", handle),
159 "password": "password"
160 });
161 let create_res = client
162 .post(format!(
163 "{}/xrpc/com.atproto.server.createAccount",
164 base_url().await
165 ))
166 .json(&payload)
167 .send()
168 .await
169 .expect("Failed to create account");
170
171 assert_eq!(create_res.status(), StatusCode::OK);
172 let create_body: Value = create_res.json().await.unwrap();
173 let did = create_body["did"].as_str().unwrap();
174
175 let _ = verify_new_account(&client, did).await;
176
177 let login_payload = json!({
178 "identifier": handle,
179 "password": "password"
180 });
181 let res = client
182 .post(format!(
183 "{}/xrpc/com.atproto.server.createSession",
184 base_url().await
185 ))
186 .json(&login_payload)
187 .send()
188 .await
189 .expect("Failed to login");
190
191 assert_eq!(res.status(), StatusCode::OK);
192 let body: Value = res.json().await.expect("Invalid JSON");
193 let refresh_jwt = body["refreshJwt"]
194 .as_str()
195 .expect("No refreshJwt")
196 .to_string();
197 let access_jwt = body["accessJwt"]
198 .as_str()
199 .expect("No accessJwt")
200 .to_string();
201
202 let res = client
203 .post(format!(
204 "{}/xrpc/com.atproto.server.refreshSession",
205 base_url().await
206 ))
207 .bearer_auth(&refresh_jwt)
208 .send()
209 .await
210 .expect("Failed to refresh");
211
212 assert_eq!(res.status(), StatusCode::OK);
213 let body: Value = res.json().await.expect("Invalid JSON");
214 assert!(body["accessJwt"].as_str().is_some());
215 assert!(body["refreshJwt"].as_str().is_some());
216 assert_ne!(body["accessJwt"].as_str().unwrap(), access_jwt);
217 assert_ne!(body["refreshJwt"].as_str().unwrap(), refresh_jwt);
218}
219
220#[tokio::test]
221async fn test_delete_session() {
222 let client = client();
223 let res = client
224 .post(format!(
225 "{}/xrpc/com.atproto.server.deleteSession",
226 base_url().await
227 ))
228 .bearer_auth(AUTH_TOKEN)
229 .send()
230 .await
231 .expect("Failed to send request");
232
233 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
234}
235
236#[tokio::test]
237async fn test_get_service_auth_success() {
238 let client = client();
239 let (access_jwt, did) = create_account_and_login(&client).await;
240
241 let params = [("aud", "did:web:example.com")];
242 let res = client
243 .get(format!(
244 "{}/xrpc/com.atproto.server.getServiceAuth",
245 base_url().await
246 ))
247 .bearer_auth(&access_jwt)
248 .query(¶ms)
249 .send()
250 .await
251 .expect("Failed to send request");
252
253 assert_eq!(res.status(), StatusCode::OK);
254 let body: Value = res.json().await.expect("Response was not valid JSON");
255 assert!(body["token"].is_string());
256
257 let token = body["token"].as_str().unwrap();
258 let parts: Vec<&str> = token.split('.').collect();
259 assert_eq!(parts.len(), 3, "Token should be a valid JWT");
260
261 use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
262 let payload_bytes = URL_SAFE_NO_PAD.decode(parts[1]).expect("payload b64");
263 let claims: Value = serde_json::from_slice(&payload_bytes).expect("payload json");
264
265 assert_eq!(claims["iss"], did);
266 assert_eq!(claims["sub"], did);
267 assert_eq!(claims["aud"], "did:web:example.com");
268}
269
270#[tokio::test]
271async fn test_get_service_auth_with_lxm() {
272 let client = client();
273 let (access_jwt, did) = create_account_and_login(&client).await;
274
275 let params = [("aud", "did:web:example.com"), ("lxm", "com.atproto.repo.getRecord")];
276 let res = client
277 .get(format!(
278 "{}/xrpc/com.atproto.server.getServiceAuth",
279 base_url().await
280 ))
281 .bearer_auth(&access_jwt)
282 .query(¶ms)
283 .send()
284 .await
285 .expect("Failed to send request");
286
287 assert_eq!(res.status(), StatusCode::OK);
288 let body: Value = res.json().await.expect("Response was not valid JSON");
289
290 use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
291 let token = body["token"].as_str().unwrap();
292 let parts: Vec<&str> = token.split('.').collect();
293 let payload_bytes = URL_SAFE_NO_PAD.decode(parts[1]).expect("payload b64");
294 let claims: Value = serde_json::from_slice(&payload_bytes).expect("payload json");
295
296 assert_eq!(claims["iss"], did);
297 assert_eq!(claims["lxm"], "com.atproto.repo.getRecord");
298}
299
300#[tokio::test]
301async fn test_get_service_auth_no_auth() {
302 let client = client();
303 let params = [("aud", "did:web:example.com")];
304 let res = client
305 .get(format!(
306 "{}/xrpc/com.atproto.server.getServiceAuth",
307 base_url().await
308 ))
309 .query(¶ms)
310 .send()
311 .await
312 .expect("Failed to send request");
313
314 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
315 let body: Value = res.json().await.expect("Response was not valid JSON");
316 assert_eq!(body["error"], "AuthenticationRequired");
317}
318
319#[tokio::test]
320async fn test_get_service_auth_missing_aud() {
321 let client = client();
322 let (access_jwt, _) = create_account_and_login(&client).await;
323
324 let res = client
325 .get(format!(
326 "{}/xrpc/com.atproto.server.getServiceAuth",
327 base_url().await
328 ))
329 .bearer_auth(&access_jwt)
330 .send()
331 .await
332 .expect("Failed to send request");
333
334 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
335}
336
337#[tokio::test]
338async fn test_check_account_status_success() {
339 let client = client();
340 let (access_jwt, _) = create_account_and_login(&client).await;
341
342 let res = client
343 .get(format!(
344 "{}/xrpc/com.atproto.server.checkAccountStatus",
345 base_url().await
346 ))
347 .bearer_auth(&access_jwt)
348 .send()
349 .await
350 .expect("Failed to send request");
351
352 assert_eq!(res.status(), StatusCode::OK);
353 let body: Value = res.json().await.expect("Response was not valid JSON");
354 assert_eq!(body["activated"], true);
355 assert_eq!(body["validDid"], true);
356 assert!(body["repoCommit"].is_string());
357 assert!(body["repoRev"].is_string());
358 assert!(body["indexedRecords"].is_number());
359}
360
361#[tokio::test]
362async fn test_check_account_status_no_auth() {
363 let client = client();
364 let res = client
365 .get(format!(
366 "{}/xrpc/com.atproto.server.checkAccountStatus",
367 base_url().await
368 ))
369 .send()
370 .await
371 .expect("Failed to send request");
372
373 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
374 let body: Value = res.json().await.expect("Response was not valid JSON");
375 assert_eq!(body["error"], "AuthenticationRequired");
376}
377
378#[tokio::test]
379async fn test_activate_account_success() {
380 let client = client();
381 let (access_jwt, _) = create_account_and_login(&client).await;
382
383 let res = client
384 .post(format!(
385 "{}/xrpc/com.atproto.server.activateAccount",
386 base_url().await
387 ))
388 .bearer_auth(&access_jwt)
389 .send()
390 .await
391 .expect("Failed to send request");
392
393 assert_eq!(res.status(), StatusCode::OK);
394}
395
396#[tokio::test]
397async fn test_activate_account_no_auth() {
398 let client = client();
399 let res = client
400 .post(format!(
401 "{}/xrpc/com.atproto.server.activateAccount",
402 base_url().await
403 ))
404 .send()
405 .await
406 .expect("Failed to send request");
407
408 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
409}
410
411#[tokio::test]
412async fn test_deactivate_account_success() {
413 let client = client();
414 let (access_jwt, _) = create_account_and_login(&client).await;
415
416 let res = client
417 .post(format!(
418 "{}/xrpc/com.atproto.server.deactivateAccount",
419 base_url().await
420 ))
421 .bearer_auth(&access_jwt)
422 .json(&json!({}))
423 .send()
424 .await
425 .expect("Failed to send request");
426
427 assert_eq!(res.status(), StatusCode::OK);
428}