instant_epp/contact/
info.rs

1//! Types for EPP contact info request
2
3use 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// Request
18
19/// Type for elements under the contact `<info>` tag
20#[derive(Debug, ToXml)]
21#[xml(rename = "info", ns(XMLNS))]
22pub struct ContactInfoRequest<'a> {
23    /// The contact id for the info command
24    id: &'a str,
25    /// The `<authInfo>` data
26    auth_info: ContactAuthInfo<'a>,
27}
28
29/// Type for EPP XML `<info>` command for contacts
30#[derive(Debug, ToXml)]
31#[xml(rename = "info", ns(EPP_XMLNS))]
32pub struct ContactInfo<'a> {
33    /// Data for `<info>` command for contact
34    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// Response
49
50/// Type that represents the `<infData>` tag for contact check response
51#[derive(Debug, FromXml)]
52#[xml(rename = "infData", ns(XMLNS))]
53pub struct InfoData {
54    /// The contact id
55    pub id: String,
56    /// The contact ROID
57    pub roid: String,
58    /// The list of contact statuses
59    pub statuses: Vec<Status>,
60    /// The postal info for the contact
61    pub postal_info: PostalInfo<'static>,
62    /// The voice data for the contact
63    pub voice: Option<Voice<'static>>,
64    /// The fax data for the contact
65    pub fax: Option<Fax<'static>>,
66    /// The email for the contact
67    pub email: String,
68    /// The epp user to whom the contact belongs
69    #[xml(rename = "clID")]
70    pub client_id: String,
71    /// The epp user who created the contact
72    #[xml(rename = "crID")]
73    pub creator_id: String,
74    /// The creation date
75    #[xml(rename = "crDate")]
76    pub created_at: DateTime<Utc>,
77    /// The epp user who last updated the contact
78    #[xml(rename = "upID")]
79    pub updater_id: Option<String>,
80    /// The last update date
81    #[xml(rename = "upDate")]
82    pub updated_at: Option<DateTime<Utc>>,
83    /// The contact transfer date
84    #[xml(rename = "trDate")]
85    pub transferred_at: Option<DateTime<Utc>>,
86    /// The contact auth info
87    #[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}