this repo has no description
1mod common;
2use common::*;
3
4use chrono::Utc;
5use reqwest::{StatusCode, header};
6use serde_json::{Value, json};
7
8#[tokio::test]
9#[ignore]
10async fn test_get_record() {
11 let client = client();
12 let params = [
13 ("repo", "did:plc:12345"),
14 ("collection", "app.bsky.actor.profile"),
15 ("rkey", "self"),
16 ];
17
18 let res = client
19 .get(format!(
20 "{}/xrpc/com.atproto.repo.getRecord",
21 base_url().await
22 ))
23 .query(¶ms)
24 .send()
25 .await
26 .expect("Failed to send request");
27
28 assert_eq!(res.status(), StatusCode::OK);
29 let body: Value = res.json().await.expect("Response was not valid JSON");
30 assert_eq!(body["value"]["$type"], "app.bsky.actor.profile");
31}
32
33#[tokio::test]
34#[ignore]
35async fn test_get_record_not_found() {
36 let client = client();
37 let params = [
38 ("repo", "did:plc:12345"),
39 ("collection", "app.bsky.feed.post"),
40 ("rkey", "nonexistent"),
41 ];
42
43 let res = client
44 .get(format!(
45 "{}/xrpc/com.atproto.repo.getRecord",
46 base_url().await
47 ))
48 .query(¶ms)
49 .send()
50 .await
51 .expect("Failed to send request");
52
53 assert_eq!(res.status(), StatusCode::NOT_FOUND);
54 let body: Value = res.json().await.expect("Response was not valid JSON");
55 assert_eq!(body["error"], "NotFound");
56}
57
58#[tokio::test]
59async fn test_upload_blob_no_auth() {
60 let client = client();
61 let res = client
62 .post(format!(
63 "{}/xrpc/com.atproto.repo.uploadBlob",
64 base_url().await
65 ))
66 .header(header::CONTENT_TYPE, "text/plain")
67 .body("no auth")
68 .send()
69 .await
70 .expect("Failed to send request");
71
72 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
73 let body: Value = res.json().await.expect("Response was not valid JSON");
74 assert_eq!(body["error"], "AuthenticationRequired");
75}
76
77#[tokio::test]
78async fn test_upload_blob_success() {
79 let client = client();
80 let (token, _) = create_account_and_login(&client).await;
81 let res = client
82 .post(format!(
83 "{}/xrpc/com.atproto.repo.uploadBlob",
84 base_url().await
85 ))
86 .header(header::CONTENT_TYPE, "text/plain")
87 .bearer_auth(token)
88 .body("This is our blob data")
89 .send()
90 .await
91 .expect("Failed to send request");
92
93 assert_eq!(res.status(), StatusCode::OK);
94 let body: Value = res.json().await.expect("Response was not valid JSON");
95 assert!(body["blob"]["ref"]["$link"].as_str().is_some());
96}
97
98#[tokio::test]
99#[ignore]
100async fn test_put_record_no_auth() {
101 let client = client();
102 let payload = json!({
103 "repo": "did:plc:123",
104 "collection": "app.bsky.feed.post",
105 "rkey": "fake",
106 "record": {}
107 });
108
109 let res = client
110 .post(format!(
111 "{}/xrpc/com.atproto.repo.putRecord",
112 base_url().await
113 ))
114 .json(&payload)
115 .send()
116 .await
117 .expect("Failed to send request");
118
119 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
120 let body: Value = res.json().await.expect("Response was not valid JSON");
121 assert_eq!(body["error"], "AuthenticationFailed");
122}
123
124#[tokio::test]
125#[ignore]
126async fn test_put_record_success() {
127 let client = client();
128 let (token, did) = create_account_and_login(&client).await;
129 let now = Utc::now().to_rfc3339();
130 let payload = json!({
131 "repo": did,
132 "collection": "app.bsky.feed.post",
133 "rkey": "e2e_test_post",
134 "record": {
135 "$type": "app.bsky.feed.post",
136 "text": "Hello from the e2e test script!",
137 "createdAt": now
138 }
139 });
140
141 let res = client
142 .post(format!(
143 "{}/xrpc/com.atproto.repo.putRecord",
144 base_url().await
145 ))
146 .bearer_auth(token)
147 .json(&payload)
148 .send()
149 .await
150 .expect("Failed to send request");
151
152 assert_eq!(res.status(), StatusCode::OK);
153 let body: Value = res.json().await.expect("Response was not valid JSON");
154 assert!(body.get("uri").is_some());
155 assert!(body.get("cid").is_some());
156}
157
158#[tokio::test]
159#[ignore]
160async fn test_get_record_missing_params() {
161 let client = client();
162 let params = [("repo", "did:plc:12345")];
163
164 let res = client
165 .get(format!(
166 "{}/xrpc/com.atproto.repo.getRecord",
167 base_url().await
168 ))
169 .query(¶ms)
170 .send()
171 .await
172 .expect("Failed to send request");
173
174 assert_eq!(
175 res.status(),
176 StatusCode::BAD_REQUEST,
177 "Expected 400 for missing params"
178 );
179}
180
181#[tokio::test]
182async fn test_upload_blob_bad_token() {
183 let client = client();
184 let res = client
185 .post(format!(
186 "{}/xrpc/com.atproto.repo.uploadBlob",
187 base_url().await
188 ))
189 .header(header::CONTENT_TYPE, "text/plain")
190 .bearer_auth(BAD_AUTH_TOKEN)
191 .body("This is our blob data")
192 .send()
193 .await
194 .expect("Failed to send request");
195
196 assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
197 let body: Value = res.json().await.expect("Response was not valid JSON");
198 assert_eq!(body["error"], "AuthenticationFailed");
199}
200
201#[tokio::test]
202#[ignore]
203async fn test_put_record_mismatched_repo() {
204 let client = client();
205 let (token, _) = create_account_and_login(&client).await;
206 let now = Utc::now().to_rfc3339();
207 let payload = json!({
208 "repo": "did:plc:OTHER-USER", // This does NOT match AUTH_DID
209 "collection": "app.bsky.feed.post",
210 "rkey": "e2e_test_post",
211 "record": {
212 "$type": "app.bsky.feed.post",
213 "text": "Hello from the e2e test script!",
214 "createdAt": now
215 }
216 });
217
218 let res = client
219 .post(format!(
220 "{}/xrpc/com.atproto.repo.putRecord",
221 base_url().await
222 ))
223 .bearer_auth(token)
224 .json(&payload)
225 .send()
226 .await
227 .expect("Failed to send request");
228
229 assert_eq!(
230 res.status(),
231 StatusCode::FORBIDDEN,
232 "Expected 403 for mismatched repo and auth"
233 );
234}
235
236#[tokio::test]
237#[ignore]
238async fn test_put_record_invalid_schema() {
239 let client = client();
240 let (token, did) = create_account_and_login(&client).await;
241 let now = Utc::now().to_rfc3339();
242 let payload = json!({
243 "repo": did,
244 "collection": "app.bsky.feed.post",
245 "rkey": "e2e_test_invalid",
246 "record": {
247 "$type": "app.bsky.feed.post",
248 "createdAt": now
249 }
250 });
251
252 let res = client
253 .post(format!(
254 "{}/xrpc/com.atproto.repo.putRecord",
255 base_url().await
256 ))
257 .bearer_auth(token)
258 .json(&payload)
259 .send()
260 .await
261 .expect("Failed to send request");
262
263 assert_eq!(
264 res.status(),
265 StatusCode::BAD_REQUEST,
266 "Expected 400 for invalid record schema"
267 );
268}
269
270#[tokio::test]
271async fn test_upload_blob_unsupported_mime_type() {
272 let client = client();
273 let (token, _) = create_account_and_login(&client).await;
274 let res = client
275 .post(format!(
276 "{}/xrpc/com.atproto.repo.uploadBlob",
277 base_url().await
278 ))
279 .header(header::CONTENT_TYPE, "application/xml")
280 .bearer_auth(token)
281 .body("<xml>not an image</xml>")
282 .send()
283 .await
284 .expect("Failed to send request");
285
286 // Changed expectation to OK for now, bc we don't validate mime type strictly yet.
287 assert_eq!(res.status(), StatusCode::OK);
288}
289
290#[tokio::test]
291async fn test_list_records() {
292 let client = client();
293 let (_, did) = create_account_and_login(&client).await;
294 let params = [
295 ("repo", did.as_str()),
296 ("collection", "app.bsky.feed.post"),
297 ("limit", "10"),
298 ];
299 let res = client
300 .get(format!(
301 "{}/xrpc/com.atproto.repo.listRecords",
302 base_url().await
303 ))
304 .query(¶ms)
305 .send()
306 .await
307 .expect("Failed to send request");
308
309 assert_eq!(res.status(), StatusCode::OK);
310}
311
312#[tokio::test]
313async fn test_describe_repo() {
314 let client = client();
315 let (_, did) = create_account_and_login(&client).await;
316 let params = [("repo", did.as_str())];
317 let res = client
318 .get(format!(
319 "{}/xrpc/com.atproto.repo.describeRepo",
320 base_url().await
321 ))
322 .query(¶ms)
323 .send()
324 .await
325 .expect("Failed to send request");
326
327 assert_eq!(res.status(), StatusCode::OK);
328}
329
330#[tokio::test]
331#[ignore]
332async fn test_create_record_success_with_generated_rkey() {
333 let client = client();
334 let (token, did) = create_account_and_login(&client).await;
335 let payload = json!({
336 "repo": did,
337 "collection": "app.bsky.feed.post",
338 "record": {
339 "$type": "app.bsky.feed.post",
340 "text": "Hello, world!",
341 "createdAt": "2025-12-02T12:00:00Z"
342 }
343 });
344
345 let res = client
346 .post(format!(
347 "{}/xrpc/com.atproto.repo.createRecord",
348 base_url().await
349 ))
350 .json(&payload)
351 .bearer_auth(token)
352 .send()
353 .await
354 .expect("Failed to send request");
355
356 assert_eq!(res.status(), StatusCode::OK);
357 let body: Value = res.json().await.expect("Response was not valid JSON");
358 let uri = body["uri"].as_str().unwrap();
359 assert!(uri.starts_with(&format!("at://{}/app.bsky.feed.post/", did)));
360 // assert_eq!(body["cid"], "bafyreihy");
361}
362
363#[tokio::test]
364#[ignore]
365async fn test_create_record_success_with_provided_rkey() {
366 let client = client();
367 let (token, did) = create_account_and_login(&client).await;
368 let rkey = "custom-rkey";
369 let payload = json!({
370 "repo": did,
371 "collection": "app.bsky.feed.post",
372 "rkey": rkey,
373 "record": {
374 "$type": "app.bsky.feed.post",
375 "text": "Hello, world!",
376 "createdAt": "2025-12-02T12:00:00Z"
377 }
378 });
379
380 let res = client
381 .post(format!(
382 "{}/xrpc/com.atproto.repo.createRecord",
383 base_url().await
384 ))
385 .json(&payload)
386 .bearer_auth(token)
387 .send()
388 .await
389 .expect("Failed to send request");
390
391 assert_eq!(res.status(), StatusCode::OK);
392 let body: Value = res.json().await.expect("Response was not valid JSON");
393 assert_eq!(
394 body["uri"],
395 format!("at://{}/app.bsky.feed.post/{}", did, rkey)
396 );
397 // assert_eq!(body["cid"], "bafyreihy");
398}
399
400#[tokio::test]
401#[ignore]
402async fn test_delete_record() {
403 let client = client();
404 let (token, did) = create_account_and_login(&client).await;
405 let payload = json!({
406 "repo": did,
407 "collection": "app.bsky.feed.post",
408 "rkey": "some_post_to_delete"
409 });
410 let res = client
411 .post(format!(
412 "{}/xrpc/com.atproto.repo.deleteRecord",
413 base_url().await
414 ))
415 .bearer_auth(token)
416 .json(&payload)
417 .send()
418 .await
419 .expect("Failed to send request");
420
421 assert_eq!(res.status(), StatusCode::OK);
422}