this repo has no description
1mod common;
2use common::*;
3use reqwest::StatusCode;
4use reqwest::header;
5use serde_json::Value;
6use chrono;
7
8#[tokio::test]
9async fn test_get_latest_commit_success() {
10 let client = client();
11 let (_, did) = create_account_and_login(&client).await;
12
13 let params = [("did", did.as_str())];
14 let res = client
15 .get(format!(
16 "{}/xrpc/com.atproto.sync.getLatestCommit",
17 base_url().await
18 ))
19 .query(¶ms)
20 .send()
21 .await
22 .expect("Failed to send request");
23
24 assert_eq!(res.status(), StatusCode::OK);
25 let body: Value = res.json().await.expect("Response was not valid JSON");
26 assert!(body["cid"].is_string());
27 assert!(body["rev"].is_string());
28}
29
30#[tokio::test]
31async fn test_get_latest_commit_not_found() {
32 let client = client();
33 let params = [("did", "did:plc:nonexistent12345")];
34 let res = client
35 .get(format!(
36 "{}/xrpc/com.atproto.sync.getLatestCommit",
37 base_url().await
38 ))
39 .query(¶ms)
40 .send()
41 .await
42 .expect("Failed to send request");
43
44 assert_eq!(res.status(), StatusCode::NOT_FOUND);
45 let body: Value = res.json().await.expect("Response was not valid JSON");
46 assert_eq!(body["error"], "RepoNotFound");
47}
48
49#[tokio::test]
50async fn test_get_latest_commit_missing_param() {
51 let client = client();
52 let res = client
53 .get(format!(
54 "{}/xrpc/com.atproto.sync.getLatestCommit",
55 base_url().await
56 ))
57 .send()
58 .await
59 .expect("Failed to send request");
60
61 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
62}
63
64#[tokio::test]
65async fn test_list_repos() {
66 let client = client();
67 let _ = create_account_and_login(&client).await;
68
69 let res = client
70 .get(format!(
71 "{}/xrpc/com.atproto.sync.listRepos",
72 base_url().await
73 ))
74 .send()
75 .await
76 .expect("Failed to send request");
77
78 assert_eq!(res.status(), StatusCode::OK);
79 let body: Value = res.json().await.expect("Response was not valid JSON");
80 assert!(body["repos"].is_array());
81 let repos = body["repos"].as_array().unwrap();
82 assert!(!repos.is_empty());
83
84 let repo = &repos[0];
85 assert!(repo["did"].is_string());
86 assert!(repo["head"].is_string());
87 assert!(repo["active"].is_boolean());
88}
89
90#[tokio::test]
91async fn test_list_repos_with_limit() {
92 let client = client();
93 let _ = create_account_and_login(&client).await;
94 let _ = create_account_and_login(&client).await;
95 let _ = create_account_and_login(&client).await;
96
97 let params = [("limit", "2")];
98 let res = client
99 .get(format!(
100 "{}/xrpc/com.atproto.sync.listRepos",
101 base_url().await
102 ))
103 .query(¶ms)
104 .send()
105 .await
106 .expect("Failed to send request");
107
108 assert_eq!(res.status(), StatusCode::OK);
109 let body: Value = res.json().await.expect("Response was not valid JSON");
110 let repos = body["repos"].as_array().unwrap();
111 assert!(repos.len() <= 2);
112}
113
114#[tokio::test]
115async fn test_list_repos_pagination() {
116 let client = client();
117 let _ = create_account_and_login(&client).await;
118 let _ = create_account_and_login(&client).await;
119 let _ = create_account_and_login(&client).await;
120
121 let params = [("limit", "1")];
122 let res = client
123 .get(format!(
124 "{}/xrpc/com.atproto.sync.listRepos",
125 base_url().await
126 ))
127 .query(¶ms)
128 .send()
129 .await
130 .expect("Failed to send request");
131
132 assert_eq!(res.status(), StatusCode::OK);
133 let body: Value = res.json().await.expect("Response was not valid JSON");
134 let repos = body["repos"].as_array().unwrap();
135 assert_eq!(repos.len(), 1);
136
137 if let Some(cursor) = body["cursor"].as_str() {
138 let params = [("limit", "1"), ("cursor", cursor)];
139 let res = client
140 .get(format!(
141 "{}/xrpc/com.atproto.sync.listRepos",
142 base_url().await
143 ))
144 .query(¶ms)
145 .send()
146 .await
147 .expect("Failed to send request");
148
149 assert_eq!(res.status(), StatusCode::OK);
150 let body: Value = res.json().await.expect("Response was not valid JSON");
151 let repos2 = body["repos"].as_array().unwrap();
152 assert_eq!(repos2.len(), 1);
153 assert_ne!(repos[0]["did"], repos2[0]["did"]);
154 }
155}
156
157#[tokio::test]
158async fn test_get_repo_status_success() {
159 let client = client();
160 let (_, did) = create_account_and_login(&client).await;
161
162 let params = [("did", did.as_str())];
163 let res = client
164 .get(format!(
165 "{}/xrpc/com.atproto.sync.getRepoStatus",
166 base_url().await
167 ))
168 .query(¶ms)
169 .send()
170 .await
171 .expect("Failed to send request");
172
173 assert_eq!(res.status(), StatusCode::OK);
174 let body: Value = res.json().await.expect("Response was not valid JSON");
175 assert_eq!(body["did"], did);
176 assert_eq!(body["active"], true);
177 assert!(body["rev"].is_string());
178}
179
180#[tokio::test]
181async fn test_get_repo_status_not_found() {
182 let client = client();
183 let params = [("did", "did:plc:nonexistent12345")];
184 let res = client
185 .get(format!(
186 "{}/xrpc/com.atproto.sync.getRepoStatus",
187 base_url().await
188 ))
189 .query(¶ms)
190 .send()
191 .await
192 .expect("Failed to send request");
193
194 assert_eq!(res.status(), StatusCode::NOT_FOUND);
195 let body: Value = res.json().await.expect("Response was not valid JSON");
196 assert_eq!(body["error"], "RepoNotFound");
197}
198
199#[tokio::test]
200async fn test_list_blobs_success() {
201 let client = client();
202 let (access_jwt, did) = create_account_and_login(&client).await;
203
204 let blob_res = client
205 .post(format!(
206 "{}/xrpc/com.atproto.repo.uploadBlob",
207 base_url().await
208 ))
209 .header(header::CONTENT_TYPE, "text/plain")
210 .bearer_auth(&access_jwt)
211 .body("test blob content")
212 .send()
213 .await
214 .expect("Failed to upload blob");
215
216 assert_eq!(blob_res.status(), StatusCode::OK);
217
218 let params = [("did", did.as_str())];
219 let res = client
220 .get(format!(
221 "{}/xrpc/com.atproto.sync.listBlobs",
222 base_url().await
223 ))
224 .query(¶ms)
225 .send()
226 .await
227 .expect("Failed to send request");
228
229 assert_eq!(res.status(), StatusCode::OK);
230 let body: Value = res.json().await.expect("Response was not valid JSON");
231 assert!(body["cids"].is_array());
232 let cids = body["cids"].as_array().unwrap();
233 assert!(!cids.is_empty());
234}
235
236#[tokio::test]
237async fn test_list_blobs_not_found() {
238 let client = client();
239 let params = [("did", "did:plc:nonexistent12345")];
240 let res = client
241 .get(format!(
242 "{}/xrpc/com.atproto.sync.listBlobs",
243 base_url().await
244 ))
245 .query(¶ms)
246 .send()
247 .await
248 .expect("Failed to send request");
249
250 assert_eq!(res.status(), StatusCode::NOT_FOUND);
251 let body: Value = res.json().await.expect("Response was not valid JSON");
252 assert_eq!(body["error"], "RepoNotFound");
253}
254
255#[tokio::test]
256async fn test_get_blob_success() {
257 let client = client();
258 let (access_jwt, did) = create_account_and_login(&client).await;
259
260 let blob_content = "test blob for get_blob";
261 let blob_res = client
262 .post(format!(
263 "{}/xrpc/com.atproto.repo.uploadBlob",
264 base_url().await
265 ))
266 .header(header::CONTENT_TYPE, "text/plain")
267 .bearer_auth(&access_jwt)
268 .body(blob_content)
269 .send()
270 .await
271 .expect("Failed to upload blob");
272
273 assert_eq!(blob_res.status(), StatusCode::OK);
274 let blob_body: Value = blob_res.json().await.expect("Response was not valid JSON");
275 let cid = blob_body["blob"]["ref"]["$link"].as_str().expect("No CID");
276
277 let params = [("did", did.as_str()), ("cid", cid)];
278 let res = client
279 .get(format!(
280 "{}/xrpc/com.atproto.sync.getBlob",
281 base_url().await
282 ))
283 .query(¶ms)
284 .send()
285 .await
286 .expect("Failed to send request");
287
288 assert_eq!(res.status(), StatusCode::OK);
289 assert_eq!(
290 res.headers()
291 .get("content-type")
292 .and_then(|h| h.to_str().ok()),
293 Some("text/plain")
294 );
295 let body = res.text().await.expect("Failed to get body");
296 assert_eq!(body, blob_content);
297}
298
299#[tokio::test]
300async fn test_get_blob_not_found() {
301 let client = client();
302 let (_, did) = create_account_and_login(&client).await;
303
304 let params = [
305 ("did", did.as_str()),
306 ("cid", "bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"),
307 ];
308 let res = client
309 .get(format!(
310 "{}/xrpc/com.atproto.sync.getBlob",
311 base_url().await
312 ))
313 .query(¶ms)
314 .send()
315 .await
316 .expect("Failed to send request");
317
318 assert_eq!(res.status(), StatusCode::NOT_FOUND);
319 let body: Value = res.json().await.expect("Response was not valid JSON");
320 assert_eq!(body["error"], "BlobNotFound");
321}
322
323#[tokio::test]
324async fn test_notify_of_update() {
325 let client = client();
326 let params = [("hostname", "example.com")];
327 let res = client
328 .post(format!(
329 "{}/xrpc/com.atproto.sync.notifyOfUpdate",
330 base_url().await
331 ))
332 .query(¶ms)
333 .send()
334 .await
335 .expect("Failed to send request");
336
337 assert_eq!(res.status(), StatusCode::OK);
338}
339
340#[tokio::test]
341async fn test_request_crawl() {
342 let client = client();
343 let payload = serde_json::json!({"hostname": "example.com"});
344 let res = client
345 .post(format!(
346 "{}/xrpc/com.atproto.sync.requestCrawl",
347 base_url().await
348 ))
349 .json(&payload)
350 .send()
351 .await
352 .expect("Failed to send request");
353
354 assert_eq!(res.status(), StatusCode::OK);
355}
356
357#[tokio::test]
358async fn test_get_repo_success() {
359 let client = client();
360 let (access_jwt, did) = create_account_and_login(&client).await;
361
362 let post_payload = serde_json::json!({
363 "repo": did,
364 "collection": "app.bsky.feed.post",
365 "record": {
366 "$type": "app.bsky.feed.post",
367 "text": "Test post for getRepo",
368 "createdAt": chrono::Utc::now().to_rfc3339()
369 }
370 });
371 let _ = client
372 .post(format!(
373 "{}/xrpc/com.atproto.repo.createRecord",
374 base_url().await
375 ))
376 .bearer_auth(&access_jwt)
377 .json(&post_payload)
378 .send()
379 .await
380 .expect("Failed to create record");
381
382 let params = [("did", did.as_str())];
383 let res = client
384 .get(format!(
385 "{}/xrpc/com.atproto.sync.getRepo",
386 base_url().await
387 ))
388 .query(¶ms)
389 .send()
390 .await
391 .expect("Failed to send request");
392
393 assert_eq!(res.status(), StatusCode::OK);
394 assert_eq!(
395 res.headers()
396 .get("content-type")
397 .and_then(|h| h.to_str().ok()),
398 Some("application/vnd.ipld.car")
399 );
400 let body = res.bytes().await.expect("Failed to get body");
401 assert!(!body.is_empty());
402}
403
404#[tokio::test]
405async fn test_get_repo_not_found() {
406 let client = client();
407 let params = [("did", "did:plc:nonexistent12345")];
408 let res = client
409 .get(format!(
410 "{}/xrpc/com.atproto.sync.getRepo",
411 base_url().await
412 ))
413 .query(¶ms)
414 .send()
415 .await
416 .expect("Failed to send request");
417
418 assert_eq!(res.status(), StatusCode::NOT_FOUND);
419 let body: Value = res.json().await.expect("Response was not valid JSON");
420 assert_eq!(body["error"], "RepoNotFound");
421}
422
423#[tokio::test]
424async fn test_get_record_sync_success() {
425 let client = client();
426 let (access_jwt, did) = create_account_and_login(&client).await;
427
428 let post_payload = serde_json::json!({
429 "repo": did,
430 "collection": "app.bsky.feed.post",
431 "record": {
432 "$type": "app.bsky.feed.post",
433 "text": "Test post for sync getRecord",
434 "createdAt": chrono::Utc::now().to_rfc3339()
435 }
436 });
437 let create_res = client
438 .post(format!(
439 "{}/xrpc/com.atproto.repo.createRecord",
440 base_url().await
441 ))
442 .bearer_auth(&access_jwt)
443 .json(&post_payload)
444 .send()
445 .await
446 .expect("Failed to create record");
447
448 let create_body: Value = create_res.json().await.expect("Invalid JSON");
449 let uri = create_body["uri"].as_str().expect("No URI");
450 let rkey = uri.split('/').last().expect("Invalid URI");
451
452 let params = [
453 ("did", did.as_str()),
454 ("collection", "app.bsky.feed.post"),
455 ("rkey", rkey),
456 ];
457 let res = client
458 .get(format!(
459 "{}/xrpc/com.atproto.sync.getRecord",
460 base_url().await
461 ))
462 .query(¶ms)
463 .send()
464 .await
465 .expect("Failed to send request");
466
467 assert_eq!(res.status(), StatusCode::OK);
468 assert_eq!(
469 res.headers()
470 .get("content-type")
471 .and_then(|h| h.to_str().ok()),
472 Some("application/vnd.ipld.car")
473 );
474 let body = res.bytes().await.expect("Failed to get body");
475 assert!(!body.is_empty());
476}
477
478#[tokio::test]
479async fn test_get_record_sync_not_found() {
480 let client = client();
481 let (_, did) = create_account_and_login(&client).await;
482
483 let params = [
484 ("did", did.as_str()),
485 ("collection", "app.bsky.feed.post"),
486 ("rkey", "nonexistent12345"),
487 ];
488 let res = client
489 .get(format!(
490 "{}/xrpc/com.atproto.sync.getRecord",
491 base_url().await
492 ))
493 .query(¶ms)
494 .send()
495 .await
496 .expect("Failed to send request");
497
498 assert_eq!(res.status(), StatusCode::NOT_FOUND);
499 let body: Value = res.json().await.expect("Response was not valid JSON");
500 assert_eq!(body["error"], "RecordNotFound");
501}
502
503#[tokio::test]
504async fn test_get_blocks_success() {
505 let client = client();
506 let (_, did) = create_account_and_login(&client).await;
507
508 let params = [("did", did.as_str())];
509 let latest_res = client
510 .get(format!(
511 "{}/xrpc/com.atproto.sync.getLatestCommit",
512 base_url().await
513 ))
514 .query(¶ms)
515 .send()
516 .await
517 .expect("Failed to get latest commit");
518
519 let latest_body: Value = latest_res.json().await.expect("Invalid JSON");
520 let root_cid = latest_body["cid"].as_str().expect("No CID");
521
522 let url = format!(
523 "{}/xrpc/com.atproto.sync.getBlocks?did={}&cids={}",
524 base_url().await,
525 did,
526 root_cid
527 );
528 let res = client
529 .get(&url)
530 .send()
531 .await
532 .expect("Failed to send request");
533
534 assert_eq!(res.status(), StatusCode::OK);
535 assert_eq!(
536 res.headers()
537 .get("content-type")
538 .and_then(|h| h.to_str().ok()),
539 Some("application/vnd.ipld.car")
540 );
541}
542
543#[tokio::test]
544async fn test_get_blocks_not_found() {
545 let client = client();
546 let url = format!(
547 "{}/xrpc/com.atproto.sync.getBlocks?did=did:plc:nonexistent12345&cids=bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku",
548 base_url().await
549 );
550 let res = client
551 .get(&url)
552 .send()
553 .await
554 .expect("Failed to send request");
555
556 assert_eq!(res.status(), StatusCode::NOT_FOUND);
557}