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}