1 /*
2  * Copyright (C) 2006-2021 Registro.br. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  * 1. Redistribution of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY REGISTRO.BR ``AS IS AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIE OF FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16  * EVENT SHALL REGISTRO.BR BE LIABLE FOR ANY DIRECT, INDIRECT,
17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
19  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
21  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
22  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
23  * DAMAGE.
24  */
25 /* $Id$ */
26 #if USE_BR_DOMAINS
27 #include <string>
28 #include <memory>
29 #include <iostream>
30 
31 #include "libepp_nicbr.H"
32 #include "StrUtil.H"
33 
34 #include "BrDomainInfoTest.H"
35 #include "BrDomainInfo.H"
36 #include "FileUtil.H"
37 #include "IoException.H"
38 #include "XmlException.H"
39 
40 using std::cout;
41 using std::endl;
42 
43 LIBEPP_NICBR_NS_USE
44 
45 CPPUNIT_TEST_SUITE_REGISTRATION(BrDomainInfoTest);
46 
BrDomainInfoTest()47 BrDomainInfoTest::BrDomainInfoTest() {}
48 
~BrDomainInfoTest()49 BrDomainInfoTest::~BrDomainInfoTest() {}
50 
setUp()51 void BrDomainInfoTest::setUp() {}
52 
tearDown()53 void BrDomainInfoTest::tearDown() {}
54 
set_xml_template_test()55 void BrDomainInfoTest::set_xml_template_test()
56 {
57 	string to_be_parsed =
58 		"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
59 		"<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' "
60 		"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
61 		"xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0 "
62 		"epp-1.0.xsd'>"
63 		"<command>"
64 		"<info>"
65 		"<domain:info "
66 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
67 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
68 		"domain-1.0.xsd'>"
69 		"<domain:name hosts='$(hosts_control)$'>$(name)$</domain:name>"
70 		"$(auth_info)$"
71 		"</domain:info>"
72 		"</info>"
73 		"$(extension)$"
74 		"$(clTRID)$"
75 		"</command>"
76 		"</epp>";
77 
78 	string expected =
79 		"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
80 		"<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' "
81 		"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
82 		"xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0 "
83 		"epp-1.0.xsd'>"
84 		"<command>"
85 		"<info>"
86 		"<domain:info "
87 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
88 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
89 		"domain-1.0.xsd'>"
90 		"<domain:name hosts='all'>example.com.br</domain:name>"
91 		"</domain:info>"
92 		"</info>"
93 		"<extension>"
94 		"<brdomain:info "
95 		"xmlns:brdomain='urn:ietf:params:xml:ns:brdomain-1.0' "
96 		"xsi:schemaLocation='urn:ietf:params:xml:ns:brdomain-1.0 "
97 		"brdomain-1.0.xsd'>"
98 		"<brdomain:ticketNumber>123456</brdomain:ticketNumber>"
99 		"</brdomain:info>"
100 		"</extension>"
101 		"<clTRID>ABC-12345</clTRID>"
102 		"</command>"
103 		"</epp>";
104 
105 	BrDomainInfo br_domain_info;
106 	BrDomainInfoCmd* br_domain_info_cmd = br_domain_info.get_command();
107 	br_domain_info_cmd->set_name("example.com.br");
108 	br_domain_info_cmd->set_hosts_control("all");
109 	br_domain_info_cmd->set_ticketNumber(123456);
110 
111 	br_domain_info.get_command()->set_clTRID("ABC-12345");
112 	br_domain_info.set_xml_template(to_be_parsed);
113 
114 	CPPUNIT_ASSERT_EQUAL(expected, br_domain_info.get_xml());
115 
116 	// tests reset method
117 	br_domain_info_cmd->reset();
118 
119 	//parent attributes
120 	CPPUNIT_ASSERT(br_domain_info_cmd->get_name() == "");
121 	CPPUNIT_ASSERT(br_domain_info_cmd->get_hosts_control() == "all");
122 	CPPUNIT_ASSERT(br_domain_info_cmd->get_authInfo().get_pw() == "");
123 	CPPUNIT_ASSERT(br_domain_info_cmd->get_authInfo().get_roid() == "");
124 
125 	//BrDomainInfo specific
126 	CPPUNIT_ASSERT_EQUAL(0, br_domain_info_cmd->get_ticketNumber());
127 }
128 
command_test()129 void BrDomainInfoTest::command_test()
130 {
131 	BrDomainInfo domain_info;
132 	BrDomainInfoCmd *domain_info_cmd = domain_info.get_command();
133 
134 	domain_info_cmd->set_name("EmmaWatsonIsCharming.com");
135 	domain_info_cmd->set_hosts_control("sub");
136 
137 	AuthInfo auth;
138 	auth.set_roid("SH8013-REP");
139 	auth.set_pw("abc123");
140 	domain_info_cmd->set_authInfo(auth);
141 
142 	bool exception_caught = false;
143 	try {
144 		string xml_template =
145 			FileUtil::read_file("../docs/templates/br_domain_info.xml");
146 
147 		domain_info.get_command()->set_clTRID("ABC-12345");
148 		domain_info.set_xml_template(xml_template);
149 
150 		DomParser parser;
151 		parser.enable_validation("../docs/schemas");
152 		parser.parse_command(domain_info.get_xml());
153 	} catch (const IoException &e) {
154 		exception_caught = true;
155 		printf("\nIO Exception: code [%d] message [%s]",
156 		       e.get_code(), e.get_msg().c_str());
157 	} catch (const XmlException &e) {
158 		exception_caught = true;
159 		printf("\nXml Exception: code [%d] message [%s] low level message [%s]\n",
160 		       e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
161 	}
162 
163 	CPPUNIT_ASSERT(!exception_caught);
164 }
165 
response_test()166 void BrDomainInfoTest::response_test()
167 {
168 	response_test(true);
169 	response_test(false);
170 }
171 
response_test(bool withDNSSECExtension)172 void BrDomainInfoTest::response_test(bool withDNSSECExtension)
173 {
174 	string expected =
175 		"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
176 		"<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' "
177 		"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
178 		"xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0 "
179 		"epp-1.0.xsd'>"
180 		"<response>"
181 		"<result code='1000'>"
182 		"<msg>Command completed successfully</msg>"
183 		"</result>"
184 		"<resData>"
185 		"<domain:infData "
186 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
187 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
188 		"domain-1.0.xsd'>"
189 		"<domain:name>example.com.br</domain:name>"
190 		"<domain:roid>EXAMPLE1-REP</domain:roid>"
191 		"<domain:status s='pendingCreate'/>"
192 		"<domain:contact type='admin'>fan</domain:contact>"
193 		"<domain:contact type='billing'>fan</domain:contact>"
194 		"<domain:contact type='tech'>fan</domain:contact>"
195 		"<domain:ns>"
196 		"<domain:hostAttr>"
197 		"<domain:hostName>ns1.example.net.br</domain:hostName>"
198 		"</domain:hostAttr>"
199 		"<domain:hostAttr>"
200 		"<domain:hostName>ns1.example.com.br</domain:hostName>"
201 		"<domain:hostAddr ip='v4'>192.0.2.1</domain:hostAddr>"
202 		"</domain:hostAttr>"
203 		"</domain:ns>"
204 		"<domain:clID>ClientX</domain:clID>"
205 		"<domain:crID>ClientX</domain:crID>"
206 		"<domain:crDate>2006-01-30T22:00:00.0Z</domain:crDate>"
207 		"<domain:upID>ClientX</domain:upID>"
208 		"<domain:upDate>2006-01-31T09:00:00.0Z</domain:upDate>"
209 		"</domain:infData>"
210 		"</resData>"
211 		"<extension>";
212 
213 	if (withDNSSECExtension) {
214 		expected +=
215 			"<secDNS:infData "
216 			"xmlns:secDNS=\"urn:ietf:params:xml:ns:secDNS-1.0\" "
217 			"xsi:schemaLocation=\"urn:ietf:params:xml:ns:secDNS-1.0 "
218 			"secDNS-1.0.xsd\">"
219 			"<secDNS:dsData>"
220 			"<secDNS:keyTag>12345</secDNS:keyTag>"
221 			"<secDNS:alg>3</secDNS:alg>"
222 			"<secDNS:digestType>1</secDNS:digestType>"
223 			"<secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest>"
224 			"<secDNS:maxSigLife>604800</secDNS:maxSigLife>"
225 			"<secDNS:keyData>"
226 			"<secDNS:flags>256</secDNS:flags>"
227 			"<secDNS:protocol>3</secDNS:protocol>"
228 			"<secDNS:alg>1</secDNS:alg>"
229 			"<secDNS:pubKey>AQPJ////4Q==</secDNS:pubKey>"
230 			"</secDNS:keyData>"
231 			"</secDNS:dsData>"
232 			"<secDNS:dsData>"
233 			"<secDNS:keyTag>12345</secDNS:keyTag>"
234 			"<secDNS:alg>3</secDNS:alg>"
235 			"<secDNS:digestType>1</secDNS:digestType>"
236 			"<secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest>"
237 			"</secDNS:dsData>"
238 			"</secDNS:infData>";
239 	}
240 
241 	expected +=
242 		"<brdomain:infData "
243 		"xmlns:brdomain='urn:ietf:params:xml:ns:brdomain-1.0' "
244 		"xsi:schemaLocation='urn:ietf:params:xml:ns:brdomain-1.0 "
245 		"brdomain-1.0.xsd'>"
246 		"<brdomain:ticketNumber>123456</brdomain:ticketNumber>"
247 		"<brdomain:organization>"
248 		"005.506.560/0001-36"
249 		"</brdomain:organization>"
250 		"<brdomain:releaseProcessFlags flag2='1'/>"
251 		"<brdomain:pending>"
252 		"<brdomain:doc status='notReceived'>"
253 		"<brdomain:docType>CNPJ</brdomain:docType>"
254 		"<brdomain:limit>2006-03-01T22:00:00.0Z</brdomain:limit>"
255 		"<brdomain:description lang='pt'>"
256 		"Cadastro Nacional da Pessoa Jur�dica"
257 		"</brdomain:description>"
258 		"</brdomain:doc>"
259 		"<brdomain:dns status='queryTimeOut'>"
260 		"<brdomain:hostName>"
261 		"ns1.example.com.br"
262 		"</brdomain:hostName>"
263 		"<brdomain:limit>2006-02-13T22:00:00.0Z</brdomain:limit>"
264 		"</brdomain:dns>"
265 		"<brdomain:dns status='notInformed'>"
266 		"<brdomain:limit>2006-02-13T22:00:00.0Z</brdomain:limit>"
267 		"</brdomain:dns>"
268 		"<brdomain:releaseProc status='waiting'>"
269 		"<brdomain:limit>2006-02-01T22:00:00.0Z</brdomain:limit>"
270 		"</brdomain:releaseProc>"
271 		"</brdomain:pending>"
272 		"<brdomain:ticketNumberConc>"
273 		"123451"
274 		"</brdomain:ticketNumberConc>"
275 		"<brdomain:ticketNumberConc>"
276 		"123455"
277 		"</brdomain:ticketNumberConc>"
278 		"</brdomain:infData>"
279 		"</extension>"
280 		"<trID>"
281 		"<clTRID>ABC-12345</clTRID>"
282 		"<svTRID>54322-XYZ</svTRID>"
283 		"</trID>"
284 		"</response>"
285 		"</epp>";
286 
287 	string utf8_expected;
288 	StrUtil::iso88591_to_utf8(expected, utf8_expected);
289 
290 	DomParser parser;
291 	parser.enable_validation("../docs/schemas");
292 
293 	BrDomainInfo domain_info;
294 
295 	bool exception_caught = false;
296 	try {
297 		domain_info.set_response(utf8_expected, &parser);
298 	} catch (const XmlException &e) {
299 		exception_caught = true;
300 		printf("\nXml Exception: code [%d] message [%s] low level message [%s]\n",
301 		       e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
302 		cout << endl << domain_info.get_xml() << endl;
303 	}
304 	CPPUNIT_ASSERT(!exception_caught);
305 
306 	BrDomainInfoRsp* domain_info_rsp = domain_info.get_response();
307 
308 	CPPUNIT_ASSERT(domain_info_rsp != 0);
309 
310 	map <Response::ResultCode, Response::ResultInfo> results;
311 	map <Response::ResultCode, Response::ResultInfo>::const_iterator r_it;
312 	results = domain_info_rsp->get_result_list();
313 	r_it = results.begin();
314 
315 	CPPUNIT_ASSERT(r_it != results.end());
316 	CPPUNIT_ASSERT_EQUAL(Response::OK, r_it->first);
317 
318 	string result_code =
319 		StrUtil::to_string("%d", (int)r_it->first);
320 
321 	string response =
322 		"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
323 		"<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' "
324 		"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
325 		"xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0 "
326 		"epp-1.0.xsd'>"
327 		"<response>"
328 		"<result code='" + result_code + "'>"
329 		"<msg";
330 
331 	string result_lang = domain_info_rsp->get_result_lang();
332 	if (result_lang != "en") {
333 		response += " lang='" + result_lang + "'";
334 	}
335 
336 	response +=
337 		">" + r_it->second.msg + "</msg>"
338 		"</result>"
339 		"<resData>"
340 		"<domain:infData "
341 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
342 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
343 		"domain-1.0.xsd'>";
344 
345 	//get_name
346 	//get_roid
347 	response +=
348 		"<domain:name>" + domain_info_rsp->get_name() + "</domain:name>"
349 		"<domain:roid>" + domain_info_rsp->get_roid() + "</domain:roid>";
350 
351 	//get_status_set
352 	set<string> status_set = domain_info_rsp->get_status_set();
353 	set<string>::const_iterator it;
354 	for (it = status_set.begin(); it != status_set.end(); it++) {
355 		response += "<domain:status s='" + (*it) + "'/>";
356 	}
357 
358 	//get_contacts
359 	map< string, string, less<string> > contacts =
360 		domain_info_rsp->get_contacts();
361 	map< string, string, less<string> >::const_iterator it_map;
362 	for (it_map = contacts.begin(); it_map != contacts.end(); it_map++) {
363 		response += "<domain:contact type='" + (*it_map).first + "'>" +
364 			(*it_map).second + "</domain:contact>";
365 	}
366 
367 	//get_nameservers
368 	response += "<domain:ns>";
369 	vector<struct NameServer> nameservers = domain_info_rsp->get_nameservers();
370 	vector<struct NameServer>::const_iterator it_ns;
371 	set<struct NSIPAddr>::const_iterator it_ip;
372 	for (it_ns = nameservers.begin(); it_ns != nameservers.end(); it_ns++) {
373 		response += "<domain:hostAttr>" ;
374 		response += "<domain:hostName>" + it_ns->name + "</domain:hostName>";
375 		for (it_ip = it_ns->ips.begin(); it_ip != it_ns->ips.end(); it_ip++) {
376 			response += "<domain:hostAddr";
377 			if ((*it_ip).version != "") {
378 				response += " ip='" + (*it_ip).version + "'";
379 			}
380 			response += ">" + (*it_ip).addr + "</domain:hostAddr>";
381 		}
382 		response += "</domain:hostAttr>";
383 	}
384 	response += "</domain:ns>";
385 
386 	//get_clID
387 	response += "<domain:clID>" + domain_info_rsp->get_clID() +
388 		"</domain:clID>";
389 
390 	//get_crID
391 	//get_crDate
392 	response += "<domain:crID>" + domain_info_rsp->get_crID() + "</domain:crID>"
393 		"<domain:crDate>" + domain_info_rsp->get_crDate() + "</domain:crDate>";
394 
395 	//get_upID
396 	response += "<domain:upID>" + domain_info_rsp->get_upID() + "</domain:upID>";
397 
398 	//get_upDate
399 	response +=
400 		"<domain:upDate>" + domain_info_rsp->get_upDate() + "</domain:upDate>";
401 
402 	response +=
403 		"</domain:infData>"
404 		"</resData>";
405 
406 	response +=
407 		"<extension>";
408 
409 	// secDNS extension
410 	list<DSInfo> dsInfoList = domain_info_rsp->get_dsInfo();
411 
412 	if (!dsInfoList.empty()) {
413 		response += "<secDNS:infData "
414 			"xmlns:secDNS=\"urn:ietf:params:xml:ns:secDNS-1.0\" "
415 			"xsi:schemaLocation=\"urn:ietf:params:xml:ns:secDNS-1.0 "
416 			"secDNS-1.0.xsd\">";
417 
418 		list<DSInfo>::iterator ds_it;
419 		for (ds_it = dsInfoList.begin(); ds_it != dsInfoList.end(); ds_it++) {
420 			response +=
421 				"<secDNS:dsData>"
422 				"<secDNS:keyTag>" + StrUtil::to_string("%d", (*ds_it).get_key_tag()) +
423 				"</secDNS:keyTag>"
424 				"<secDNS:alg>" + StrUtil::to_string("%d", (*ds_it).get_algo()) +
425 				"</secDNS:alg>"
426 				"<secDNS:digestType>" +
427 				StrUtil::to_string("%d", (*ds_it).get_digest_type()) +
428 				"</secDNS:digestType>"
429 				"<secDNS:digest>" + (*ds_it).get_digest() + "</secDNS:digest>";
430 
431 			unsigned int maxSigLife = (*ds_it).get_max_sig_life();
432 			if (maxSigLife > 0) {
433 				response += "<secDNS:maxSigLife>" +
434 					StrUtil::to_string("%d", maxSigLife) + "</secDNS:maxSigLife>";
435 			}
436 
437 			if ((*ds_it).hasKeyData()) {
438 				KeyData kd = (*ds_it).get_key_data();
439 				response +=
440 					"<secDNS:keyData>"
441 					"<secDNS:flags>" + StrUtil::to_string("%d", kd.get_flags()) +
442 					"</secDNS:flags>"
443 					"<secDNS:protocol>" + StrUtil::to_string("%d", kd.get_protocol()) +
444 					"</secDNS:protocol>"
445 					"<secDNS:alg>" + StrUtil::to_string("%d", kd.get_algorithm()) +
446 					"</secDNS:alg>"
447 					"<secDNS:pubKey>" + kd.get_pub_key() + "</secDNS:pubKey>"
448 					"</secDNS:keyData>";
449 			}
450 
451 			response += "</secDNS:dsData>";
452 		}
453 		response += "</secDNS:infData>";
454 	}
455 
456 	// brdomain extension
457 	response +=
458 		"<brdomain:infData "
459 		"xmlns:brdomain='urn:ietf:params:xml:ns:brdomain-1.0' "
460 		"xsi:schemaLocation='urn:ietf:params:xml:ns:brdomain-1.0 "
461 		"brdomain-1.0.xsd'>"
462 		"<brdomain:ticketNumber>" +
463 		StrUtil::to_string("%d", domain_info_rsp->get_ticketNumber()) +
464 		"</brdomain:ticketNumber>"
465 		"<brdomain:organization>" + domain_info_rsp->get_organization() +
466 		"</brdomain:organization>";
467 
468 	// Release Process Flags
469 	struct ReleaseProcessFlags rpf = domain_info_rsp->get_releaseProcessFlags();
470 	if (rpf.flag1 == 1 || rpf.flag2 == 1 || rpf.flag3 == 1) {
471 		response +=
472 			"<brdomain:releaseProcessFlags";
473 		if (rpf.flag1 == 1) {
474 			response += " flag1='1'";
475 		}
476 		if (rpf.flag2 == 1) {
477 			response += " flag2='1'";
478 		}
479 		if (rpf.flag3 == 1) {
480 			response += " flag3='1'";
481 		}
482 		response += "/>";
483 	}
484 
485 	// Pendings
486 	response +=
487 		"<brdomain:pending>";
488 
489 	PENDING_CONTAINER<struct PendingDoc> doc_pendings =
490 		domain_info_rsp->get_doc_pendings();
491 	PENDING_CONTAINER<struct PendingDoc>::const_iterator doc_it;
492 
493 	for (doc_it = doc_pendings.begin(); doc_it != doc_pendings.end(); doc_it++) {
494 		response +=
495 			"<brdomain:doc status='" + (*doc_it).status + "'>"
496 			"<brdomain:docType>" + (*doc_it).docType + "</brdomain:docType>"
497 			"<brdomain:limit>" + (*doc_it).limit + "</brdomain:limit>"
498 
499 			"<brdomain:description";
500 		if ((*doc_it).description_lang != "") {
501 			response += " lang='" + (*doc_it).description_lang + "'";
502 		}
503 
504 		response += ">" + (*doc_it).description +
505 			"</brdomain:description>"
506 
507 			"</brdomain:doc>";
508 	}
509 
510 	PENDING_CONTAINER<struct PendingDns> dns_pendings =
511 		domain_info_rsp->get_dns_pendings();
512 	PENDING_CONTAINER<struct PendingDns>::const_iterator dns_it;
513 
514 	for (dns_it = dns_pendings.begin(); dns_it != dns_pendings.end(); dns_it++) {
515 		response += "<brdomain:dns status='" + (*dns_it).status + "'>";
516 		if ((*dns_it).hostName != "") {
517 			response += "<brdomain:hostName>" + (*dns_it).hostName +
518 				"</brdomain:hostName>";
519 		}
520 		response += "<brdomain:limit>" + (*dns_it).limit + "</brdomain:limit>"
521 			"</brdomain:dns>";
522 	}
523 
524 	struct PendingReleaseProc rel_pending = domain_info_rsp->get_rel_pending();
525 	if (rel_pending.status != "") {
526 		response +=
527 			"<brdomain:releaseProc status='" + rel_pending.status + "'>"
528 			"<brdomain:limit>" + rel_pending.limit + "</brdomain:limit>"
529 			"</brdomain:releaseProc>";
530 	}
531 
532 	response += "</brdomain:pending>";
533 
534 	set<int> concurrent_tickets = domain_info_rsp->get_concurrent_tickets();
535 	set<int>::const_iterator tkt_it;
536 	for (tkt_it = concurrent_tickets.begin(); tkt_it != concurrent_tickets.end();
537 	     tkt_it++) {
538 		response +=
539 			"<brdomain:ticketNumberConc>" + StrUtil::to_string("%d", (*tkt_it)) +
540 			"</brdomain:ticketNumberConc>";
541 	}
542 
543 	response +=
544 		"</brdomain:infData>"
545 		"</extension>"
546 		"<trID>"
547 		"<clTRID>" + domain_info_rsp->get_clTRID() + "</clTRID>"
548 		"<svTRID>" + domain_info_rsp->get_svTRID() + "</svTRID>"
549 		"</trID>"
550 		"</response>"
551 		"</epp>";
552 
553 	CPPUNIT_ASSERT_EQUAL(expected, response);
554 
555 	// tests reset method
556 	domain_info_rsp->reset();
557 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_name());
558 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_roid());
559 	CPPUNIT_ASSERT(domain_info_rsp->get_status_set().empty());
560 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_registrant());
561 	CPPUNIT_ASSERT(domain_info_rsp->get_contacts().empty());
562 	CPPUNIT_ASSERT(domain_info_rsp->get_nameservers().empty());
563 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_clID());
564 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_crID());
565 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_crDate());
566 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_upID());
567 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_exDate());
568 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_upDate());
569 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_trDate());
570 	CPPUNIT_ASSERT_EQUAL((const string)"",
571 	                     domain_info_rsp->get_authInfo().get_roid());
572 	CPPUNIT_ASSERT_EQUAL((const string)"",
573 	                     domain_info_rsp->get_authInfo().get_pw());
574 
575 	// BrDomainInfoRsp specific attributes
576 	CPPUNIT_ASSERT_EQUAL(0, domain_info_rsp->get_ticketNumber());
577 	CPPUNIT_ASSERT_EQUAL((string)"", domain_info_rsp->get_organization());
578 
579 	rpf = domain_info_rsp->get_releaseProcessFlags();
580 	CPPUNIT_ASSERT_EQUAL(0, rpf.flag1 + rpf.flag2 + rpf.flag3);
581 
582 	CPPUNIT_ASSERT_EQUAL(true, domain_info_rsp->get_doc_pendings().empty());
583 	CPPUNIT_ASSERT_EQUAL(true, domain_info_rsp->get_dns_pendings().empty());
584 	CPPUNIT_ASSERT_EQUAL((string)"", domain_info_rsp->get_rel_pending().status);
585 	CPPUNIT_ASSERT_EQUAL((string)"", domain_info_rsp->get_rel_pending().limit);
586 	CPPUNIT_ASSERT_EQUAL(true, domain_info_rsp->get_concurrent_tickets().empty());
587 }
588 
589 
response_test2()590 void BrDomainInfoTest::response_test2()
591 {
592 	string expected =
593 		"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
594 		"<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' "
595 		"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
596 		"xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0 "
597 		"epp-1.0.xsd'>"
598 		"<response>"
599 		"<result code='1000'>"
600 		"<msg>Command completed successfully</msg>"
601 		"</result>"
602 		"<resData>"
603 		"<domain:infData "
604 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
605 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
606 		"domain-1.0.xsd'>"
607 		"<domain:name>example.com.br</domain:name>"
608 		"<domain:roid>EXAMPLE1-REP</domain:roid>"
609 		"<domain:status s='pendingCreate'/>"
610 		"<domain:contact type='admin'>fan</domain:contact>"
611 		"<domain:contact type='billing'>fan</domain:contact>"
612 		"<domain:contact type='tech'>fan</domain:contact>"
613 		"<domain:ns>"
614 		"<domain:hostAttr>"
615 		"<domain:hostName>ns1.example.com.br</domain:hostName>"
616 		"<domain:hostAddr ip='v4'>192.0.2.1</domain:hostAddr>"
617 		"</domain:hostAttr>"
618 		"<domain:hostAttr>"
619 		"<domain:hostName>ns1.example.net.br</domain:hostName>"
620 		"</domain:hostAttr>"
621 		"</domain:ns>"
622 		"<domain:clID>ClientX</domain:clID>"
623 		"<domain:crID>ClientX</domain:crID>"
624 		"<domain:crDate>2006-01-30T22:00:00.0Z</domain:crDate>"
625 		"<domain:upID>ClientX</domain:upID>"
626 		"<domain:upDate>2006-01-31T09:00:00.0Z</domain:upDate>"
627 		"</domain:infData>"
628 		"</resData>"
629 		"<extension>"
630 		"<brdomain:infData "
631 		"xmlns:brdomain='urn:ietf:params:xml:ns:brdomain-1.0' "
632 		"xsi:schemaLocation='urn:ietf:params:xml:ns:brdomain-1.0 "
633 		"brdomain-1.0.xsd'>"
634 		"<brdomain:organization>"
635 		"005.506.560/0001-36"
636 		"</brdomain:organization>"
637 		"<brdomain:publicationStatus publicationFlag=\"onHold\">"
638 		"<brdomain:onHoldReason>billing</brdomain:onHoldReason>"
639 		"<brdomain:onHoldReason>dns</brdomain:onHoldReason>"
640 		"</brdomain:publicationStatus>"
641 		"<brdomain:autoRenew active=\"1\"/>"
642 		"</brdomain:infData>"
643 		"</extension>"
644 		"<trID>"
645 		"<clTRID>ABC-12345</clTRID>"
646 		"<svTRID>54322-XYZ</svTRID>"
647 		"</trID>"
648 		"</response>"
649 		"</epp>";
650 
651 	string utf8_expected;
652 	StrUtil::iso88591_to_utf8(expected, utf8_expected);
653 
654 	DomParser parser;
655 	parser.enable_validation("../docs/schemas");
656 
657 	BrDomainInfo domain_info;
658 
659 	bool exception_caught = false;
660 	try {
661 		domain_info.set_response(utf8_expected, &parser);
662 	} catch (const XmlException &e) {
663 		exception_caught = true;
664 		printf("\nXml Exception: code [%d] message [%s] low level message [%s]\n",
665 		       e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
666 		cout << endl << domain_info.get_xml() << endl;
667 	}
668 	CPPUNIT_ASSERT(!exception_caught);
669 
670 	BrDomainInfoRsp* domain_info_rsp = domain_info.get_response();
671 
672 	CPPUNIT_ASSERT(domain_info_rsp != 0);
673 
674 	map <Response::ResultCode, Response::ResultInfo> results;
675 	map <Response::ResultCode, Response::ResultInfo>::const_iterator r_it;
676 	results = domain_info_rsp->get_result_list();
677 	r_it = results.begin();
678 
679 	CPPUNIT_ASSERT(r_it != results.end());
680 	CPPUNIT_ASSERT_EQUAL(Response::OK, r_it->first);
681 
682 	string result_code =
683 		StrUtil::to_string("%d", (int)r_it->first);
684 
685 	string response =
686 		"<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
687 		"<epp xmlns='urn:ietf:params:xml:ns:epp-1.0' "
688 		"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' "
689 		"xsi:schemaLocation='urn:ietf:params:xml:ns:epp-1.0 "
690 		"epp-1.0.xsd'>"
691 		"<response>"
692 		"<result code='" + result_code + "'>"
693 		"<msg";
694 
695 	string result_lang = domain_info_rsp->get_result_lang();
696 	if (result_lang != "en") {
697 		response += " lang='" + result_lang + "'";
698 	}
699 
700 	response +=
701 		">" + r_it->second.msg + "</msg>"
702 		"</result>"
703 		"<resData>"
704 		"<domain:infData "
705 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
706 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
707 		"domain-1.0.xsd'>";
708 
709 	//get_name
710 	//get_roid
711 	response +=
712 		"<domain:name>" + domain_info_rsp->get_name() + "</domain:name>"
713 		"<domain:roid>" + domain_info_rsp->get_roid() + "</domain:roid>";
714 
715 	//get_status_set
716 	set<string> status_set = domain_info_rsp->get_status_set();
717 	set<string>::const_iterator it;
718 	for (it = status_set.begin(); it != status_set.end(); it++) {
719 		response += "<domain:status s='" + (*it) + "'/>";
720 	}
721 
722 	//get_contacts
723 	map< string, string, less<string> > contacts =
724 		domain_info_rsp->get_contacts();
725 	map< string, string, less<string> >::const_iterator it_map;
726 	for (it_map = contacts.begin(); it_map != contacts.end(); it_map++) {
727 		response += "<domain:contact type='" + (*it_map).first + "'>" +
728 			(*it_map).second + "</domain:contact>";
729 	}
730 
731 	//get_nameservers
732 	response += "<domain:ns>";
733 	vector<struct NameServer> nameservers = domain_info_rsp->get_nameservers();
734 	vector<struct NameServer>::const_iterator it_ns;
735 	set<struct NSIPAddr>::const_iterator it_ip;
736 	for (it_ns = nameservers.begin(); it_ns != nameservers.end(); it_ns++) {
737 		response += "<domain:hostAttr>" ;
738 		response += "<domain:hostName>" + it_ns->name + "</domain:hostName>";
739 		for (it_ip = it_ns->ips.begin(); it_ip != it_ns->ips.end(); it_ip++) {
740 			response += "<domain:hostAddr";
741 			if ((*it_ip).version != "") {
742 				response += " ip='" + (*it_ip).version + "'";
743 			}
744 			response += ">" + (*it_ip).addr + "</domain:hostAddr>";
745 		}
746 		response += "</domain:hostAttr>";
747 	}
748 	response += "</domain:ns>";
749 
750 	//get_clID
751 	response += "<domain:clID>" + domain_info_rsp->get_clID() +
752 		"</domain:clID>";
753 
754 	//get_crID
755 	//get_crDate
756 	response += "<domain:crID>" + domain_info_rsp->get_crID() + "</domain:crID>"
757 		"<domain:crDate>" + domain_info_rsp->get_crDate() + "</domain:crDate>";
758 
759 	//get_upID
760 	response += "<domain:upID>" + domain_info_rsp->get_upID() + "</domain:upID>";
761 
762 	//get_upDate
763 	response +=
764 		"<domain:upDate>" + domain_info_rsp->get_upDate() + "</domain:upDate>";
765 
766 	response +=
767 		"</domain:infData>"
768 		"</resData>";
769 
770 	response +=
771 		"<extension>"
772 		"<brdomain:infData "
773 		"xmlns:brdomain='urn:ietf:params:xml:ns:brdomain-1.0' "
774 		"xsi:schemaLocation='urn:ietf:params:xml:ns:brdomain-1.0 "
775 		"brdomain-1.0.xsd'>"
776 		"<brdomain:organization>" + domain_info_rsp->get_organization() +
777 		"</brdomain:organization>";
778 
779 	string publicationFlag = domain_info_rsp->get_publication_flag();
780 
781 	response += "<brdomain:publicationStatus publicationFlag=\"" +
782 		publicationFlag + "\">";
783 
784 	set<string> onhold_reasons = domain_info_rsp->get_onhold_reasons();
785 
786 	set<string>::const_iterator tkt_it;
787 	for (tkt_it = onhold_reasons.begin(); tkt_it != onhold_reasons.end();
788 	     tkt_it++) {
789 		response +=
790 			"<brdomain:onHoldReason>" +  (*tkt_it) +
791 			"</brdomain:onHoldReason>";
792 	}
793 
794 	response +=
795 		"</brdomain:publicationStatus><brdomain:autoRenew active=\""
796 		+ StrUtil::to_string("%d", domain_info_rsp->get_auto_renew()) +
797 		"\"/></brdomain:infData>"
798 		"</extension>"
799 		"<trID>"
800 		"<clTRID>" + domain_info_rsp->get_clTRID() + "</clTRID>"
801 		"<svTRID>" + domain_info_rsp->get_svTRID() + "</svTRID>"
802 		"</trID>"
803 		"</response>"
804 		"</epp>";
805 
806 	CPPUNIT_ASSERT_EQUAL(expected, response);
807 
808 	// tests reset method
809 	domain_info_rsp->reset();
810 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_name());
811 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_roid());
812 	CPPUNIT_ASSERT(domain_info_rsp->get_status_set().empty());
813 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_registrant());
814 	CPPUNIT_ASSERT(domain_info_rsp->get_contacts().empty());
815 	CPPUNIT_ASSERT(domain_info_rsp->get_nameservers().empty());
816 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_clID());
817 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_crID());
818 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_crDate());
819 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_upID());
820 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_exDate());
821 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_upDate());
822 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_trDate());
823 	CPPUNIT_ASSERT_EQUAL((const string)"",
824 	                     domain_info_rsp->get_authInfo().get_roid());
825 	CPPUNIT_ASSERT_EQUAL((const string)"",
826 	                     domain_info_rsp->get_authInfo().get_pw());
827 
828 	// BrDomainInfoRsp specific attributes
829 	CPPUNIT_ASSERT_EQUAL((string)"", domain_info_rsp->get_organization());
830 	CPPUNIT_ASSERT_EQUAL((string)"", domain_info_rsp->get_publication_flag());
831 	CPPUNIT_ASSERT_EQUAL(true, domain_info_rsp->get_onhold_reasons().empty());
832 	CPPUNIT_ASSERT_EQUAL(-1, domain_info_rsp->get_auto_renew());
833 }
834 #endif //USE_BR_DOMAINS
835