zero_bounce/utility/structures/
validation.rs1use chrono::NaiveDateTime;
2
3use serde::Deserialize;
4
5use crate::utility::structures::custom_deserialize::deserialize_naive_date;
6
7
8#[derive(Clone, Debug, Deserialize)]
9pub struct ZBValidation {
10 pub address: String,
11 pub status: String,
12 pub sub_status: String,
13 pub free_email: bool,
14 pub did_you_mean: Option<String>,
15 pub account: Option<String>,
16 pub domain: Option<String>,
17 pub domain_age_days: Option<String>,
18 pub smtp_provider: Option<String>,
19 pub mx_record: Option<String>,
20 pub mx_found: Option<String>,
21 pub firstname: Option<String>,
22 pub lastname: Option<String>,
23 pub gender: Option<String>,
24 pub country: Option<String>,
25 pub region: Option<String>,
26 pub city: Option<String>,
27 pub zipcode: Option<String>,
28
29 #[serde(deserialize_with="deserialize_naive_date")]
30 pub processed_at: NaiveDateTime,
31}
32
33
34#[derive(Clone, Debug, Deserialize)]
35pub struct ZBBatchError {
36 pub error: String,
37 pub email_address: String,
38}
39
40
41#[derive(Clone, Debug, Deserialize)]
42pub struct ZBBatchValidation {
43 pub email_batch: Vec<ZBValidation>,
44 pub errors: Vec<ZBBatchError>,
45}
46
47#[cfg(test)]
48mod test {
49 use serde_json::{Result as SerdeResult, from_str};
50
51 use super::*;
52 use crate::utility::mock_constants::VALIDATION_RESPONSE_VALID;
53 use crate::utility::mock_constants::VALIDATION_RESPONSE_INVALID;
54 use crate::utility::mock_constants::VALIDATION_RESPONSE_NULL_FIELDS;
55 use crate::utility::mock_constants::BATCH_VALIDATION_WITH_ERROR;
56 use crate::utility::mock_constants::BATCH_VALIDATION_ERROR_ONLY;
57 use crate::utility::mock_constants::BATCH_VALIDATION_NO_ERROR;
58
59 #[test]
60 fn test_validation_invalid_json() {
61 let validation_res: SerdeResult<ZBValidation> = from_str("");
62 assert!(validation_res.is_err());
63 }
64
65 #[test]
66 fn test_validation_missing_expected_fields() {
67 let validation_res: SerdeResult<ZBValidation> = from_str(VALIDATION_RESPONSE_NULL_FIELDS);
68 assert!(validation_res.is_ok());
69
70 let validation = validation_res.unwrap();
71 assert_eq!(validation.did_you_mean, None);
72 assert_eq!(validation.domain_age_days, Some("".to_string()));
73 }
74
75 #[test]
76 fn test_validation_invalid_email_status() {
77 let validation_res: SerdeResult<ZBValidation> = from_str(VALIDATION_RESPONSE_INVALID);
78 assert!(validation_res.is_ok());
79
80 let validation = validation_res.unwrap();
81 assert_eq!(validation.status, "invalid".to_string());
82 assert_eq!(validation.sub_status, "mailbox_not_found".to_string());
83 assert_eq!(validation.did_you_mean, None);
84 assert_eq!(validation.smtp_provider, Some("example".to_string()));
85 assert_eq!(validation.free_email, false);
86
87 let expected_date = NaiveDateTime::new(
88 chrono::NaiveDate::from_ymd_opt(2023, 3, 23).unwrap(),
89 chrono::NaiveTime::from_hms_milli_opt(12, 30, 28, 3).unwrap(),
90 );
91 assert_eq!(validation.processed_at, expected_date);
92 }
93
94 #[test]
95 fn test_validation_valid_email_status() {
96 let validation_res: SerdeResult<ZBValidation> = from_str(VALIDATION_RESPONSE_VALID);
97 assert!(validation_res.is_ok());
98
99 let validation = validation_res.unwrap();
100 assert_eq!(validation.status, "valid".to_string());
101 assert_eq!(validation.sub_status, "".to_string());
102 assert_eq!(validation.did_you_mean, None);
103 assert_eq!(validation.smtp_provider, Some("example".to_string()));
104 assert_eq!(validation.free_email, false);
105
106 let expected_date = NaiveDateTime::new(
107 chrono::NaiveDate::from_ymd_opt(2023, 3, 23).unwrap(),
108 chrono::NaiveTime::from_hms_milli_opt(13, 30, 28, 105).unwrap(),
109 );
110 assert_eq!(validation.processed_at, expected_date);
111 }
112
113 #[test]
114 fn test_batch_error_only_content() {
115 let batch: SerdeResult<ZBBatchValidation> = from_str(BATCH_VALIDATION_ERROR_ONLY);
116 assert!(batch.is_ok());
117
118 let batch_object = batch.unwrap();
119 assert_eq!(batch_object.email_batch.len(), 0);
120 assert_eq!(batch_object.errors.len(), 1);
121 }
122
123 #[test]
124 fn test_batch_validation_and_error_content() {
125 let batch: SerdeResult<ZBBatchValidation> = from_str(BATCH_VALIDATION_WITH_ERROR);
126 assert!(batch.is_ok());
127
128 let batch_object = batch.unwrap();
129 assert_eq!(batch_object.email_batch.len(), 1);
130 assert_eq!(batch_object.errors.len(), 1);
131 }
132
133 #[test]
134 fn test_batch_validation_only_content() {
135 let batch: SerdeResult<ZBBatchValidation> = from_str(BATCH_VALIDATION_NO_ERROR);
136 assert!(batch.is_ok());
137
138 let batch_object = batch.unwrap();
139 assert_eq!(batch_object.email_batch.len(), 1);
140 assert_eq!(batch_object.errors.len(), 0);
141 }
142
143}