mcaptcha/api/v1/notifications/
mark_read.rs

1// Copyright (C) 2022  Aravinth Manivannan <realaravinth@batsense.net>
2// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6use actix_identity::Identity;
7use actix_web::{web, HttpResponse, Responder};
8use serde::{Deserialize, Serialize};
9
10use crate::errors::*;
11use crate::AppData;
12
13#[derive(Deserialize, Serialize)]
14pub struct MarkReadReq {
15    pub id: i32,
16}
17
18/// route handler that marks a notification read
19#[my_codegen::post(
20    path = "crate::V1_API_ROUTES.notifications.mark_read",
21    wrap = "crate::api::v1::get_middleware()"
22)]
23pub async fn mark_read(
24    data: AppData,
25    payload: web::Json<MarkReadReq>,
26    id: Identity,
27) -> ServiceResult<impl Responder> {
28    let receiver = id.identity().unwrap();
29    // TODO handle error where payload.to doesn't exist
30
31    // TODO get payload from path /api/v1/notifications/{id}/read"
32    data.db
33        .mark_notification_read(&receiver, payload.id)
34        .await?;
35
36    Ok(HttpResponse::Ok())
37}
38
39#[cfg(test)]
40pub mod tests {
41    use actix_web::http::StatusCode;
42    use actix_web::test;
43
44    use super::*;
45    use crate::api::v1::notifications::add::AddNotificationRequest;
46    use crate::api::v1::notifications::get::NotificationResp;
47    use crate::tests::*;
48    use crate::*;
49
50    #[actix_rt::test]
51    async fn notification_mark_read_works_pg() {
52        let data = pg::get_data().await;
53        notification_mark_read_works(data).await;
54    }
55
56    #[actix_rt::test]
57    async fn notification_mark_read_works_maria() {
58        let data = maria::get_data().await;
59        notification_mark_read_works(data).await;
60    }
61
62    pub async fn notification_mark_read_works(data: ArcData) {
63        const NAME1: &str = "notifuser122";
64        const NAME2: &str = "notiuser222";
65        const PASSWORD: &str = "longpassworddomain";
66        const EMAIL1: &str = "testnotification122@a.com";
67        const EMAIL2: &str = "testnotification222@a.com";
68        const HEADING: &str = "testing notifications get";
69        const MESSAGE: &str = "testing notifications get message";
70        let data = &data;
71
72        delete_user(data, NAME1).await;
73        delete_user(data, NAME2).await;
74
75        register_and_signin(data, NAME1, EMAIL1, PASSWORD).await;
76        register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
77        let (_creds, signin_resp) = signin(data, NAME1, PASSWORD).await;
78        let (_creds2, signin_resp2) = signin(data, NAME2, PASSWORD).await;
79        let cookies = get_cookie!(signin_resp);
80        let cookies2 = get_cookie!(signin_resp2);
81        let app = get_app!(data).await;
82
83        let msg = AddNotificationRequest {
84            to: NAME2.into(),
85            heading: HEADING.into(),
86            message: MESSAGE.into(),
87        };
88
89        let send_notification_resp = test::call_service(
90            &app,
91            post_request!(&msg, V1_API_ROUTES.notifications.add)
92                .cookie(cookies.clone())
93                .to_request(),
94        )
95        .await;
96        assert_eq!(send_notification_resp.status(), StatusCode::OK);
97
98        let get_notifications_resp = test::call_service(
99            &app,
100            test::TestRequest::get()
101                .uri(V1_API_ROUTES.notifications.get)
102                .cookie(cookies2.clone())
103                .to_request(),
104        )
105        .await;
106        assert_eq!(get_notifications_resp.status(), StatusCode::OK);
107
108        let mut notifications: Vec<NotificationResp> =
109            test::read_body_json(get_notifications_resp).await;
110        let notification = notifications.pop().unwrap();
111        assert_eq!(notification.name, NAME1);
112        assert_eq!(notification.message, MESSAGE);
113        assert_eq!(notification.heading, HEADING);
114
115        let mark_read_payload = MarkReadReq {
116            id: notification.id,
117        };
118        let mark_read_resp = test::call_service(
119            &app,
120            post_request!(&mark_read_payload, V1_API_ROUTES.notifications.mark_read)
121                .cookie(cookies2.clone())
122                .to_request(),
123        )
124        .await;
125        assert_eq!(mark_read_resp.status(), StatusCode::OK);
126
127        let get_notifications_resp = test::call_service(
128            &app,
129            test::TestRequest::get()
130                .uri(V1_API_ROUTES.notifications.get)
131                .cookie(cookies2.clone())
132                .to_request(),
133        )
134        .await;
135        assert_eq!(get_notifications_resp.status(), StatusCode::OK);
136        let mut notifications: Vec<NotificationResp> =
137            test::read_body_json(get_notifications_resp).await;
138        assert!(notifications.pop().is_none());
139    }
140}