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