this repo has no description
1mod common;
2mod helpers;
3use common::*;
4use helpers::*;
5use reqwest::StatusCode;
6use serde_json::Value;
7
8#[tokio::test]
9async fn test_search_accounts_as_admin() {
10 let client = client();
11 let (admin_jwt, _) = create_admin_account_and_login(&client).await;
12 let (user_did, _) = setup_new_user("search-target").await;
13 let res = client
14 .get(format!(
15 "{}/xrpc/com.atproto.admin.searchAccounts?limit=1000",
16 base_url().await
17 ))
18 .bearer_auth(&admin_jwt)
19 .send()
20 .await
21 .expect("Failed to send request");
22 assert_eq!(res.status(), StatusCode::OK);
23 let body: Value = res.json().await.unwrap();
24 let accounts = body["accounts"]
25 .as_array()
26 .expect("accounts should be array");
27 assert!(!accounts.is_empty(), "Should return some accounts");
28 let found = accounts
29 .iter()
30 .any(|a| a["did"].as_str() == Some(&user_did));
31 assert!(
32 found,
33 "Should find the created user in results (DID: {})",
34 user_did
35 );
36}
37
38#[tokio::test]
39async fn test_search_accounts_with_handle_filter() {
40 let client = client();
41 let (admin_jwt, _) = create_admin_account_and_login(&client).await;
42 let ts = chrono::Utc::now().timestamp_millis();
43 let unique_handle = format!("unique-handle-{}.test", ts);
44 let create_payload = serde_json::json!({
45 "handle": unique_handle,
46 "email": format!("unique-{}@searchtest.com", ts),
47 "password": "test-password-123"
48 });
49 let create_res = client
50 .post(format!(
51 "{}/xrpc/com.atproto.server.createAccount",
52 base_url().await
53 ))
54 .json(&create_payload)
55 .send()
56 .await
57 .expect("Failed to create account");
58 assert_eq!(create_res.status(), StatusCode::OK);
59 let res = client
60 .get(format!(
61 "{}/xrpc/com.atproto.admin.searchAccounts?handle={}",
62 base_url().await,
63 unique_handle
64 ))
65 .bearer_auth(&admin_jwt)
66 .send()
67 .await
68 .expect("Failed to send request");
69 assert_eq!(res.status(), StatusCode::OK);
70 let body: Value = res.json().await.unwrap();
71 let accounts = body["accounts"].as_array().unwrap();
72 assert_eq!(
73 accounts.len(),
74 1,
75 "Should find exactly one account with this handle"
76 );
77 assert_eq!(accounts[0]["handle"].as_str(), Some(unique_handle.as_str()));
78}
79
80#[tokio::test]
81async fn test_search_accounts_pagination() {
82 let client = client();
83 let (admin_jwt, _) = create_admin_account_and_login(&client).await;
84 for i in 0..3 {
85 let _ = setup_new_user(&format!("search-page-{}", i)).await;
86 }
87 let res = client
88 .get(format!(
89 "{}/xrpc/com.atproto.admin.searchAccounts?limit=2",
90 base_url().await
91 ))
92 .bearer_auth(&admin_jwt)
93 .send()
94 .await
95 .expect("Failed to send request");
96 assert_eq!(res.status(), StatusCode::OK);
97 let body: Value = res.json().await.unwrap();
98 let accounts = body["accounts"].as_array().unwrap();
99 assert_eq!(accounts.len(), 2, "Should return exactly 2 accounts");
100 let cursor = body["cursor"].as_str();
101 assert!(cursor.is_some(), "Should have cursor for more results");
102 let res2 = client
103 .get(format!(
104 "{}/xrpc/com.atproto.admin.searchAccounts?limit=2&cursor={}",
105 base_url().await,
106 cursor.unwrap()
107 ))
108 .bearer_auth(&admin_jwt)
109 .send()
110 .await
111 .expect("Failed to send request");
112 assert_eq!(res2.status(), StatusCode::OK);
113 let body2: Value = res2.json().await.unwrap();
114 let accounts2 = body2["accounts"].as_array().unwrap();
115 assert!(
116 !accounts2.is_empty(),
117 "Should return more accounts after cursor"
118 );
119 let first_page_dids: Vec<&str> = accounts
120 .iter()
121 .map(|a| a["did"].as_str().unwrap())
122 .collect();
123 let second_page_dids: Vec<&str> = accounts2
124 .iter()
125 .map(|a| a["did"].as_str().unwrap())
126 .collect();
127 for did in &second_page_dids {
128 assert!(
129 !first_page_dids.contains(did),
130 "Second page should not repeat first page DIDs"
131 );
132 }
133}
134
135#[tokio::test]
136async fn test_search_accounts_requires_admin() {
137 let client = client();
138 let _ = create_account_and_login(&client).await;
139 let (_, user_jwt) = setup_new_user("search-nonadmin").await;
140 let res = client
141 .get(format!(
142 "{}/xrpc/com.atproto.admin.searchAccounts",
143 base_url().await
144 ))
145 .bearer_auth(&user_jwt)
146 .send()
147 .await
148 .expect("Failed to send request");
149 assert_eq!(res.status(), StatusCode::FORBIDDEN);
150}
151
152#[tokio::test]
153async fn test_search_accounts_requires_auth() {
154 let client = client();
155 let res = client
156 .get(format!(
157 "{}/xrpc/com.atproto.admin.searchAccounts",
158 base_url().await
159 ))
160 .send()
161 .await
162 .expect("Failed to send request");
163 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
164}
165
166#[tokio::test]
167async fn test_search_accounts_returns_expected_fields() {
168 let client = client();
169 let (admin_jwt, _) = create_admin_account_and_login(&client).await;
170 let _ = setup_new_user("search-fields").await;
171 let res = client
172 .get(format!(
173 "{}/xrpc/com.atproto.admin.searchAccounts?limit=1",
174 base_url().await
175 ))
176 .bearer_auth(&admin_jwt)
177 .send()
178 .await
179 .expect("Failed to send request");
180 assert_eq!(res.status(), StatusCode::OK);
181 let body: Value = res.json().await.unwrap();
182 let accounts = body["accounts"].as_array().unwrap();
183 assert!(!accounts.is_empty());
184 let account = &accounts[0];
185 assert!(account["did"].as_str().is_some(), "Should have did");
186 assert!(account["handle"].as_str().is_some(), "Should have handle");
187 assert!(
188 account["indexedAt"].as_str().is_some(),
189 "Should have indexedAt"
190 );
191}