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_server_basics() {
10 let client = client();
11 let base = base_url().await;
12 let health = client.get(format!("{}/health", base)).send().await.unwrap();
13 assert_eq!(health.status(), StatusCode::OK);
14 assert_eq!(health.text().await.unwrap(), "OK");
15 let describe = client.get(format!("{}/xrpc/com.atproto.server.describeServer", base)).send().await.unwrap();
16 assert_eq!(describe.status(), StatusCode::OK);
17 let body: Value = describe.json().await.unwrap();
18 assert!(body.get("availableUserDomains").is_some());
19}
20
21#[tokio::test]
22async fn test_account_and_session_lifecycle() {
23 let client = client();
24 let base = base_url().await;
25 let handle = format!("user_{}", uuid::Uuid::new_v4());
26 let payload = json!({ "handle": handle, "email": format!("{}@example.com", handle), "password": "password" });
27 let create_res = client.post(format!("{}/xrpc/com.atproto.server.createAccount", base))
28 .json(&payload).send().await.unwrap();
29 assert_eq!(create_res.status(), StatusCode::OK);
30 let create_body: Value = create_res.json().await.unwrap();
31 let did = create_body["did"].as_str().unwrap();
32 let _ = verify_new_account(&client, did).await;
33 let login = client.post(format!("{}/xrpc/com.atproto.server.createSession", base))
34 .json(&json!({ "identifier": handle, "password": "password" })).send().await.unwrap();
35 assert_eq!(login.status(), StatusCode::OK);
36 let login_body: Value = login.json().await.unwrap();
37 let access_jwt = login_body["accessJwt"].as_str().unwrap().to_string();
38 let refresh_jwt = login_body["refreshJwt"].as_str().unwrap().to_string();
39 let refresh = client.post(format!("{}/xrpc/com.atproto.server.refreshSession", base))
40 .bearer_auth(&refresh_jwt).send().await.unwrap();
41 assert_eq!(refresh.status(), StatusCode::OK);
42 let refresh_body: Value = refresh.json().await.unwrap();
43 assert!(refresh_body["accessJwt"].as_str().is_some());
44 assert_ne!(refresh_body["accessJwt"].as_str().unwrap(), access_jwt);
45 assert_ne!(refresh_body["refreshJwt"].as_str().unwrap(), refresh_jwt);
46 let missing_id = client.post(format!("{}/xrpc/com.atproto.server.createSession", base))
47 .json(&json!({ "password": "password" })).send().await.unwrap();
48 assert!(missing_id.status() == StatusCode::BAD_REQUEST || missing_id.status() == StatusCode::UNPROCESSABLE_ENTITY);
49 let invalid_handle = client.post(format!("{}/xrpc/com.atproto.server.createAccount", base))
50 .json(&json!({ "handle": "invalid!handle.com", "email": "test@example.com", "password": "password" }))
51 .send().await.unwrap();
52 assert_eq!(invalid_handle.status(), StatusCode::BAD_REQUEST);
53 let unauth_session = client.get(format!("{}/xrpc/com.atproto.server.getSession", base))
54 .bearer_auth(AUTH_TOKEN).send().await.unwrap();
55 assert_eq!(unauth_session.status(), StatusCode::UNAUTHORIZED);
56 let delete_session = client.post(format!("{}/xrpc/com.atproto.server.deleteSession", base))
57 .bearer_auth(AUTH_TOKEN).send().await.unwrap();
58 assert_eq!(delete_session.status(), StatusCode::UNAUTHORIZED);
59}
60
61#[tokio::test]
62async fn test_service_auth() {
63 let client = client();
64 let base = base_url().await;
65 let (access_jwt, did) = create_account_and_login(&client).await;
66 let res = client.get(format!("{}/xrpc/com.atproto.server.getServiceAuth", base))
67 .bearer_auth(&access_jwt).query(&[("aud", "did:web:example.com")]).send().await.unwrap();
68 assert_eq!(res.status(), StatusCode::OK);
69 let body: Value = res.json().await.unwrap();
70 let token = body["token"].as_str().unwrap();
71 let parts: Vec<&str> = token.split('.').collect();
72 assert_eq!(parts.len(), 3, "Token should be a valid JWT");
73 use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
74 let payload_bytes = URL_SAFE_NO_PAD.decode(parts[1]).unwrap();
75 let claims: Value = serde_json::from_slice(&payload_bytes).unwrap();
76 assert_eq!(claims["iss"], did);
77 assert_eq!(claims["sub"], did);
78 assert_eq!(claims["aud"], "did:web:example.com");
79 let lxm_res = client.get(format!("{}/xrpc/com.atproto.server.getServiceAuth", base))
80 .bearer_auth(&access_jwt).query(&[("aud", "did:web:example.com"), ("lxm", "com.atproto.repo.getRecord")])
81 .send().await.unwrap();
82 assert_eq!(lxm_res.status(), StatusCode::OK);
83 let lxm_body: Value = lxm_res.json().await.unwrap();
84 let lxm_token = lxm_body["token"].as_str().unwrap();
85 let lxm_parts: Vec<&str> = lxm_token.split('.').collect();
86 let lxm_payload = URL_SAFE_NO_PAD.decode(lxm_parts[1]).unwrap();
87 let lxm_claims: Value = serde_json::from_slice(&lxm_payload).unwrap();
88 assert_eq!(lxm_claims["lxm"], "com.atproto.repo.getRecord");
89 let unauth = client.get(format!("{}/xrpc/com.atproto.server.getServiceAuth", base))
90 .query(&[("aud", "did:web:example.com")]).send().await.unwrap();
91 assert_eq!(unauth.status(), StatusCode::UNAUTHORIZED);
92 let missing_aud = client.get(format!("{}/xrpc/com.atproto.server.getServiceAuth", base))
93 .bearer_auth(&access_jwt).send().await.unwrap();
94 assert_eq!(missing_aud.status(), StatusCode::BAD_REQUEST);
95}
96
97#[tokio::test]
98async fn test_account_status_and_activation() {
99 let client = client();
100 let base = base_url().await;
101 let (access_jwt, _) = create_account_and_login(&client).await;
102 let status = client.get(format!("{}/xrpc/com.atproto.server.checkAccountStatus", base))
103 .bearer_auth(&access_jwt).send().await.unwrap();
104 assert_eq!(status.status(), StatusCode::OK);
105 let body: Value = status.json().await.unwrap();
106 assert_eq!(body["activated"], true);
107 assert_eq!(body["validDid"], true);
108 assert!(body["repoCommit"].is_string());
109 assert!(body["repoRev"].is_string());
110 assert!(body["indexedRecords"].is_number());
111 let unauth_status = client.get(format!("{}/xrpc/com.atproto.server.checkAccountStatus", base))
112 .send().await.unwrap();
113 assert_eq!(unauth_status.status(), StatusCode::UNAUTHORIZED);
114 let activate = client.post(format!("{}/xrpc/com.atproto.server.activateAccount", base))
115 .bearer_auth(&access_jwt).send().await.unwrap();
116 assert_eq!(activate.status(), StatusCode::OK);
117 let unauth_activate = client.post(format!("{}/xrpc/com.atproto.server.activateAccount", base))
118 .send().await.unwrap();
119 assert_eq!(unauth_activate.status(), StatusCode::UNAUTHORIZED);
120 let deactivate = client.post(format!("{}/xrpc/com.atproto.server.deactivateAccount", base))
121 .bearer_auth(&access_jwt).json(&json!({})).send().await.unwrap();
122 assert_eq!(deactivate.status(), StatusCode::OK);
123}