rullama_a2a/
push_notification.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct AuthenticationInfo {
8 pub scheme: String,
10 #[serde(skip_serializing_if = "Option::is_none")]
12 pub credentials: Option<String>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct TaskPushNotificationConfig {
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub tenant: Option<String>,
21 #[serde(rename = "configId", skip_serializing_if = "Option::is_none")]
23 pub config_id: Option<String>,
24 #[serde(rename = "taskId")]
26 pub task_id: String,
27 pub url: String,
29 #[serde(skip_serializing_if = "Option::is_none")]
31 pub token: Option<String>,
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub authentication: Option<AuthenticationInfo>,
35 #[serde(rename = "createdAt", skip_serializing_if = "Option::is_none")]
37 pub created_at: Option<String>,
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 fn minimal_config() -> TaskPushNotificationConfig {
45 TaskPushNotificationConfig {
46 tenant: None,
47 config_id: None,
48 task_id: "task-1".to_string(),
49 url: "https://example.com/notify".to_string(),
50 token: None,
51 authentication: None,
52 created_at: None,
53 }
54 }
55
56 #[test]
57 fn minimal_config_roundtrip() {
58 let cfg = minimal_config();
59 let json = serde_json::to_string(&cfg).unwrap();
60 let back: TaskPushNotificationConfig = serde_json::from_str(&json).unwrap();
61 assert_eq!(back.task_id, cfg.task_id);
62 assert_eq!(back.url, cfg.url);
63 }
64
65 #[test]
66 fn optional_fields_omitted_when_none() {
67 let cfg = minimal_config();
68 let json = serde_json::to_string(&cfg).unwrap();
69 assert!(!json.contains("tenant"));
70 assert!(!json.contains("configId"));
71 assert!(!json.contains("token"));
72 assert!(!json.contains("authentication"));
73 assert!(!json.contains("createdAt"));
74 }
75
76 #[test]
77 fn json_uses_camel_case_task_id() {
78 let cfg = minimal_config();
79 let json = serde_json::to_string(&cfg).unwrap();
80 assert!(json.contains("taskId"));
81 assert!(!json.contains("task_id"));
82 }
83
84 #[test]
85 fn with_authentication_roundtrip() {
86 let mut cfg = minimal_config();
87 cfg.authentication = Some(AuthenticationInfo {
88 scheme: "Bearer".to_string(),
89 credentials: Some("token-abc".to_string()),
90 });
91 let json = serde_json::to_string(&cfg).unwrap();
92 let back: TaskPushNotificationConfig = serde_json::from_str(&json).unwrap();
93 let auth = back.authentication.unwrap();
94 assert_eq!(auth.scheme, "Bearer");
95 assert_eq!(auth.credentials.as_deref(), Some("token-abc"));
96 }
97
98 #[test]
99 fn authentication_info_credentials_omitted_when_none() {
100 let auth = AuthenticationInfo {
101 scheme: "Basic".to_string(),
102 credentials: None,
103 };
104 let json = serde_json::to_string(&auth).unwrap();
105 assert!(!json.contains("credentials"));
106 }
107}