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