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