this repo has no description
1mod common;
2use common::*;
3use reqwest::StatusCode;
4use serde_json::{Value, json};
5use wiremock::matchers::{method, path};
6use wiremock::{Mock, MockServer, ResponseTemplate};
7
8// #[tokio::test]
9// async fn test_resolve_handle() {
10// let client = client();
11// let params = [
12// ("handle", "bsky.app"),
13// ];
14// let res = client.get(format!("{}/xrpc/com.atproto.identity.resolveHandle", base_url().await))
15// .query(¶ms)
16// .send()
17// .await
18// .expect("Failed to send request");
19//
20// assert_eq!(res.status(), StatusCode::OK);
21// }
22
23#[tokio::test]
24async fn test_well_known_did() {
25 let client = client();
26 let res = client
27 .get(format!("{}/.well-known/did.json", base_url().await))
28 .send()
29 .await
30 .expect("Failed to send request");
31
32 assert_eq!(res.status(), StatusCode::OK);
33 let body: Value = res.json().await.expect("Response was not valid JSON");
34 assert!(body["id"].as_str().unwrap().starts_with("did:web:"));
35 assert_eq!(body["service"][0]["type"], "AtprotoPersonalDataServer");
36}
37
38#[tokio::test]
39async fn test_create_did_web_account_and_resolve() {
40 let client = client();
41
42 let mock_server = MockServer::start().await;
43 let mock_uri = mock_server.uri();
44 let mock_addr = mock_uri.trim_start_matches("http://");
45
46 let did = format!("did:web:{}", mock_addr.replace(":", "%3A"));
47
48 let handle = format!("webuser_{}", uuid::Uuid::new_v4());
49
50 let pds_endpoint = "https://localhost";
51
52 let did_doc = json!({
53 "@context": ["https://www.w3.org/ns/did/v1"],
54 "id": did,
55 "service": [{
56 "id": "#atproto_pds",
57 "type": "AtprotoPersonalDataServer",
58 "serviceEndpoint": pds_endpoint
59 }]
60 });
61
62 Mock::given(method("GET"))
63 .and(path("/.well-known/did.json"))
64 .respond_with(ResponseTemplate::new(200).set_body_json(did_doc))
65 .mount(&mock_server)
66 .await;
67
68 let payload = json!({
69 "handle": handle,
70 "email": format!("{}@example.com", handle),
71 "password": "password",
72 "did": did
73 });
74
75 let res = client
76 .post(format!(
77 "{}/xrpc/com.atproto.server.createAccount",
78 base_url().await
79 ))
80 .json(&payload)
81 .send()
82 .await
83 .expect("Failed to send request");
84
85 if res.status() != StatusCode::OK {
86 let status = res.status();
87 let body: Value = res
88 .json()
89 .await
90 .unwrap_or(json!({"error": "could not parse body"}));
91 panic!("createAccount failed with status {}: {:?}", status, body);
92 }
93 let body: Value = res
94 .json()
95 .await
96 .expect("createAccount response was not JSON");
97 assert_eq!(body["did"], did);
98
99 let res = client
100 .get(format!("{}/u/{}/did.json", base_url().await, handle))
101 .send()
102 .await
103 .expect("Failed to fetch DID doc");
104
105 assert_eq!(res.status(), StatusCode::OK);
106 let doc: Value = res.json().await.expect("DID doc was not JSON");
107
108 assert_eq!(doc["id"], did);
109 assert_eq!(doc["alsoKnownAs"][0], format!("at://{}", handle));
110 assert_eq!(doc["verificationMethod"][0]["controller"], did);
111 assert!(doc["verificationMethod"][0]["publicKeyJwk"].is_object());
112}
113
114#[tokio::test]
115async fn test_create_account_duplicate_handle() {
116 let client = client();
117 let handle = format!("dupe_{}", uuid::Uuid::new_v4());
118 let email = format!("{}@example.com", handle);
119
120 let payload = json!({
121 "handle": handle,
122 "email": email,
123 "password": "password"
124 });
125
126 let res = client
127 .post(format!(
128 "{}/xrpc/com.atproto.server.createAccount",
129 base_url().await
130 ))
131 .json(&payload)
132 .send()
133 .await
134 .expect("Failed to send request");
135 assert_eq!(res.status(), StatusCode::OK);
136
137 let res = client
138 .post(format!(
139 "{}/xrpc/com.atproto.server.createAccount",
140 base_url().await
141 ))
142 .json(&payload)
143 .send()
144 .await
145 .expect("Failed to send request");
146
147 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
148 let body: Value = res.json().await.expect("Response was not JSON");
149 assert_eq!(body["error"], "HandleTaken");
150}
151
152#[tokio::test]
153async fn test_did_web_lifecycle() {
154 let client = client();
155 let handle = format!("lifecycle_{}", uuid::Uuid::new_v4());
156 let did = format!("did:web:localhost:u:{}", handle);
157 let email = format!("{}@test.com", handle);
158
159 let create_payload = json!({
160 "handle": handle,
161 "email": email,
162 "password": "password",
163 "did": did
164 });
165
166 let res = client
167 .post(format!(
168 "{}/xrpc/com.atproto.server.createAccount",
169 base_url().await
170 ))
171 .json(&create_payload)
172 .send()
173 .await
174 .expect("Failed createAccount");
175
176 if res.status() != StatusCode::OK {
177 let body: Value = res.json().await.unwrap();
178 println!("createAccount failed: {:?}", body);
179 panic!("createAccount returned non-200");
180 }
181 assert_eq!(res.status(), StatusCode::OK);
182 let create_body: Value = res.json().await.expect("Not JSON");
183 assert_eq!(create_body["did"], did);
184
185 let login_payload = json!({
186 "identifier": handle,
187 "password": "password"
188 });
189 let res = client
190 .post(format!(
191 "{}/xrpc/com.atproto.server.createSession",
192 base_url().await
193 ))
194 .json(&login_payload)
195 .send()
196 .await
197 .expect("Failed createSession");
198
199 assert_eq!(res.status(), StatusCode::OK);
200 let session_body: Value = res.json().await.expect("Not JSON");
201 let _jwt = session_body["accessJwt"].as_str().unwrap();
202
203 /*
204 let profile_payload = json!({
205 "repo": did,
206 "collection": "app.bsky.actor.profile",
207 "rkey": "self",
208 "record": {
209 "$type": "app.bsky.actor.profile",
210 "displayName": "DID Web User",
211 "description": "Testing lifecycle"
212 }
213 });
214
215 let res = client.post(format!("{}/xrpc/com.atproto.repo.putRecord", base_url().await))
216 .bearer_auth(_jwt)
217 .json(&profile_payload)
218 .send()
219 .await
220 .expect("Failed putRecord");
221
222 if res.status() != StatusCode::OK {
223 let body: Value = res.json().await.unwrap();
224 println!("putRecord failed: {:?}", body);
225 panic!("putRecord returned non-200");
226 }
227 assert_eq!(res.status(), StatusCode::OK);
228
229 let res = client.get(format!("{}/xrpc/com.atproto.repo.getRecord", base_url().await))
230 .query(&[
231 ("repo", &handle),
232 ("collection", &"app.bsky.actor.profile".to_string()),
233 ("rkey", &"self".to_string())
234 ])
235 .send()
236 .await
237 .expect("Failed getRecord");
238
239 if res.status() != StatusCode::OK {
240 let body: Value = res.json().await.unwrap();
241 println!("getRecord failed: {:?}", body);
242 panic!("getRecord returned non-200");
243 }
244 let record_body: Value = res.json().await.expect("Not JSON");
245 assert_eq!(record_body["value"]["displayName"], "DID Web User");
246 */
247}