openzeppelin_relayer/models/notification/
response.rs

1//! This module handles outgoing HTTP responses for notification operations, providing:
2//!
3//! - **Response Models**: Structures for representing notification data in API responses
4//! - **Security Handling**: Obfuscation of sensitive data (e.g., signing keys)
5//! - **Serialization**: Conversion to JSON format for HTTP responses
6//!
7//! Serves as the output format for notification data to external clients, ensuring
8//! all sensitive information is properly masked and formatted correctly.
9use crate::models::{NotificationRepoModel, NotificationType};
10use serde::{Deserialize, Serialize};
11use utoipa::ToSchema;
12
13/// Response structure for notification API endpoints
14#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, ToSchema)]
15pub struct NotificationResponse {
16    pub id: String,
17    pub r#type: NotificationType,
18    pub url: String,
19    /// Signing key is hidden in responses for security
20    pub has_signing_key: bool,
21}
22
23impl From<NotificationRepoModel> for NotificationResponse {
24    fn from(model: NotificationRepoModel) -> Self {
25        Self {
26            id: model.id,
27            r#type: model.notification_type,
28            url: model.url,
29            has_signing_key: model.signing_key.is_some(),
30        }
31    }
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37    use crate::models::SecretString;
38
39    #[test]
40    fn test_from_notification_repo_model() {
41        let model = NotificationRepoModel {
42            id: "test-id".to_string(),
43            notification_type: NotificationType::Webhook,
44            url: "https://example.com/webhook".to_string(),
45            signing_key: Some(SecretString::new("secret-key")),
46        };
47
48        let response = NotificationResponse::from(model);
49
50        assert_eq!(response.id, "test-id");
51        assert_eq!(response.r#type, NotificationType::Webhook);
52        assert_eq!(response.url, "https://example.com/webhook");
53        assert!(response.has_signing_key);
54    }
55
56    #[test]
57    fn test_from_notification_repo_model_without_signing_key() {
58        let model = NotificationRepoModel {
59            id: "test-id".to_string(),
60            notification_type: NotificationType::Webhook,
61            url: "https://example.com/webhook".to_string(),
62            signing_key: None,
63        };
64
65        let response = NotificationResponse::from(model);
66
67        assert_eq!(response.id, "test-id");
68        assert_eq!(response.r#type, NotificationType::Webhook);
69        assert_eq!(response.url, "https://example.com/webhook");
70        assert!(!response.has_signing_key);
71    }
72}