this repo has no description
1mod common; 2mod helpers; 3 4use common::*; 5use reqwest::{StatusCode, header}; 6use serde_json::{Value, json}; 7 8#[tokio::test] 9async fn test_list_backups_empty() { 10 let client = client(); 11 let (token, _did) = create_account_and_login(&client).await; 12 13 let res = client 14 .get(format!("{}/xrpc/_backup.listBackups", base_url().await)) 15 .bearer_auth(&token) 16 .send() 17 .await 18 .expect("listBackups request failed"); 19 20 assert_eq!(res.status(), StatusCode::OK); 21 let body: Value = res.json().await.expect("Invalid JSON"); 22 assert!(body["backups"].is_array()); 23 assert_eq!(body["backups"].as_array().unwrap().len(), 0); 24 assert!(body["backupEnabled"].as_bool().unwrap_or(false)); 25} 26 27#[tokio::test] 28async fn test_create_and_list_backup() { 29 let client = client(); 30 let (token, _did) = create_account_and_login(&client).await; 31 32 let create_res = client 33 .post(format!("{}/xrpc/_backup.createBackup", base_url().await)) 34 .bearer_auth(&token) 35 .send() 36 .await 37 .expect("createBackup request failed"); 38 39 assert_eq!(create_res.status(), StatusCode::OK, "createBackup failed"); 40 let create_body: Value = create_res.json().await.expect("Invalid JSON"); 41 assert!(create_body["id"].is_string()); 42 assert!(create_body["repoRev"].is_string()); 43 assert!(create_body["sizeBytes"].is_i64()); 44 assert!(create_body["blockCount"].is_i64()); 45 46 let list_res = client 47 .get(format!("{}/xrpc/_backup.listBackups", base_url().await)) 48 .bearer_auth(&token) 49 .send() 50 .await 51 .expect("listBackups request failed"); 52 53 assert_eq!(list_res.status(), StatusCode::OK); 54 let list_body: Value = list_res.json().await.expect("Invalid JSON"); 55 let backups = list_body["backups"].as_array().unwrap(); 56 assert!(!backups.is_empty()); 57} 58 59#[tokio::test] 60async fn test_download_backup() { 61 let client = client(); 62 let (token, _did) = create_account_and_login(&client).await; 63 64 let create_res = client 65 .post(format!("{}/xrpc/_backup.createBackup", base_url().await)) 66 .bearer_auth(&token) 67 .send() 68 .await 69 .expect("createBackup request failed"); 70 71 assert_eq!(create_res.status(), StatusCode::OK); 72 let create_body: Value = create_res.json().await.expect("Invalid JSON"); 73 let backup_id = create_body["id"].as_str().unwrap(); 74 75 let get_res = client 76 .get(format!( 77 "{}/xrpc/_backup.getBackup?id={}", 78 base_url().await, 79 backup_id 80 )) 81 .bearer_auth(&token) 82 .send() 83 .await 84 .expect("getBackup request failed"); 85 86 assert_eq!(get_res.status(), StatusCode::OK); 87 let content_type = get_res.headers().get(header::CONTENT_TYPE).unwrap(); 88 assert_eq!(content_type, "application/vnd.ipld.car"); 89 90 let bytes = get_res.bytes().await.expect("Failed to read body"); 91 assert!(bytes.len() > 100, "CAR file should have content"); 92 assert_eq!( 93 bytes[1], 0xa2, 94 "CAR file should have valid header structure" 95 ); 96} 97 98#[tokio::test] 99async fn test_delete_backup() { 100 let client = client(); 101 let (token, _did) = create_account_and_login(&client).await; 102 103 let create_res = client 104 .post(format!("{}/xrpc/_backup.createBackup", base_url().await)) 105 .bearer_auth(&token) 106 .send() 107 .await 108 .expect("createBackup request failed"); 109 110 assert_eq!(create_res.status(), StatusCode::OK); 111 let create_body: Value = create_res.json().await.expect("Invalid JSON"); 112 let backup_id = create_body["id"].as_str().unwrap(); 113 114 let delete_res = client 115 .post(format!( 116 "{}/xrpc/_backup.deleteBackup?id={}", 117 base_url().await, 118 backup_id 119 )) 120 .bearer_auth(&token) 121 .send() 122 .await 123 .expect("deleteBackup request failed"); 124 125 assert_eq!(delete_res.status(), StatusCode::OK); 126 127 let get_res = client 128 .get(format!( 129 "{}/xrpc/_backup.getBackup?id={}", 130 base_url().await, 131 backup_id 132 )) 133 .bearer_auth(&token) 134 .send() 135 .await 136 .expect("getBackup request failed"); 137 138 assert_eq!(get_res.status(), StatusCode::NOT_FOUND); 139} 140 141#[tokio::test] 142async fn test_toggle_backup_enabled() { 143 let client = client(); 144 let (token, _did) = create_account_and_login(&client).await; 145 146 let list_res = client 147 .get(format!("{}/xrpc/_backup.listBackups", base_url().await)) 148 .bearer_auth(&token) 149 .send() 150 .await 151 .expect("listBackups request failed"); 152 153 assert_eq!(list_res.status(), StatusCode::OK); 154 let list_body: Value = list_res.json().await.expect("Invalid JSON"); 155 assert!(list_body["backupEnabled"].as_bool().unwrap()); 156 157 let disable_res = client 158 .post(format!("{}/xrpc/_backup.setEnabled", base_url().await)) 159 .bearer_auth(&token) 160 .json(&json!({"enabled": false})) 161 .send() 162 .await 163 .expect("setEnabled request failed"); 164 165 assert_eq!(disable_res.status(), StatusCode::OK); 166 let disable_body: Value = disable_res.json().await.expect("Invalid JSON"); 167 assert!(!disable_body["enabled"].as_bool().unwrap()); 168 169 let list_res2 = client 170 .get(format!("{}/xrpc/_backup.listBackups", base_url().await)) 171 .bearer_auth(&token) 172 .send() 173 .await 174 .expect("listBackups request failed"); 175 176 let list_body2: Value = list_res2.json().await.expect("Invalid JSON"); 177 assert!(!list_body2["backupEnabled"].as_bool().unwrap()); 178 179 let enable_res = client 180 .post(format!("{}/xrpc/_backup.setEnabled", base_url().await)) 181 .bearer_auth(&token) 182 .json(&json!({"enabled": true})) 183 .send() 184 .await 185 .expect("setEnabled request failed"); 186 187 assert_eq!(enable_res.status(), StatusCode::OK); 188} 189 190#[tokio::test] 191async fn test_backup_includes_blobs() { 192 let client = client(); 193 let (token, did) = create_account_and_login(&client).await; 194 195 let blob_data = b"Hello, this is test blob data for backup testing!"; 196 let upload_res = client 197 .post(format!( 198 "{}/xrpc/com.atproto.repo.uploadBlob", 199 base_url().await 200 )) 201 .header(header::CONTENT_TYPE, "text/plain") 202 .bearer_auth(&token) 203 .body(blob_data.to_vec()) 204 .send() 205 .await 206 .expect("uploadBlob request failed"); 207 208 assert_eq!(upload_res.status(), StatusCode::OK); 209 let upload_body: Value = upload_res.json().await.expect("Invalid JSON"); 210 let blob = &upload_body["blob"]; 211 212 let record = json!({ 213 "$type": "app.bsky.feed.post", 214 "text": "Test post with blob", 215 "createdAt": chrono::Utc::now().to_rfc3339(), 216 "embed": { 217 "$type": "app.bsky.embed.images", 218 "images": [{ 219 "alt": "test image", 220 "image": blob 221 }] 222 } 223 }); 224 225 let create_record_res = client 226 .post(format!( 227 "{}/xrpc/com.atproto.repo.createRecord", 228 base_url().await 229 )) 230 .bearer_auth(&token) 231 .json(&json!({ 232 "repo": did, 233 "collection": "app.bsky.feed.post", 234 "record": record 235 })) 236 .send() 237 .await 238 .expect("createRecord request failed"); 239 240 assert_eq!(create_record_res.status(), StatusCode::OK); 241 242 let create_backup_res = client 243 .post(format!("{}/xrpc/_backup.createBackup", base_url().await)) 244 .bearer_auth(&token) 245 .send() 246 .await 247 .expect("createBackup request failed"); 248 249 assert_eq!(create_backup_res.status(), StatusCode::OK); 250 let backup_body: Value = create_backup_res.json().await.expect("Invalid JSON"); 251 let backup_id = backup_body["id"].as_str().unwrap(); 252 253 let get_backup_res = client 254 .get(format!( 255 "{}/xrpc/_backup.getBackup?id={}", 256 base_url().await, 257 backup_id 258 )) 259 .bearer_auth(&token) 260 .send() 261 .await 262 .expect("getBackup request failed"); 263 264 assert_eq!(get_backup_res.status(), StatusCode::OK); 265 let car_bytes = get_backup_res.bytes().await.expect("Failed to read body"); 266 267 let blob_cid = blob["ref"]["$link"].as_str().unwrap(); 268 let blob_found = String::from_utf8_lossy(&car_bytes).contains("Hello, this is test blob data"); 269 assert!( 270 blob_found || car_bytes.len() > 500, 271 "Backup should contain blob data (cid: {})", 272 blob_cid 273 ); 274} 275 276#[tokio::test] 277async fn test_backup_unauthorized() { 278 let client = client(); 279 280 let res = client 281 .get(format!("{}/xrpc/_backup.listBackups", base_url().await)) 282 .send() 283 .await 284 .expect("listBackups request failed"); 285 286 assert_eq!(res.status(), StatusCode::UNAUTHORIZED); 287} 288 289#[tokio::test] 290async fn test_get_nonexistent_backup() { 291 let client = client(); 292 let (token, _did) = create_account_and_login(&client).await; 293 294 let fake_id = uuid::Uuid::new_v4(); 295 let res = client 296 .get(format!( 297 "{}/xrpc/_backup.getBackup?id={}", 298 base_url().await, 299 fake_id 300 )) 301 .bearer_auth(&token) 302 .send() 303 .await 304 .expect("getBackup request failed"); 305 306 assert_eq!(res.status(), StatusCode::NOT_FOUND); 307} 308 309#[tokio::test] 310async fn test_backup_invalid_id() { 311 let client = client(); 312 let (token, _did) = create_account_and_login(&client).await; 313 314 let res = client 315 .get(format!( 316 "{}/xrpc/_backup.getBackup?id=not-a-uuid", 317 base_url().await 318 )) 319 .bearer_auth(&token) 320 .send() 321 .await 322 .expect("getBackup request failed"); 323 324 assert_eq!(res.status(), StatusCode::BAD_REQUEST); 325}