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}