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}