this repo has no description
1mod common; 2mod helpers; 3use common::*; 4use helpers::*; 5use reqwest::StatusCode; 6use serde_json::Value; 7#[tokio::test] 8async fn test_get_head_success() { 9 let client = client(); 10 let (did, _jwt) = setup_new_user("gethead-success").await; 11 let res = client 12 .get(format!( 13 "{}/xrpc/com.atproto.sync.getHead", 14 base_url().await 15 )) 16 .query(&[("did", did.as_str())]) 17 .send() 18 .await 19 .expect("Failed to send request"); 20 assert_eq!(res.status(), StatusCode::OK); 21 let body: Value = res.json().await.expect("Response was not valid JSON"); 22 assert!(body["root"].is_string()); 23 let root = body["root"].as_str().unwrap(); 24 assert!(root.starts_with("bafy"), "Root CID should be a CID"); 25} 26#[tokio::test] 27async fn test_get_head_not_found() { 28 let client = client(); 29 let res = client 30 .get(format!( 31 "{}/xrpc/com.atproto.sync.getHead", 32 base_url().await 33 )) 34 .query(&[("did", "did:plc:nonexistent12345")]) 35 .send() 36 .await 37 .expect("Failed to send request"); 38 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 39 let body: Value = res.json().await.expect("Response was not valid JSON"); 40 assert_eq!(body["error"], "HeadNotFound"); 41 assert!(body["message"].as_str().unwrap().contains("Could not find root")); 42} 43#[tokio::test] 44async fn test_get_head_missing_param() { 45 let client = client(); 46 let res = client 47 .get(format!( 48 "{}/xrpc/com.atproto.sync.getHead", 49 base_url().await 50 )) 51 .send() 52 .await 53 .expect("Failed to send request"); 54 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 55} 56#[tokio::test] 57async fn test_get_head_empty_did() { 58 let client = client(); 59 let res = client 60 .get(format!( 61 "{}/xrpc/com.atproto.sync.getHead", 62 base_url().await 63 )) 64 .query(&[("did", "")]) 65 .send() 66 .await 67 .expect("Failed to send request"); 68 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 69 let body: Value = res.json().await.expect("Response was not valid JSON"); 70 assert_eq!(body["error"], "InvalidRequest"); 71} 72#[tokio::test] 73async fn test_get_head_whitespace_did() { 74 let client = client(); 75 let res = client 76 .get(format!( 77 "{}/xrpc/com.atproto.sync.getHead", 78 base_url().await 79 )) 80 .query(&[("did", " ")]) 81 .send() 82 .await 83 .expect("Failed to send request"); 84 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 85} 86#[tokio::test] 87async fn test_get_head_changes_after_record_create() { 88 let client = client(); 89 let (did, jwt) = setup_new_user("gethead-changes").await; 90 let res1 = client 91 .get(format!( 92 "{}/xrpc/com.atproto.sync.getHead", 93 base_url().await 94 )) 95 .query(&[("did", did.as_str())]) 96 .send() 97 .await 98 .expect("Failed to get initial head"); 99 let body1: Value = res1.json().await.unwrap(); 100 let head1 = body1["root"].as_str().unwrap().to_string(); 101 create_post(&client, &did, &jwt, "Post to change head").await; 102 let res2 = client 103 .get(format!( 104 "{}/xrpc/com.atproto.sync.getHead", 105 base_url().await 106 )) 107 .query(&[("did", did.as_str())]) 108 .send() 109 .await 110 .expect("Failed to get head after record"); 111 let body2: Value = res2.json().await.unwrap(); 112 let head2 = body2["root"].as_str().unwrap().to_string(); 113 assert_ne!(head1, head2, "Head CID should change after record creation"); 114} 115#[tokio::test] 116async fn test_get_checkout_success() { 117 let client = client(); 118 let (did, jwt) = setup_new_user("getcheckout-success").await; 119 create_post(&client, &did, &jwt, "Post for checkout test").await; 120 let res = client 121 .get(format!( 122 "{}/xrpc/com.atproto.sync.getCheckout", 123 base_url().await 124 )) 125 .query(&[("did", did.as_str())]) 126 .send() 127 .await 128 .expect("Failed to send request"); 129 assert_eq!(res.status(), StatusCode::OK); 130 assert_eq!( 131 res.headers() 132 .get("content-type") 133 .and_then(|h| h.to_str().ok()), 134 Some("application/vnd.ipld.car") 135 ); 136 let body = res.bytes().await.expect("Failed to get body"); 137 assert!(!body.is_empty(), "CAR file should not be empty"); 138 assert!(body.len() > 50, "CAR file should contain actual data"); 139} 140#[tokio::test] 141async fn test_get_checkout_not_found() { 142 let client = client(); 143 let res = client 144 .get(format!( 145 "{}/xrpc/com.atproto.sync.getCheckout", 146 base_url().await 147 )) 148 .query(&[("did", "did:plc:nonexistent12345")]) 149 .send() 150 .await 151 .expect("Failed to send request"); 152 assert_eq!(res.status(), StatusCode::NOT_FOUND); 153 let body: Value = res.json().await.expect("Response was not valid JSON"); 154 assert_eq!(body["error"], "RepoNotFound"); 155} 156#[tokio::test] 157async fn test_get_checkout_missing_param() { 158 let client = client(); 159 let res = client 160 .get(format!( 161 "{}/xrpc/com.atproto.sync.getCheckout", 162 base_url().await 163 )) 164 .send() 165 .await 166 .expect("Failed to send request"); 167 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 168} 169#[tokio::test] 170async fn test_get_checkout_empty_did() { 171 let client = client(); 172 let res = client 173 .get(format!( 174 "{}/xrpc/com.atproto.sync.getCheckout", 175 base_url().await 176 )) 177 .query(&[("did", "")]) 178 .send() 179 .await 180 .expect("Failed to send request"); 181 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 182} 183#[tokio::test] 184async fn test_get_checkout_empty_repo() { 185 let client = client(); 186 let (did, _jwt) = setup_new_user("getcheckout-empty").await; 187 let res = client 188 .get(format!( 189 "{}/xrpc/com.atproto.sync.getCheckout", 190 base_url().await 191 )) 192 .query(&[("did", did.as_str())]) 193 .send() 194 .await 195 .expect("Failed to send request"); 196 assert_eq!(res.status(), StatusCode::OK); 197 let body = res.bytes().await.expect("Failed to get body"); 198 assert!(!body.is_empty(), "Even empty repo should return CAR header"); 199} 200#[tokio::test] 201async fn test_get_checkout_includes_multiple_records() { 202 let client = client(); 203 let (did, jwt) = setup_new_user("getcheckout-multi").await; 204 for i in 0..5 { 205 tokio::time::sleep(std::time::Duration::from_millis(50)).await; 206 create_post(&client, &did, &jwt, &format!("Checkout post {}", i)).await; 207 } 208 let res = client 209 .get(format!( 210 "{}/xrpc/com.atproto.sync.getCheckout", 211 base_url().await 212 )) 213 .query(&[("did", did.as_str())]) 214 .send() 215 .await 216 .expect("Failed to send request"); 217 assert_eq!(res.status(), StatusCode::OK); 218 let body = res.bytes().await.expect("Failed to get body"); 219 assert!(body.len() > 500, "CAR file with 5 records should be larger"); 220} 221#[tokio::test] 222async fn test_get_head_matches_latest_commit() { 223 let client = client(); 224 let (did, _jwt) = setup_new_user("gethead-matches-latest").await; 225 let head_res = client 226 .get(format!( 227 "{}/xrpc/com.atproto.sync.getHead", 228 base_url().await 229 )) 230 .query(&[("did", did.as_str())]) 231 .send() 232 .await 233 .expect("Failed to get head"); 234 let head_body: Value = head_res.json().await.unwrap(); 235 let head_root = head_body["root"].as_str().unwrap(); 236 let latest_res = client 237 .get(format!( 238 "{}/xrpc/com.atproto.sync.getLatestCommit", 239 base_url().await 240 )) 241 .query(&[("did", did.as_str())]) 242 .send() 243 .await 244 .expect("Failed to get latest commit"); 245 let latest_body: Value = latest_res.json().await.unwrap(); 246 let latest_cid = latest_body["cid"].as_str().unwrap(); 247 assert_eq!(head_root, latest_cid, "getHead root should match getLatestCommit cid"); 248} 249#[tokio::test] 250async fn test_get_checkout_car_header_valid() { 251 let client = client(); 252 let (did, _jwt) = setup_new_user("getcheckout-header").await; 253 let res = client 254 .get(format!( 255 "{}/xrpc/com.atproto.sync.getCheckout", 256 base_url().await 257 )) 258 .query(&[("did", did.as_str())]) 259 .send() 260 .await 261 .expect("Failed to send request"); 262 assert_eq!(res.status(), StatusCode::OK); 263 let body = res.bytes().await.expect("Failed to get body"); 264 assert!(body.len() >= 2, "CAR file should have at least header length"); 265}