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}