this repo has no description
1mod common;
2
3use reqwest::StatusCode;
4use serde_json::{json, Value};
5use sqlx::PgPool;
6
7async fn get_pool() -> PgPool {
8 let conn_str = common::get_db_connection_string().await;
9 sqlx::postgres::PgPoolOptions::new()
10 .max_connections(5)
11 .connect(&conn_str)
12 .await
13 .expect("Failed to connect to test database")
14}
15
16#[tokio::test]
17async fn test_email_update_flow_success() {
18 let client = common::client();
19 let base_url = common::base_url().await;
20 let pool = get_pool().await;
21
22 let handle = format!("emailup_{}", uuid::Uuid::new_v4());
23 let email = format!("{}@example.com", handle);
24 let payload = json!({
25 "handle": handle,
26 "email": email,
27 "password": "password"
28 });
29
30 let res = client
31 .post(format!("{}/xrpc/com.atproto.server.createAccount", base_url))
32 .json(&payload)
33 .send()
34 .await
35 .expect("Failed to create account");
36 assert_eq!(res.status(), StatusCode::OK);
37 let body: Value = res.json().await.expect("Invalid JSON");
38 let access_jwt = body["accessJwt"].as_str().expect("No accessJwt");
39
40 let new_email = format!("new_{}@example.com", handle);
41 let res = client
42 .post(format!("{}/xrpc/com.atproto.server.requestEmailUpdate", base_url))
43 .bearer_auth(access_jwt)
44 .json(&json!({"email": new_email}))
45 .send()
46 .await
47 .expect("Failed to request email update");
48 assert_eq!(res.status(), StatusCode::OK);
49 let body: Value = res.json().await.expect("Invalid JSON");
50 assert_eq!(body["tokenRequired"], true);
51
52 let user = sqlx::query!(
53 "SELECT email_pending_verification, email_confirmation_code, email FROM users WHERE handle = $1",
54 handle
55 )
56 .fetch_one(&pool)
57 .await
58 .expect("User not found");
59
60 assert_eq!(user.email_pending_verification.as_deref(), Some(new_email.as_str()));
61 assert!(user.email_confirmation_code.is_some());
62 let code = user.email_confirmation_code.unwrap();
63
64 let res = client
65 .post(format!("{}/xrpc/com.atproto.server.confirmEmail", base_url))
66 .bearer_auth(access_jwt)
67 .json(&json!({
68 "email": new_email,
69 "token": code
70 }))
71 .send()
72 .await
73 .expect("Failed to confirm email");
74 assert_eq!(res.status(), StatusCode::OK);
75
76 let user = sqlx::query!(
77 "SELECT email, email_pending_verification, email_confirmation_code FROM users WHERE handle = $1",
78 handle
79 )
80 .fetch_one(&pool)
81 .await
82 .expect("User not found");
83
84 assert_eq!(user.email, new_email);
85 assert!(user.email_pending_verification.is_none());
86 assert!(user.email_confirmation_code.is_none());
87}
88
89#[tokio::test]
90async fn test_request_email_update_taken_email() {
91 let client = common::client();
92 let base_url = common::base_url().await;
93
94 let handle1 = format!("emailup_taken1_{}", uuid::Uuid::new_v4());
95 let email1 = format!("{}@example.com", handle1);
96 let res = client
97 .post(format!("{}/xrpc/com.atproto.server.createAccount", base_url))
98 .json(&json!({
99 "handle": handle1,
100 "email": email1,
101 "password": "password"
102 }))
103 .send()
104 .await
105 .expect("Failed to create account 1");
106 assert_eq!(res.status(), StatusCode::OK);
107
108 let handle2 = format!("emailup_taken2_{}", uuid::Uuid::new_v4());
109 let email2 = format!("{}@example.com", handle2);
110 let res = client
111 .post(format!("{}/xrpc/com.atproto.server.createAccount", base_url))
112 .json(&json!({
113 "handle": handle2,
114 "email": email2,
115 "password": "password"
116 }))
117 .send()
118 .await
119 .expect("Failed to create account 2");
120 assert_eq!(res.status(), StatusCode::OK);
121 let body: Value = res.json().await.expect("Invalid JSON");
122 let access_jwt2 = body["accessJwt"].as_str().expect("No accessJwt");
123
124 let res = client
125 .post(format!("{}/xrpc/com.atproto.server.requestEmailUpdate", base_url))
126 .bearer_auth(access_jwt2)
127 .json(&json!({"email": email1}))
128 .send()
129 .await
130 .expect("Failed to request email update");
131
132 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
133 let body: Value = res.json().await.expect("Invalid JSON");
134 assert_eq!(body["error"], "EmailTaken");
135}
136
137#[tokio::test]
138async fn test_confirm_email_invalid_token() {
139 let client = common::client();
140 let base_url = common::base_url().await;
141
142 let handle = format!("emailup_inv_{}", uuid::Uuid::new_v4());
143 let email = format!("{}@example.com", handle);
144 let res = client
145 .post(format!("{}/xrpc/com.atproto.server.createAccount", base_url))
146 .json(&json!({
147 "handle": handle,
148 "email": email,
149 "password": "password"
150 }))
151 .send()
152 .await
153 .expect("Failed to create account");
154 assert_eq!(res.status(), StatusCode::OK);
155 let body: Value = res.json().await.expect("Invalid JSON");
156 let access_jwt = body["accessJwt"].as_str().expect("No accessJwt");
157
158 let new_email = format!("new_{}@example.com", handle);
159 let res = client
160 .post(format!("{}/xrpc/com.atproto.server.requestEmailUpdate", base_url))
161 .bearer_auth(access_jwt)
162 .json(&json!({"email": new_email}))
163 .send()
164 .await
165 .expect("Failed to request email update");
166 assert_eq!(res.status(), StatusCode::OK);
167
168 let res = client
169 .post(format!("{}/xrpc/com.atproto.server.confirmEmail", base_url))
170 .bearer_auth(access_jwt)
171 .json(&json!({
172 "email": new_email,
173 "token": "wrong-token"
174 }))
175 .send()
176 .await
177 .expect("Failed to confirm email");
178
179 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
180 let body: Value = res.json().await.expect("Invalid JSON");
181 assert_eq!(body["error"], "InvalidToken");
182}
183
184#[tokio::test]
185async fn test_confirm_email_wrong_email() {
186 let client = common::client();
187 let base_url = common::base_url().await;
188 let pool = get_pool().await;
189
190 let handle = format!("emailup_wrong_{}", uuid::Uuid::new_v4());
191 let email = format!("{}@example.com", handle);
192 let res = client
193 .post(format!("{}/xrpc/com.atproto.server.createAccount", base_url))
194 .json(&json!({
195 "handle": handle,
196 "email": email,
197 "password": "password"
198 }))
199 .send()
200 .await
201 .expect("Failed to create account");
202 assert_eq!(res.status(), StatusCode::OK);
203 let body: Value = res.json().await.expect("Invalid JSON");
204 let access_jwt = body["accessJwt"].as_str().expect("No accessJwt");
205
206 let new_email = format!("new_{}@example.com", handle);
207 let res = client
208 .post(format!("{}/xrpc/com.atproto.server.requestEmailUpdate", base_url))
209 .bearer_auth(access_jwt)
210 .json(&json!({"email": new_email}))
211 .send()
212 .await
213 .expect("Failed to request email update");
214 assert_eq!(res.status(), StatusCode::OK);
215
216 let user = sqlx::query!("SELECT email_confirmation_code FROM users WHERE handle = $1", handle)
217 .fetch_one(&pool)
218 .await
219 .expect("User not found");
220 let code = user.email_confirmation_code.unwrap();
221
222 let res = client
223 .post(format!("{}/xrpc/com.atproto.server.confirmEmail", base_url))
224 .bearer_auth(access_jwt)
225 .json(&json!({
226 "email": "another_random@example.com",
227 "token": code
228 }))
229 .send()
230 .await
231 .expect("Failed to confirm email");
232
233 assert_eq!(res.status(), StatusCode::BAD_REQUEST);
234 let body: Value = res.json().await.expect("Invalid JSON");
235 assert_eq!(body["message"], "Email does not match pending update");
236}