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