mcaptcha/api/v1/notifications/
get.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::{HttpResponse, Responder};
8use serde::{Deserialize, Serialize};
9
10use crate::errors::*;
11use crate::AppData;
12
13use db_core::Notification;
14
15#[derive(Default, PartialEq, Clone, Deserialize, Serialize)]
16pub struct NotificationResp {
17    pub name: String,
18    pub heading: String,
19    pub message: String,
20    pub received: i64,
21    pub id: i32,
22}
23
24impl From<Notification> for NotificationResp {
25    fn from(n: Notification) -> Self {
26        NotificationResp {
27            name: n.name.unwrap(),
28            heading: n.heading.unwrap(),
29            received: n.received.unwrap(),
30            id: n.id.unwrap(),
31            message: n.message.unwrap(),
32        }
33    }
34}
35
36impl NotificationResp {
37    pub fn from_notifications(mut n: Vec<Notification>) -> Vec<Self> {
38        let mut notifications = Vec::with_capacity(n.len());
39
40        n.drain(0..).for_each(|x| {
41            let y: NotificationResp = x.into();
42            notifications.push(y)
43        });
44
45        notifications
46    }
47}
48
49/// route handler that gets all unread notifications
50#[my_codegen::get(
51    path = "crate::V1_API_ROUTES.notifications.get",
52    wrap = "crate::api::v1::get_middleware()"
53)]
54pub async fn get_notification(
55    data: AppData,
56    id: Identity,
57) -> ServiceResult<impl Responder> {
58    let receiver = id.identity().unwrap();
59    // TODO handle error where payload.to doesn't exist
60
61    let notifications = data.db.get_all_unread_notifications(&receiver).await?;
62    let notifications = NotificationResp::from_notifications(notifications);
63    Ok(HttpResponse::Ok().json(notifications))
64}
65
66#[cfg(test)]
67pub mod tests {
68    use actix_web::http::StatusCode;
69    use actix_web::test;
70
71    use super::*;
72    use crate::api::v1::notifications::add::AddNotificationRequest;
73    use crate::tests::*;
74    use crate::*;
75
76    #[actix_rt::test]
77    async fn notification_get_works_pg() {
78        let data = pg::get_data().await;
79        notification_get_works(data).await;
80    }
81
82    #[actix_rt::test]
83    async fn notification_get_works_maria() {
84        let data = maria::get_data().await;
85        notification_get_works(data).await;
86    }
87
88    pub async fn notification_get_works(data: ArcData) {
89        const NAME1: &str = "notifuser12";
90        const NAME2: &str = "notiuser22";
91        const PASSWORD: &str = "longpassworddomain";
92        const EMAIL1: &str = "testnotification12@a.com";
93        const EMAIL2: &str = "testnotification22@a.com";
94        const HEADING: &str = "testing notifications get";
95        const MESSAGE: &str = "testing notifications get message";
96
97        let data = &data;
98
99        delete_user(data, NAME1).await;
100        delete_user(data, NAME2).await;
101
102        register_and_signin(data, NAME1, EMAIL1, PASSWORD).await;
103        register_and_signin(data, NAME2, EMAIL2, PASSWORD).await;
104        let (_creds, signin_resp) = signin(data, NAME1, PASSWORD).await;
105        let (_creds2, signin_resp2) = signin(data, NAME2, PASSWORD).await;
106        let cookies = get_cookie!(signin_resp);
107        let cookies2 = get_cookie!(signin_resp2);
108        let app = get_app!(data).await;
109
110        let msg = AddNotificationRequest {
111            to: NAME2.into(),
112            heading: HEADING.into(),
113            message: MESSAGE.into(),
114        };
115
116        let send_notification_resp = test::call_service(
117            &app,
118            post_request!(&msg, V1_API_ROUTES.notifications.add)
119                .cookie(cookies.clone())
120                .to_request(),
121        )
122        .await;
123        assert_eq!(send_notification_resp.status(), StatusCode::OK);
124
125        let get_notifications_resp = test::call_service(
126            &app,
127            test::TestRequest::get()
128                .uri(V1_API_ROUTES.notifications.get)
129                .cookie(cookies2.clone())
130                .to_request(),
131        )
132        .await;
133        assert_eq!(get_notifications_resp.status(), StatusCode::OK);
134
135        let mut notifications: Vec<NotificationResp> =
136            test::read_body_json(get_notifications_resp).await;
137        let notification = notifications.pop().unwrap();
138        assert_eq!(notification.name, NAME1);
139        assert_eq!(notification.message, MESSAGE);
140        assert_eq!(notification.heading, HEADING);
141    }
142}