1use chrono::{DateTime, Utc};
4use instant_xml::{FromXml, ToXml};
5
6use super::{ContactAuthInfo, Fax, PostalInfo, Status, Voice, XMLNS};
7use crate::common::{NoExtension, EPP_XMLNS};
8use crate::request::{Command, Transaction};
9
10impl<'a> Transaction<NoExtension> for ContactInfo<'a> {}
11
12impl<'a> Command for ContactInfo<'a> {
13 type Response = InfoData;
14 const COMMAND: &'static str = "info";
15}
16
17#[derive(Debug, ToXml)]
21#[xml(rename = "info", ns(XMLNS))]
22pub struct ContactInfoRequest<'a> {
23 id: &'a str,
25 auth_info: ContactAuthInfo<'a>,
27}
28
29#[derive(Debug, ToXml)]
31#[xml(rename = "info", ns(EPP_XMLNS))]
32pub struct ContactInfo<'a> {
33 info: ContactInfoRequest<'a>,
35}
36
37impl<'a> ContactInfo<'a> {
38 pub fn new(id: &'a str, auth_password: &'a str) -> ContactInfo<'a> {
39 Self {
40 info: ContactInfoRequest {
41 id,
42 auth_info: ContactAuthInfo::new(auth_password),
43 },
44 }
45 }
46}
47
48#[derive(Debug, FromXml)]
52#[xml(rename = "infData", ns(XMLNS))]
53pub struct InfoData {
54 pub id: String,
56 pub roid: String,
58 pub statuses: Vec<Status>,
60 pub postal_info: PostalInfo<'static>,
62 pub voice: Option<Voice<'static>>,
64 pub fax: Option<Fax<'static>>,
66 pub email: String,
68 #[xml(rename = "clID")]
70 pub client_id: String,
71 #[xml(rename = "crID")]
73 pub creator_id: String,
74 #[xml(rename = "crDate")]
76 pub created_at: DateTime<Utc>,
77 #[xml(rename = "upID")]
79 pub updater_id: Option<String>,
80 #[xml(rename = "upDate")]
82 pub updated_at: Option<DateTime<Utc>>,
83 #[xml(rename = "trDate")]
85 pub transferred_at: Option<DateTime<Utc>>,
86 #[xml(rename = "authInfo")]
88 pub auth_info: Option<ContactAuthInfo<'static>>,
89}
90
91#[cfg(test)]
92mod tests {
93 use chrono::{TimeZone, Utc};
94
95 use super::ContactInfo;
96 use crate::contact::Status;
97 use crate::response::ResultCode;
98 use crate::tests::{assert_serialized, response_from_file, CLTRID, SUCCESS_MSG, SVTRID};
99
100 #[test]
101 fn command() {
102 let object = ContactInfo::new("eppdev-contact-3", "eppdev-387323");
103 assert_serialized("request/contact/info.xml", &object);
104 }
105
106 #[test]
107 fn response() {
108 let object = response_from_file::<ContactInfo>("response/contact/info.xml");
109
110 let result = object.res_data().unwrap();
111 let fax = result.fax.as_ref().unwrap();
112 let voice_ext = result.voice.as_ref().unwrap().extension.as_ref().unwrap();
113 let fax_ext = fax.extension.as_ref().unwrap();
114 let auth_info = result.auth_info.as_ref().unwrap();
115
116 assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
117 assert_eq!(object.result.message, SUCCESS_MSG);
118 assert_eq!(result.id, "eppdev-contact-3");
119 assert_eq!(result.roid, "UNDEF-ROID");
120 assert_eq!(result.statuses[0], Status::Ok);
121 assert_eq!(result.postal_info.info_type, "loc");
122 assert_eq!(result.postal_info.name, "John Doe");
123 assert_eq!(result.postal_info.organization, Some("Acme Widgets".into()));
124 assert_eq!(result.postal_info.address.street[0], "58");
125 assert_eq!(result.postal_info.address.street[1], "Orchid Road");
126 assert_eq!(result.postal_info.address.city, "Paris");
127 assert_eq!(result.postal_info.address.province, Some("Paris".into()));
128 assert_eq!(
129 result.postal_info.address.postal_code,
130 Some("392374".into())
131 );
132 assert_eq!(result.postal_info.address.country.alpha2, "FR");
133 assert_eq!(
134 result.voice.as_ref().unwrap().number,
135 "+33.47237942".to_string()
136 );
137 assert_eq!(*voice_ext, "123".to_string());
138 assert_eq!(fax.number, "+33.86698799".to_string());
139 assert_eq!(*fax_ext, "243".to_string());
140 assert_eq!(result.email, "contact@eppdev.net");
141 assert_eq!(result.client_id, "eppdev");
142 assert_eq!(result.creator_id, "SYSTEM");
143 assert_eq!(
144 result.created_at,
145 Utc.with_ymd_and_hms(2021, 7, 23, 13, 9, 9).unwrap(),
146 );
147 assert_eq!(*(result.updater_id.as_ref().unwrap()), "SYSTEM");
148 assert_eq!(
149 result.updated_at,
150 Utc.with_ymd_and_hms(2021, 7, 23, 13, 9, 9).single()
151 );
152 assert_eq!(auth_info.password, "eppdev-387323");
153 assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
154 assert_eq!(object.tr_ids.server_tr_id, SVTRID);
155 }
156
157 #[test]
158 fn response_minimal() {
159 let object = response_from_file::<ContactInfo>("response/contact/info_minimal.xml");
160
161 let result = object.res_data().unwrap();
162
163 assert_eq!(object.result.code, ResultCode::CommandCompletedSuccessfully);
164 assert_eq!(object.result.message, SUCCESS_MSG);
165 assert_eq!(result.id, "eppdev-contact-3");
166 assert_eq!(result.roid, "UNDEF-ROID");
167 assert_eq!(result.statuses[0], Status::Ok);
168 assert_eq!(result.postal_info.info_type, "loc");
169 assert_eq!(result.postal_info.name, "John Doe");
170 assert_eq!(result.postal_info.organization, None);
171 assert_eq!(result.postal_info.address.street[0], "58");
172 assert_eq!(result.postal_info.address.street[1], "Orchid Road");
173 assert_eq!(result.postal_info.address.city, "Paris");
174 assert_eq!(result.postal_info.address.province, None);
175 assert_eq!(result.postal_info.address.postal_code, None);
176 assert_eq!(result.postal_info.address.country.alpha2, "FR");
177 assert_eq!(result.voice, None);
178 assert_eq!(result.fax, None);
179 assert_eq!(result.email, "contact@eppdev.net");
180 assert_eq!(result.client_id, "eppdev");
181 assert_eq!(result.creator_id, "SYSTEM");
182 assert_eq!(
183 result.created_at,
184 Utc.with_ymd_and_hms(2021, 7, 23, 13, 9, 9).unwrap(),
185 );
186 assert_eq!(result.updater_id, None);
187 assert_eq!(result.updated_at, None);
188 assert_eq!(result.auth_info, None);
189 assert_eq!(object.tr_ids.client_tr_id.unwrap(), CLTRID);
190 assert_eq!(object.tr_ids.server_tr_id, SVTRID);
191 }
192}