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_get_head_comprehensive() { 10 let client = client(); 11 let (did, jwt) = setup_new_user("gethead").await; 12 let res = client 13 .get(format!( 14 "{}/xrpc/com.atproto.sync.getHead", 15 base_url().await 16 )) 17 .query(&[("did", did.as_str())]) 18 .send() 19 .await 20 .expect("Failed to send request"); 21 assert_eq!(res.status(), StatusCode::OK); 22 let body: Value = res.json().await.expect("Response was not valid JSON"); 23 assert!(body["root"].is_string()); 24 let root1 = body["root"].as_str().unwrap().to_string(); 25 assert!(root1.starts_with("bafy"), "Root CID should be a CID"); 26 let latest_res = client 27 .get(format!( 28 "{}/xrpc/com.atproto.sync.getLatestCommit", 29 base_url().await 30 )) 31 .query(&[("did", did.as_str())]) 32 .send() 33 .await 34 .expect("Failed to get latest commit"); 35 let latest_body: Value = latest_res.json().await.unwrap(); 36 let latest_cid = latest_body["cid"].as_str().unwrap(); 37 assert_eq!( 38 root1, latest_cid, 39 "getHead root should match getLatestCommit cid" 40 ); 41 create_post(&client, &did, &jwt, "Post to change head").await; 42 let res2 = client 43 .get(format!( 44 "{}/xrpc/com.atproto.sync.getHead", 45 base_url().await 46 )) 47 .query(&[("did", did.as_str())]) 48 .send() 49 .await 50 .expect("Failed to get head after record"); 51 let body2: Value = res2.json().await.unwrap(); 52 let root2 = body2["root"].as_str().unwrap().to_string(); 53 assert_ne!(root1, root2, "Head CID should change after record creation"); 54 let not_found_res = client 55 .get(format!( 56 "{}/xrpc/com.atproto.sync.getHead", 57 base_url().await 58 )) 59 .query(&[("did", "did:plc:nonexistent12345")]) 60 .send() 61 .await 62 .expect("Failed to send request"); 63 assert_eq!(not_found_res.status(), StatusCode::BAD_REQUEST); 64 let error_body: Value = not_found_res.json().await.unwrap(); 65 assert_eq!(error_body["error"], "HeadNotFound"); 66 let missing_res = client 67 .get(format!( 68 "{}/xrpc/com.atproto.sync.getHead", 69 base_url().await 70 )) 71 .send() 72 .await 73 .expect("Failed to send request"); 74 assert_eq!(missing_res.status(), StatusCode::BAD_REQUEST); 75 let empty_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!(empty_res.status(), StatusCode::BAD_REQUEST); 85 let whitespace_res = client 86 .get(format!( 87 "{}/xrpc/com.atproto.sync.getHead", 88 base_url().await 89 )) 90 .query(&[("did", " ")]) 91 .send() 92 .await 93 .expect("Failed to send request"); 94 assert_eq!(whitespace_res.status(), StatusCode::BAD_REQUEST); 95} 96 97#[tokio::test] 98async fn test_get_checkout_comprehensive() { 99 let client = client(); 100 let (did, jwt) = setup_new_user("getcheckout").await; 101 let empty_res = client 102 .get(format!( 103 "{}/xrpc/com.atproto.sync.getCheckout", 104 base_url().await 105 )) 106 .query(&[("did", did.as_str())]) 107 .send() 108 .await 109 .expect("Failed to send request"); 110 assert_eq!(empty_res.status(), StatusCode::OK); 111 let empty_body = empty_res.bytes().await.expect("Failed to get body"); 112 assert!( 113 !empty_body.is_empty(), 114 "Even empty repo should return CAR header" 115 ); 116 create_post(&client, &did, &jwt, "Post for checkout test").await; 117 let res = client 118 .get(format!( 119 "{}/xrpc/com.atproto.sync.getCheckout", 120 base_url().await 121 )) 122 .query(&[("did", did.as_str())]) 123 .send() 124 .await 125 .expect("Failed to send request"); 126 assert_eq!(res.status(), StatusCode::OK); 127 assert_eq!( 128 res.headers() 129 .get("content-type") 130 .and_then(|h| h.to_str().ok()), 131 Some("application/vnd.ipld.car") 132 ); 133 let body = res.bytes().await.expect("Failed to get body"); 134 assert!(!body.is_empty(), "CAR file should not be empty"); 135 assert!(body.len() > 50, "CAR file should contain actual data"); 136 assert!( 137 body.len() >= 2, 138 "CAR file should have at least header length" 139 ); 140 for i in 0..4 { 141 tokio::time::sleep(std::time::Duration::from_millis(100)).await; 142 create_post(&client, &did, &jwt, &format!("Checkout post {}", i)).await; 143 } 144 let multi_res = client 145 .get(format!( 146 "{}/xrpc/com.atproto.sync.getCheckout", 147 base_url().await 148 )) 149 .query(&[("did", did.as_str())]) 150 .send() 151 .await 152 .expect("Failed to send request"); 153 assert_eq!(multi_res.status(), StatusCode::OK); 154 let multi_body = multi_res.bytes().await.expect("Failed to get body"); 155 assert!( 156 multi_body.len() > 500, 157 "CAR file with 5 records should be larger" 158 ); 159 let not_found_res = client 160 .get(format!( 161 "{}/xrpc/com.atproto.sync.getCheckout", 162 base_url().await 163 )) 164 .query(&[("did", "did:plc:nonexistent12345")]) 165 .send() 166 .await 167 .expect("Failed to send request"); 168 assert_eq!(not_found_res.status(), StatusCode::NOT_FOUND); 169 let error_body: Value = not_found_res.json().await.unwrap(); 170 assert_eq!(error_body["error"], "RepoNotFound"); 171 let missing_res = client 172 .get(format!( 173 "{}/xrpc/com.atproto.sync.getCheckout", 174 base_url().await 175 )) 176 .send() 177 .await 178 .expect("Failed to send request"); 179 assert_eq!(missing_res.status(), StatusCode::BAD_REQUEST); 180 let empty_did_res = client 181 .get(format!( 182 "{}/xrpc/com.atproto.sync.getCheckout", 183 base_url().await 184 )) 185 .query(&[("did", "")]) 186 .send() 187 .await 188 .expect("Failed to send request"); 189 assert_eq!(empty_did_res.status(), StatusCode::BAD_REQUEST); 190}