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