this repo has no description
1mod common; 2mod helpers; 3use common::*; 4use helpers::*; 5use reqwest::StatusCode; 6use serde_json::{Value, json}; 7 8#[tokio::test] 9async fn test_list_sessions_returns_current_session() { 10 let client = client(); 11 let (did, jwt) = setup_new_user("list-sessions").await; 12 let res = client 13 .get(format!( 14 "{}/xrpc/com.bspds.account.listSessions", 15 base_url().await 16 )) 17 .bearer_auth(&jwt) 18 .send() 19 .await 20 .expect("Failed to send request"); 21 assert_eq!(res.status(), StatusCode::OK); 22 let body: Value = res.json().await.unwrap(); 23 let sessions = body["sessions"].as_array().expect("sessions should be array"); 24 assert!(!sessions.is_empty(), "Should have at least one session"); 25 let current = sessions.iter().find(|s| s["isCurrent"].as_bool() == Some(true)); 26 assert!(current.is_some(), "Should have a current session marked"); 27 let session = current.unwrap(); 28 assert!(session["id"].as_str().is_some(), "Session should have id"); 29 assert!(session["createdAt"].as_str().is_some(), "Session should have createdAt"); 30 assert!(session["expiresAt"].as_str().is_some(), "Session should have expiresAt"); 31 let _ = did; 32} 33 34#[tokio::test] 35async fn test_list_sessions_multiple_sessions() { 36 let client = client(); 37 let ts = chrono::Utc::now().timestamp_millis(); 38 let handle = format!("multi-list-{}.test", ts); 39 let email = format!("multi-list-{}@test.com", ts); 40 let password = "test-password-123"; 41 let create_payload = json!({ 42 "handle": handle, 43 "email": email, 44 "password": password 45 }); 46 let create_res = client 47 .post(format!( 48 "{}/xrpc/com.atproto.server.createAccount", 49 base_url().await 50 )) 51 .json(&create_payload) 52 .send() 53 .await 54 .expect("Failed to create account"); 55 assert_eq!(create_res.status(), StatusCode::OK); 56 let create_body: Value = create_res.json().await.unwrap(); 57 let did = create_body["did"].as_str().unwrap(); 58 let jwt1 = verify_new_account(&client, did).await; 59 let login_payload = json!({ 60 "identifier": handle, 61 "password": password 62 }); 63 let login_res = client 64 .post(format!( 65 "{}/xrpc/com.atproto.server.createSession", 66 base_url().await 67 )) 68 .json(&login_payload) 69 .send() 70 .await 71 .expect("Failed to login"); 72 assert_eq!(login_res.status(), StatusCode::OK); 73 let login_body: Value = login_res.json().await.unwrap(); 74 let jwt2 = login_body["accessJwt"].as_str().unwrap(); 75 let list_res = client 76 .get(format!( 77 "{}/xrpc/com.bspds.account.listSessions", 78 base_url().await 79 )) 80 .bearer_auth(jwt2) 81 .send() 82 .await 83 .expect("Failed to list sessions"); 84 assert_eq!(list_res.status(), StatusCode::OK); 85 let list_body: Value = list_res.json().await.unwrap(); 86 let sessions = list_body["sessions"].as_array().unwrap(); 87 assert!(sessions.len() >= 2, "Should have at least 2 sessions, got {}", sessions.len()); 88 let _ = jwt1; 89} 90 91#[tokio::test] 92async fn test_list_sessions_requires_auth() { 93 let client = client(); 94 let res = client 95 .get(format!( 96 "{}/xrpc/com.bspds.account.listSessions", 97 base_url().await 98 )) 99 .send() 100 .await 101 .expect("Failed to send request"); 102 assert_eq!(res.status(), StatusCode::UNAUTHORIZED); 103} 104 105#[tokio::test] 106async fn test_revoke_session_success() { 107 let client = client(); 108 let ts = chrono::Utc::now().timestamp_millis(); 109 let handle = format!("revoke-sess-{}.test", ts); 110 let email = format!("revoke-sess-{}@test.com", ts); 111 let password = "test-password-123"; 112 let create_payload = json!({ 113 "handle": handle, 114 "email": email, 115 "password": password 116 }); 117 let create_res = client 118 .post(format!( 119 "{}/xrpc/com.atproto.server.createAccount", 120 base_url().await 121 )) 122 .json(&create_payload) 123 .send() 124 .await 125 .expect("Failed to create account"); 126 assert_eq!(create_res.status(), StatusCode::OK); 127 let create_body: Value = create_res.json().await.unwrap(); 128 let did = create_body["did"].as_str().unwrap(); 129 let jwt1 = verify_new_account(&client, did).await; 130 let login_payload = json!({ 131 "identifier": handle, 132 "password": password 133 }); 134 let login_res = client 135 .post(format!( 136 "{}/xrpc/com.atproto.server.createSession", 137 base_url().await 138 )) 139 .json(&login_payload) 140 .send() 141 .await 142 .expect("Failed to login"); 143 assert_eq!(login_res.status(), StatusCode::OK); 144 let login_body: Value = login_res.json().await.unwrap(); 145 let jwt2 = login_body["accessJwt"].as_str().unwrap(); 146 let list_res = client 147 .get(format!( 148 "{}/xrpc/com.bspds.account.listSessions", 149 base_url().await 150 )) 151 .bearer_auth(jwt2) 152 .send() 153 .await 154 .expect("Failed to list sessions"); 155 let list_body: Value = list_res.json().await.unwrap(); 156 let sessions = list_body["sessions"].as_array().unwrap(); 157 let other_session = sessions.iter().find(|s| s["isCurrent"].as_bool() != Some(true)); 158 assert!(other_session.is_some(), "Should have another session to revoke"); 159 let session_id = other_session.unwrap()["id"].as_str().unwrap(); 160 let revoke_res = client 161 .post(format!( 162 "{}/xrpc/com.bspds.account.revokeSession", 163 base_url().await 164 )) 165 .bearer_auth(jwt2) 166 .json(&json!({"sessionId": session_id})) 167 .send() 168 .await 169 .expect("Failed to revoke session"); 170 assert_eq!(revoke_res.status(), StatusCode::OK); 171 let list_after_res = client 172 .get(format!( 173 "{}/xrpc/com.bspds.account.listSessions", 174 base_url().await 175 )) 176 .bearer_auth(jwt2) 177 .send() 178 .await 179 .expect("Failed to list sessions after revoke"); 180 let list_after_body: Value = list_after_res.json().await.unwrap(); 181 let sessions_after = list_after_body["sessions"].as_array().unwrap(); 182 let revoked_still_exists = sessions_after.iter().any(|s| s["id"].as_str() == Some(session_id)); 183 assert!(!revoked_still_exists, "Revoked session should not appear in list"); 184 let _ = jwt1; 185} 186 187#[tokio::test] 188async fn test_revoke_session_invalid_id() { 189 let client = client(); 190 let (_, jwt) = setup_new_user("revoke-invalid").await; 191 let res = client 192 .post(format!( 193 "{}/xrpc/com.bspds.account.revokeSession", 194 base_url().await 195 )) 196 .bearer_auth(&jwt) 197 .json(&json!({"sessionId": "not-a-number"})) 198 .send() 199 .await 200 .expect("Failed to send request"); 201 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 202} 203 204#[tokio::test] 205async fn test_revoke_session_not_found() { 206 let client = client(); 207 let (_, jwt) = setup_new_user("revoke-notfound").await; 208 let res = client 209 .post(format!( 210 "{}/xrpc/com.bspds.account.revokeSession", 211 base_url().await 212 )) 213 .bearer_auth(&jwt) 214 .json(&json!({"sessionId": "999999999"})) 215 .send() 216 .await 217 .expect("Failed to send request"); 218 assert_eq!(res.status(), StatusCode::NOT_FOUND); 219} 220 221#[tokio::test] 222async fn test_revoke_session_requires_auth() { 223 let client = client(); 224 let res = client 225 .post(format!( 226 "{}/xrpc/com.bspds.account.revokeSession", 227 base_url().await 228 )) 229 .json(&json!({"sessionId": "1"})) 230 .send() 231 .await 232 .expect("Failed to send request"); 233 assert_eq!(res.status(), StatusCode::UNAUTHORIZED); 234}