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