Author: Manos Pitsidianakis [manos@pitsidianak.is]
Hash: 52ef646faeb3b4675d7ce844093ee7929ebfe7d6
Timestamp: Tue, 16 May 2023 17:41:50 +0000 (1 year ago)

+167 -13 +/-6 browse
web: add unit tests+++
1diff --git a/mailpot-tests/for_testing.db b/mailpot-tests/for_testing.db
2index 64f74ee..fa043ad 100644
3 Binary files a/mailpot-tests/for_testing.db and b/mailpot-tests/for_testing.db differ
4 diff --git a/rest-http/src/routes/list.rs b/rest-http/src/routes/list.rs
5index 1897ce2..ebe9910 100644
6--- a/rest-http/src/routes/list.rs
7+++ b/rest-http/src/routes/list.rs
8 @@ -384,7 +384,15 @@ mod tests {
9 assert_eq!(response.status(), StatusCode::OK);
10 let body = hyper::body::to_bytes(response.into_body()).await.unwrap();
11 let r: Vec<ListOwner> = serde_json::from_slice(&body).unwrap();
12- assert_eq!(&r, &[]);
13+ assert_eq!(
14+ &r,
15+ &[ListOwner {
16+ pk: 1,
17+ list: 1,
18+ address: "user@example.com".into(),
19+ name: None
20+ }]
21+ );
22
23 // ------------------------------------------------------------
24 // new_list_owner()
25 diff --git a/web/src/auth.rs b/web/src/auth.rs
26index af17e30..cc852b2 100644
27--- a/web/src/auth.rs
28+++ b/web/src/auth.rs
29 @@ -158,7 +158,8 @@ pub async fn ssh_signin(
30 .into_response()
31 }
32
33- pub async fn ssh_signin_post(
34+ #[allow(non_snake_case)]
35+ pub async fn ssh_signin_POST(
36 _: LoginPath,
37 mut session: WritableSession,
38 Query(next): Query<Next>,
39 diff --git a/web/src/lists.rs b/web/src/lists.rs
40index bc25716..c0197af 100644
41--- a/web/src/lists.rs
42+++ b/web/src/lists.rs
43 @@ -320,7 +320,8 @@ pub async fn list_edit(
44 ))
45 }
46
47- pub async fn list_edit_post(
48+ #[allow(non_snake_case)]
49+ pub async fn list_edit_POST(
50 ListEditPath(id): ListEditPath,
51 mut session: WritableSession,
52 Extension(user): Extension<User>,
53 @@ -514,7 +515,7 @@ pub enum SubscriptionPolicySettings {
54 }
55
56 /// Raw post page.
57- pub async fn post_raw(
58+ pub async fn list_post_raw(
59 ListPostRawPath(id, msg_id): ListPostRawPath,
60 State(state): State<Arc<AppState>>,
61 ) -> Result<String, ResponseError> {
62 @@ -541,7 +542,7 @@ pub async fn post_raw(
63 }
64
65 /// .eml post page.
66- pub async fn post_eml(
67+ pub async fn list_post_eml(
68 ListPostEmlPath(id, msg_id): ListPostEmlPath,
69 State(state): State<Arc<AppState>>,
70 ) -> Result<impl IntoResponse, ResponseError> {
71 diff --git a/web/src/main.rs b/web/src/main.rs
72index 000d58e..231ac2c 100644
73--- a/web/src/main.rs
74+++ b/web/src/main.rs
75 @@ -54,8 +54,8 @@ fn create_app(shared_state: Arc<AppState>) -> Router {
76 .route("/", get(root))
77 .typed_get(list)
78 .typed_get(list_post)
79- .typed_get(post_raw)
80- .typed_get(post_eml)
81+ .typed_get(list_post_raw)
82+ .typed_get(list_post_eml)
83 .typed_get(list_edit.layer(RequireAuth::login_with_role_or_redirect(
84 Role::User..,
85 Arc::clone(&login_url),
86 @@ -65,7 +65,7 @@ fn create_app(shared_state: Arc<AppState>) -> Router {
87 {
88 let shared_state = Arc::clone(&shared_state);
89 move |path, session, user, payload| {
90- list_edit_post(path, session, user, payload, State(shared_state))
91+ list_edit_POST(path, session, user, payload, State(shared_state))
92 }
93 }
94 .layer(RequireAuth::login_with_role_or_redirect(
95 @@ -93,7 +93,7 @@ fn create_app(shared_state: Arc<AppState>) -> Router {
96 .typed_post({
97 let shared_state = Arc::clone(&shared_state);
98 move |path, session, query, auth, body| {
99- auth::ssh_signin_post(path, session, query, auth, body, shared_state)
100+ auth::ssh_signin_POST(path, session, query, auth, body, shared_state)
101 }
102 })
103 .typed_get(logout_handler)
104 @@ -112,7 +112,7 @@ fn create_app(shared_state: Arc<AppState>) -> Router {
105 {
106 let shared_state = Arc::clone(&shared_state);
107 move |path, session, auth, body| {
108- settings_post(path, session, auth, body, shared_state)
109+ settings_POST(path, session, auth, body, shared_state)
110 }
111 }
112 .layer(RequireAuth::login_or_redirect(
113 @@ -131,7 +131,7 @@ fn create_app(shared_state: Arc<AppState>) -> Router {
114 {
115 let shared_state = Arc::clone(&shared_state);
116 move |session, path, user, body| {
117- user_list_subscription_post(session, path, user, body, shared_state)
118+ user_list_subscription_POST(session, path, user, body, shared_state)
119 }
120 }
121 .layer(RequireAuth::login_with_role_or_redirect(
122 @@ -225,6 +225,7 @@ mod tests {
123 };
124 use mailpot::{Configuration, Connection, SendMail};
125 use mailpot_tests::init_stderr_logging;
126+ use percent_encoding::utf8_percent_encode;
127 use tempfile::TempDir;
128 use tower::ServiceExt;
129
130 @@ -258,6 +259,11 @@ mod tests {
131
132 let db_path = tmp_dir.path().join("mpot.db");
133 std::fs::copy("../mailpot-tests/for_testing.db", &db_path).unwrap();
134+ let mut perms = std::fs::metadata(&db_path).unwrap().permissions();
135+ #[allow(clippy::permissions_set_readonly_false)]
136+ perms.set_readonly(false);
137+ std::fs::set_permissions(&db_path, perms).unwrap();
138+
139 let config = Configuration {
140 send_mail: SendMail::ShellCommand("/usr/bin/false".to_string()),
141 db_path,
142 @@ -285,6 +291,66 @@ mod tests {
143 );
144
145 // ------------------------------------------------------------
146+ // list_post(), list_post_eml(), list_post_raw()
147+
148+ {
149+ let msg_id = "<abcdefgh@sator.example.com>";
150+ let res = create_app(state.clone())
151+ .oneshot(req!(
152+ get & format!(
153+ "/list/{id}/posts/{msgid}/",
154+ id = list.id,
155+ msgid = utf8_percent_encode(msg_id, PATH_SEGMENT)
156+ )
157+ ))
158+ .await
159+ .unwrap();
160+
161+ assert_eq!(res.status(), StatusCode::OK);
162+ assert_eq!(
163+ res.headers().get(http::header::CONTENT_TYPE),
164+ Some(&http::HeaderValue::from_static("text/html; charset=utf-8"))
165+ );
166+ let res = create_app(state.clone())
167+ .oneshot(req!(
168+ get & format!(
169+ "/list/{id}/posts/{msgid}/raw/",
170+ id = list.id,
171+ msgid = utf8_percent_encode(msg_id, PATH_SEGMENT)
172+ )
173+ ))
174+ .await
175+ .unwrap();
176+
177+ assert_eq!(res.status(), StatusCode::OK);
178+ assert_eq!(
179+ res.headers().get(http::header::CONTENT_TYPE),
180+ Some(&http::HeaderValue::from_static("text/plain; charset=utf-8"))
181+ );
182+ let res = create_app(state.clone())
183+ .oneshot(req!(
184+ get & format!(
185+ "/list/{id}/posts/{msgid}/eml/",
186+ id = list.id,
187+ msgid = utf8_percent_encode(msg_id, PATH_SEGMENT)
188+ )
189+ ))
190+ .await
191+ .unwrap();
192+
193+ assert_eq!(res.status(), StatusCode::OK);
194+ assert_eq!(
195+ res.headers().get(http::header::CONTENT_TYPE),
196+ Some(&http::HeaderValue::from_static("application/octet-stream"))
197+ );
198+ assert_eq!(
199+ res.headers().get(http::header::CONTENT_DISPOSITION),
200+ Some(&http::HeaderValue::from_static(
201+ "attachment; filename=\"<abcdefgh@sator.example.com>.eml\""
202+ )),
203+ );
204+ }
205+ // ------------------------------------------------------------
206 // help(), ssh_signin(), root()
207
208 for path in ["/help/", "/"] {
209 @@ -391,5 +457,81 @@ mod tests {
210
211 // ------------------------------------------------------------
212 // user_list_subscription_post() TODO
213+
214+ // ------------------------------------------------------------
215+ // list_edit()
216+
217+ {
218+ let mut request = req!(get & format!("/list/{id}/edit/", id = list.id,));
219+ request
220+ .headers_mut()
221+ .insert(COOKIE, session_cookie.to_owned());
222+ let response = login_app.clone().oneshot(request).await.unwrap();
223+
224+ assert_eq!(response.status(), StatusCode::OK);
225+ }
226+
227+ // ------------------------------------------------------------
228+ // list_edit_POST()
229+
230+ {
231+ let mut request = req!(
232+ post & format!("/list/{id}/edit/", id = list.id,),
233+ crate::lists::ChangeSetting::Metadata {
234+ name: "new name".to_string(),
235+ id: "new-name".to_string(),
236+ address: list.address.clone(),
237+ description: list.description.clone(),
238+ owner_local_part: None,
239+ request_local_part: None,
240+ archive_url: None,
241+ }
242+ );
243+ request
244+ .headers_mut()
245+ .insert(COOKIE, session_cookie.to_owned());
246+ let response = login_app.clone().oneshot(request).await.unwrap();
247+
248+ assert_eq!(response.status(), StatusCode::SEE_OTHER);
249+ let list_mod = db.lists().unwrap().remove(0);
250+ assert_eq!(&list_mod.name, "new name");
251+ assert_eq!(&list_mod.id, "new-name");
252+ assert_eq!(&list_mod.address, &list.address);
253+ assert_eq!(&list_mod.description, &list.description);
254+ }
255+
256+ {
257+ let mut request = req!(post "/list/new-name/edit/",
258+ crate::lists::ChangeSetting::SubscriptionPolicy {
259+ send_confirmation: BoolPOST(false),
260+ subscription_policy: crate::lists::SubscriptionPolicySettings::Custom,
261+ }
262+ );
263+ request
264+ .headers_mut()
265+ .insert(COOKIE, session_cookie.to_owned());
266+ let response = login_app.clone().oneshot(request).await.unwrap();
267+
268+ assert_eq!(response.status(), StatusCode::SEE_OTHER);
269+ let policy = db.list_subscription_policy(list.pk()).unwrap().unwrap();
270+ assert!(!policy.send_confirmation);
271+ assert!(policy.custom);
272+ }
273+ {
274+ let mut request = req!(post "/list/new-name/edit/",
275+ crate::lists::ChangeSetting::PostPolicy {
276+ delete_post_policy: None,
277+ post_policy: crate::lists::PostPolicySettings::Custom,
278+ }
279+ );
280+ request
281+ .headers_mut()
282+ .insert(COOKIE, session_cookie.to_owned());
283+ let response = login_app.clone().oneshot(request).await.unwrap();
284+
285+ assert_eq!(response.status(), StatusCode::SEE_OTHER);
286+ let policy = db.list_post_policy(list.pk()).unwrap().unwrap();
287+ assert!(policy.custom);
288+ }
289 }
290 }
291 diff --git a/web/src/settings.rs b/web/src/settings.rs
292index 7a29830..033614b 100644
293--- a/web/src/settings.rs
294+++ b/web/src/settings.rs
295 @@ -89,7 +89,8 @@ pub enum ChangeSetting {
296 ChangeName { new: String },
297 }
298
299- pub async fn settings_post(
300+ #[allow(non_snake_case)]
301+ pub async fn settings_POST(
302 _: SettingsPath,
303 mut session: WritableSession,
304 Extension(user): Extension<User>,
305 @@ -331,7 +332,8 @@ pub struct SubscriptionFormPayload {
306 pub receive_confirmation: bool,
307 }
308
309- pub async fn user_list_subscription_post(
310+ #[allow(non_snake_case)]
311+ pub async fn user_list_subscription_POST(
312 ListSettingsPath(id): ListSettingsPath,
313 mut session: WritableSession,
314 Extension(user): Extension<User>,