#
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}