zlayer_types/api/
notifiers.rs1use serde::{Deserialize, Serialize};
8
9use crate::storage::{NotifierConfig, NotifierKind};
10
11#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
13pub struct CreateNotifierRequest {
14 pub name: String,
16 pub kind: NotifierKind,
18 pub config: NotifierConfig,
20}
21
22#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
24pub struct UpdateNotifierRequest {
25 #[serde(default)]
27 pub name: Option<String>,
28 #[serde(default)]
30 pub enabled: Option<bool>,
31 #[serde(default)]
33 pub config: Option<NotifierConfig>,
34}
35
36#[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
38pub struct TestNotifierResponse {
39 pub success: bool,
41 pub message: String,
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48
49 #[test]
50 fn test_create_request_deserialize_slack() {
51 let req: CreateNotifierRequest = serde_json::from_str(
52 r#"{"name":"slack-alerts","kind":"slack","config":{"type":"slack","webhook_url":"https://hooks.slack.com/test"}}"#,
53 )
54 .unwrap();
55 assert_eq!(req.name, "slack-alerts");
56 assert_eq!(req.kind, NotifierKind::Slack);
57 match &req.config {
58 NotifierConfig::Slack { webhook_url } => {
59 assert_eq!(webhook_url, "https://hooks.slack.com/test");
60 }
61 other => panic!("Expected Slack config, got {other:?}"),
62 }
63 }
64
65 #[test]
66 fn test_create_request_deserialize_discord() {
67 let req: CreateNotifierRequest = serde_json::from_str(
68 r#"{"name":"discord-alerts","kind":"discord","config":{"type":"discord","webhook_url":"https://discord.com/api/webhooks/test"}}"#,
69 )
70 .unwrap();
71 assert_eq!(req.kind, NotifierKind::Discord);
72 }
73
74 #[test]
75 fn test_create_request_deserialize_webhook() {
76 let req: CreateNotifierRequest = serde_json::from_str(
77 r#"{
78 "name": "generic-hook",
79 "kind": "webhook",
80 "config": {
81 "type": "webhook",
82 "url": "https://example.com/hook",
83 "method": "PUT",
84 "headers": {"Authorization": "Bearer token123"}
85 }
86 }"#,
87 )
88 .unwrap();
89 assert_eq!(req.kind, NotifierKind::Webhook);
90 match &req.config {
91 NotifierConfig::Webhook {
92 url,
93 method,
94 headers,
95 } => {
96 assert_eq!(url, "https://example.com/hook");
97 assert_eq!(method.as_deref(), Some("PUT"));
98 let h = headers.as_ref().unwrap();
99 assert_eq!(h.get("Authorization").unwrap(), "Bearer token123");
100 }
101 other => panic!("Expected Webhook config, got {other:?}"),
102 }
103 }
104
105 #[test]
106 fn test_create_request_deserialize_smtp() {
107 let req: CreateNotifierRequest = serde_json::from_str(
108 r#"{
109 "name": "email-alerts",
110 "kind": "smtp",
111 "config": {
112 "type": "smtp",
113 "host": "smtp.example.com",
114 "port": 587,
115 "username": "user",
116 "password": "pass",
117 "from": "noreply@example.com",
118 "to": ["admin@example.com"]
119 }
120 }"#,
121 )
122 .unwrap();
123 assert_eq!(req.kind, NotifierKind::Smtp);
124 }
125
126 #[test]
127 fn test_update_request_partial() {
128 let req: UpdateNotifierRequest = serde_json::from_str(r#"{"enabled": false}"#).unwrap();
129 assert!(req.name.is_none());
130 assert_eq!(req.enabled, Some(false));
131 assert!(req.config.is_none());
132 }
133
134 #[test]
135 fn test_test_notifier_response_serialize() {
136 let resp = TestNotifierResponse {
137 success: true,
138 message: "ok".to_string(),
139 };
140 let json = serde_json::to_string(&resp).unwrap();
141 assert!(json.contains("\"success\":true"));
142 assert!(json.contains("\"message\":\"ok\""));
143 }
144}