openzeppelin_relayer/api/routes/
notification.rs

1//! This module defines the HTTP routes for notification operations.
2//! It includes handlers for listing, retrieving, creating, updating, and deleting notifications.
3//! The routes are integrated with the Actix-web framework and interact with the notification controller.
4
5use crate::{
6    api::controllers::notification,
7    models::{
8        DefaultAppState, NotificationCreateRequest, NotificationUpdateRequest, PaginationQuery,
9    },
10};
11use actix_web::{delete, get, patch, post, web, Responder};
12
13/// Lists all notifications with pagination support.
14#[get("/notifications")]
15async fn list_notifications(
16    query: web::Query<PaginationQuery>,
17    data: web::ThinData<DefaultAppState>,
18) -> impl Responder {
19    notification::list_notifications(query.into_inner(), data).await
20}
21
22/// Retrieves details of a specific notification by ID.
23#[get("/notifications/{notification_id}")]
24async fn get_notification(
25    notification_id: web::Path<String>,
26    data: web::ThinData<DefaultAppState>,
27) -> impl Responder {
28    notification::get_notification(notification_id.into_inner(), data).await
29}
30
31/// Creates a new notification.
32#[post("/notifications")]
33async fn create_notification(
34    request: web::Json<NotificationCreateRequest>,
35    data: web::ThinData<DefaultAppState>,
36) -> impl Responder {
37    notification::create_notification(request.into_inner(), data).await
38}
39
40/// Updates an existing notification.
41#[patch("/notifications/{notification_id}")]
42async fn update_notification(
43    notification_id: web::Path<String>,
44    request: web::Json<NotificationUpdateRequest>,
45    data: web::ThinData<DefaultAppState>,
46) -> impl Responder {
47    notification::update_notification(notification_id.into_inner(), request.into_inner(), data)
48        .await
49}
50
51/// Deletes a notification by ID.
52#[delete("/notifications/{notification_id}")]
53async fn delete_notification(
54    notification_id: web::Path<String>,
55    data: web::ThinData<DefaultAppState>,
56) -> impl Responder {
57    notification::delete_notification(notification_id.into_inner(), data).await
58}
59
60/// Configures the notification routes.
61pub fn init(cfg: &mut web::ServiceConfig) {
62    cfg.service(list_notifications)
63        .service(get_notification)
64        .service(create_notification)
65        .service(update_notification)
66        .service(delete_notification);
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::utils::mocks::mockutils::create_mock_app_state;
73    use actix_web::{http::StatusCode, test, web, App};
74
75    #[actix_web::test]
76    async fn test_notification_routes_are_registered() {
77        // Arrange - Create app with notification routes
78        let app_state = create_mock_app_state(None, None, None, None, None).await;
79        let app = test::init_service(
80            App::new()
81                .app_data(web::Data::new(app_state))
82                .configure(init),
83        )
84        .await;
85
86        // Test GET /notifications - should not return 404 (route exists)
87        let req = test::TestRequest::get().uri("/notifications").to_request();
88        let resp = test::call_service(&app, req).await;
89        assert_ne!(
90            resp.status(),
91            StatusCode::NOT_FOUND,
92            "GET /notifications route not registered"
93        );
94
95        // Test GET /notifications/{id} - should not return 404
96        let req = test::TestRequest::get()
97            .uri("/notifications/test-id")
98            .to_request();
99        let resp = test::call_service(&app, req).await;
100        assert_ne!(
101            resp.status(),
102            StatusCode::NOT_FOUND,
103            "GET /notifications/{{id}} route not registered"
104        );
105
106        // Test POST /notifications - should not return 404
107        let req = test::TestRequest::post()
108            .uri("/notifications")
109            .set_json(serde_json::json!({
110                "id": "test",
111                "type": "webhook",
112                "url": "https://example.com"
113            }))
114            .to_request();
115        let resp = test::call_service(&app, req).await;
116        assert_ne!(
117            resp.status(),
118            StatusCode::NOT_FOUND,
119            "POST /notifications route not registered"
120        );
121
122        // Test PATCH /notifications/{id} - should not return 404
123        let req = test::TestRequest::patch()
124            .uri("/notifications/test-id")
125            .set_json(serde_json::json!({"url": "https://updated.com"}))
126            .to_request();
127        let resp = test::call_service(&app, req).await;
128        assert_ne!(
129            resp.status(),
130            StatusCode::NOT_FOUND,
131            "PATCH /notifications/{{id}} route not registered"
132        );
133
134        // Test DELETE /notifications/{id} - should not return 404
135        let req = test::TestRequest::delete()
136            .uri("/notifications/test-id")
137            .to_request();
138        let resp = test::call_service(&app, req).await;
139        assert_ne!(
140            resp.status(),
141            StatusCode::NOT_FOUND,
142            "DELETE /notifications/{{id}} route not registered"
143        );
144    }
145}