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 #include <memory>
27 #include <string>
28 
29 #include "libepp_nicbr.H"
30 
31 #include "DomainInfoTest.H"
32 #include "DomainInfo.H"
33 #include "FileUtil.H"
34 #include "IoException.H"
35 #include "XmlException.H"
36 
37 #include <iostream>
38 using namespace std;
39 
40 LIBEPP_NICBR_NS_USE
41 
42 CPPUNIT_TEST_SUITE_REGISTRATION(DomainInfoTest);
43 
DomainInfoTest()44 DomainInfoTest::DomainInfoTest() {}
45 
~DomainInfoTest()46 DomainInfoTest::~DomainInfoTest() {}
47 
setUp()48 void DomainInfoTest::setUp() {}
49 
tearDown()50 void DomainInfoTest::tearDown() {}
51 
set_xml_template_test()52 void DomainInfoTest::set_xml_template_test()
53 {
54 	string to_be_parsed =
55 		"<command>"
56 		"<info>"
57 		"<domain:info "
58 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
59 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
60 		"domain-1.0.xsd'>"
61 		"<domain:name hosts='$(hosts_control)$'>"
62 		"$(name)$</domain:name>"
63 		"$(auth_info)$"
64 		"</domain:info>"
65 		"</info>"
66 		"$(ext_begin)$"
67 		"$(launch_ext)$"
68 		"$(ext_end)$"
69 		"$(clTRID)$"
70 		"</command>";
71 
72 	DomainInfo domain_info;
73 	DomainInfoCmd* domain_info_cmd = domain_info.get_command();
74 	domain_info_cmd->set_name("EmmaWatsonIsCharming.com");
75 	domain_info_cmd->set_hosts_control("sub");
76 
77 	AuthInfo auth;
78 	auth.set_roid("SH8013-REP");
79 	auth.set_pw("abc123");
80 	domain_info_cmd->set_authInfo(auth);
81 
82 	domain_info.get_command()->set_clTRID("ABC-12345");
83 	domain_info.set_xml_template(to_be_parsed);
84 
85 	string expected =
86 		"<command>"
87 		"<info>"
88 		"<domain:info "
89 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
90 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
91 		"domain-1.0.xsd'>"
92 		"<domain:name hosts='sub'>EmmaWatsonIsCharming.com</domain:name>"
93 		"<domain:authInfo>"
94 		"<domain:pw roid='SH8013-REP'>abc123</domain:pw>"
95 		"</domain:authInfo>"
96 		"</domain:info>"
97 		"</info>"
98 		"<clTRID>ABC-12345</clTRID>"
99 		"</command>";
100 
101 	CPPUNIT_ASSERT_EQUAL(expected, domain_info.get_xml());
102 
103 	LaunchInfoCmd launch;
104 	launch.set_includeMark(true);
105 	launch.set_phase(LaunchPhase::CLAIMS);
106 	launch.set_applicationId("abc123");
107 	domain_info_cmd->set_launch(launch);
108 
109 	domain_info.set_xml_template(to_be_parsed);
110 
111 	expected =
112 		"<command>"
113 		"<info>"
114 		"<domain:info "
115 		"xmlns:domain='urn:ietf:params:xml:ns:domain-1.0' "
116 		"xsi:schemaLocation='urn:ietf:params:xml:ns:domain-1.0 "
117 		"domain-1.0.xsd'>"
118 		"<domain:name hosts='sub'>EmmaWatsonIsCharming.com</domain:name>"
119 		"<domain:authInfo>"
120 		"<domain:pw roid='SH8013-REP'>abc123</domain:pw>"
121 		"</domain:authInfo>"
122 		"</domain:info>"
123 		"</info>"
124 		"<extension>"
125 		"<launch:info xmlns:launch=\"urn:ietf:params:xml:ns:launch-1.0\" "
126 		"includeMark=\"true\">"
127 		"<launch:phase>claims</launch:phase>"
128 		"<launch:applicationID>abc123</launch:applicationID>"
129 		"</launch:info>"
130 		"</extension>"
131 		"<clTRID>ABC-12345</clTRID>"
132 		"</command>";
133 
134 	CPPUNIT_ASSERT_EQUAL(expected, domain_info.get_xml());
135 
136 	// tests reset method
137 	domain_info_cmd = domain_info.get_command();
138 	domain_info_cmd->reset();
139 
140 	CPPUNIT_ASSERT(domain_info_cmd->get_name() == "");
141 	CPPUNIT_ASSERT(domain_info_cmd->get_hosts_control() == "all");
142 
143 	CPPUNIT_ASSERT(domain_info_cmd->get_authInfo().get_pw() == "");
144 	CPPUNIT_ASSERT(domain_info_cmd->get_authInfo().get_roid() == "");
145 
146 	// parent attribute
147 	CPPUNIT_ASSERT(domain_info_cmd->get_clTRID() == "");
148 }
149 
command_test()150 void DomainInfoTest::command_test()
151 {
152 	DomainInfo domain_info;
153 	DomainInfoCmd *domain_info_cmd = domain_info.get_command();
154 
155 	domain_info_cmd->set_name("EmmaWatsonIsCharming.com");
156 	domain_info_cmd->set_hosts_control("sub");
157 
158 	AuthInfo auth;
159 	auth.set_roid("SH8013-REP");
160 	auth.set_pw("abc123");
161 	domain_info_cmd->set_authInfo(auth);
162 
163 	LaunchInfoCmd launch;
164 	launch.set_includeMark(true);
165 	launch.set_phase(LaunchPhase::CLAIMS);
166 	launch.set_applicationId("abc123");
167 	domain_info_cmd->set_launch(launch);
168 
169 	bool exception_caught = false;
170 	try {
171 		string xml_template =
172 			FileUtil::read_file("../docs/templates/domain_info.xml");
173 
174 		domain_info.get_command()->set_clTRID("ABC-12345");
175 		domain_info.set_xml_template(xml_template);
176 
177 		DomParser parser;
178 		parser.enable_validation("../docs/schemas");
179 		parser.parse_command(domain_info.get_xml());
180 	} catch (const IoException &e) {
181 		exception_caught = true;
182 		printf("\nIO Exception: code [%d] message [%s]",
183 		       e.get_code(), e.get_msg().c_str());
184 	} catch (const XmlException &e) {
185 		exception_caught = true;
186 		printf("\nXml Exception: code [%d] message [%s] low level message [%s]\n",
187 		       e.get_code(), e.get_msg().c_str(), e.get_low_level_msg().c_str());
188 	}
189 
190 	CPPUNIT_ASSERT(!exception_caught);
191 }
192 
response_test()193 void DomainInfoTest::response_test()
194 {
195 	response_test(false, false, false);
196 	response_test(true, false, false);
197 	response_test(false, true, false);
198 	response_test(true, true, false);
199 	response_test(false, false, true);
200 	response_test(true, false, true);
201 	response_test(false, true, true);
202 	response_test(true, true, true);
203 }
204 
response_test(bool withDNSSECExtension,bool withRGPExtension,bool withLaunchExtension)205 void DomainInfoTest::response_test(bool withDNSSECExtension,
206                                    bool withRGPExtension,
207                                    bool withLaunchExtension)
208 {
209 	string expected =
210 		"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
211 		"<epp xmlns=\"urn:ietf:params:xml:ns:epp-1.0\" "
212 		"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
213 		"xsi:schemaLocation=\"urn:ietf:params:xml:ns:epp-1.0 "
214 		"epp-1.0.xsd\">"
215 		"<response>"
216 		"<result code=\"1000\">"
217 		"<msg>Command completed successfully</msg>"
218 		"</result>"
219 		"<resData>"
220 		"<domain:infData "
221 		"xmlns:domain=\"urn:ietf:params:xml:ns:domain-1.0\" "
222 		"xsi:schemaLocation=\"urn:ietf:params:xml:ns:domain-1.0 "
223 		"domain-1.0.xsd\">"
224 		"<domain:name>EmmaWatsonIsCharming.org</domain:name>"
225 		"<domain:roid>YADAYADAYADA-ABC</domain:roid>"
226 		"<domain:status s=\"clientHold\"/>"
227 		"<domain:status s=\"serverUpdateProhibited\"/>"
228 		"<domain:registrant>SH8013-REP</domain:registrant>"
229 		"<domain:contact type=\"admin\">Voldemort</domain:contact>"
230 		"<domain:contact type=\"tech\">Dumbledore</domain:contact>"
231 		"<domain:ns>"
232 		"<domain:hostAttr>"
233 		"<domain:hostName>ns1.EmmaWatsonIsCharming.org"
234 		"</domain:hostName>"
235 		"<domain:hostAddr ip='v4'>192.168.0.1</domain:hostAddr>"
236 		"</domain:hostAttr>"
237 		"<domain:hostAttr>"
238 		"<domain:hostName>ns1.granger.com</domain:hostName>"
239 		"</domain:hostAttr>"
240 		"</domain:ns>"
241 		"<domain:clID>MrPotter</domain:clID>"
242 		"<domain:crID>Weasley</domain:crID>"
243 		"<domain:crDate>1999-04-03T22:00:00.0Z</domain:crDate>"
244 		"<domain:upID>Sirius</domain:upID>"
245 		"<domain:upDate>2002-12-12T22:00:00.0Z</domain:upDate>"
246 		"<domain:exDate>2001-04-03T22:00:00.0Z</domain:exDate>"
247 		"<domain:trDate>2005-01-03T22:00:00.0Z</domain:trDate>"
248 		"<domain:authInfo>"
249 		"<domain:pw>FooBar321</domain:pw>"
250 		"</domain:authInfo>"
251 		"</domain:infData>"
252 		"</resData>";
253 
254 	if (withDNSSECExtension || withRGPExtension || withLaunchExtension) {
255 		expected += "<extension>";
256 	}
257 
258 	if (withDNSSECExtension) {
259 		expected +=
260 			"<secDNS:infData "
261 			"xmlns:secDNS=\"urn:ietf:params:xml:ns:secDNS-1.0\" "
262 			"xsi:schemaLocation=\"urn:ietf:params:xml:ns:secDNS-1.0 "
263 			"secDNS-1.0.xsd\">"
264 			"<secDNS:dsData>"
265 			"<secDNS:keyTag>12345</secDNS:keyTag>"
266 			"<secDNS:alg>3</secDNS:alg>"
267 			"<secDNS:digestType>1</secDNS:digestType>"
268 			"<secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest>"
269 			"<secDNS:maxSigLife>604800</secDNS:maxSigLife>"
270 			"<secDNS:keyData>"
271 			"<secDNS:flags>256</secDNS:flags>"
272 			"<secDNS:protocol>3</secDNS:protocol>"
273 			"<secDNS:alg>1</secDNS:alg>"
274 			"<secDNS:pubKey>AQPJ////4Q==</secDNS:pubKey>"
275 			"</secDNS:keyData>"
276 			"</secDNS:dsData>"
277 			"<secDNS:dsData>"
278 			"<secDNS:keyTag>12345</secDNS:keyTag>"
279 			"<secDNS:alg>3</secDNS:alg>"
280 			"<secDNS:digestType>1</secDNS:digestType>"
281 			"<secDNS:digest>49FD46E6C4B45C55D4AC</secDNS:digest>"
282 			"</secDNS:dsData>"
283 			"</secDNS:infData>";
284 	}
285 
286 	if (withRGPExtension) {
287 		expected +=
288 			"<rgp:infData xmlns:rgp=\"urn:ietf:params:xml:ns:rgp-1.0\" "
289 			"xsi:schemaLocation=\"urn:ietf:params:xml:ns:rgp-1.0 rgp-1.0.xsd\">"
290 			"<rgp:rgpStatus s=\"addPeriod\"/>"
291 			"</rgp:infData>";
292 	}
293 
294 	if (withLaunchExtension) {
295 		expected +=
296 			"<launch:infData "
297 			"xmlns:launch=\"urn:ietf:params:xml:ns:launch-1.0\">"
298 			"<launch:phase>sunrise</launch:phase>"
299 			"<launch:applicationID>abc123</launch:applicationID>"
300 			"<launch:status s=\"pendingValidation\"/>"
301 			"<mark:mark xmlns:mark=\"urn:ietf:params:xml:ns:mark-1.0\">"
302 			"<mark:trademark>"
303 			"<mark:id>1234-2</mark:id>"
304 			"<mark:markName>Example One</mark:markName>"
305 			"<mark:holder entitlement=\"owner\">"
306 			"<mark:org>Example Inc.</mark:org>"
307 			"<mark:addr>"
308 			"<mark:street>123 Example Dr.</mark:street>"
309 			"<mark:street>Suite 100</mark:street>"
310 			"<mark:city>Reston</mark:city>"
311 			"<mark:sp>VA</mark:sp>"
312 			"<mark:pc>20190</mark:pc>"
313 			"<mark:cc>US</mark:cc>"
314 			"</mark:addr>"
315 			"</mark:holder>"
316 			"<mark:jurisdiction>US</mark:jurisdiction>"
317 			"<mark:class>35</mark:class>"
318 			"<mark:class>36</mark:class>"
319 			"<mark:label>example-one</mark:label>"
320 			"<mark:label>exampleone</mark:label>"
321 			"<mark:goodsAndServices>Dirigendas et eiusmodi "
322 			"featuring infringo in airfare et cartam servicia."
323 			"</mark:goodsAndServices>"
324 			"<mark:regNum>234235</mark:regNum>"
325 			"<mark:regDate>2009-08-16T09:00:00.0Z</mark:regDate>"
326 			"<mark:exDate>2015-08-16T09:00:00.0Z</mark:exDate>"
327 			"</mark:trademark>"
328 			"</mark:mark>"
329 			"</launch:infData>";
330 	}
331 
332 	if (withDNSSECExtension || withRGPExtension || withLaunchExtension) {
333 		expected += "</extension>";
334 	}
335 
336 	expected +=
337 		"<trID>"
338 		"<clTRID>ABC-12345</clTRID>"
339 		"<svTRID>54321-XYZ</svTRID>"
340 		"</trID>"
341 		"</response>"
342 		"</epp>";
343 
344 	DomParser parser;
345 	parser.enable_validation("../docs/schemas");
346 
347 	DomainInfo domain_info;
348 	CPPUNIT_ASSERT_NO_THROW(domain_info.set_response(expected, &parser));
349 
350 	DomainInfoRsp* domain_info_rsp = domain_info.get_response();
351 
352 	CPPUNIT_ASSERT(domain_info_rsp != 0);
353 	string result_code = "1000";
354 
355 	map <Response::ResultCode, Response::ResultInfo> results;
356 	map <Response::ResultCode, Response::ResultInfo>::const_iterator r_it;
357 	results = domain_info_rsp->get_result_list();
358 	r_it = results.begin();
359 
360 	CPPUNIT_ASSERT(r_it != results.end());
361 	CPPUNIT_ASSERT_EQUAL(Response::OK, r_it->first);
362 
363 	string response =
364 		"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>"
365 		"<epp xmlns=\"urn:ietf:params:xml:ns:epp-1.0\" "
366 		"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
367 		"xsi:schemaLocation=\"urn:ietf:params:xml:ns:epp-1.0 "
368 		"epp-1.0.xsd\">"
369 		"<response>"
370 		"<result code=\"" + result_code + "\">"
371 		"<msg";
372 
373 	string result_lang = domain_info_rsp->get_result_lang();
374 	if (result_lang != "en") {
375 		response += " lang='" + result_lang + "'";
376 	}
377 
378 	response +=
379 		">" + r_it->second.msg + "</msg>"
380 		"</result>"
381 		"<resData>"
382 		"<domain:infData "
383 		"xmlns:domain=\"urn:ietf:params:xml:ns:domain-1.0\" "
384 		"xsi:schemaLocation=\"urn:ietf:params:xml:ns:domain-1.0 "
385 		"domain-1.0.xsd\">";
386 
387 	//get_name
388 	//get_roid
389 	response +=
390 		"<domain:name>" + domain_info_rsp->get_name() + "</domain:name>"
391 		"<domain:roid>" + domain_info_rsp->get_roid() + "</domain:roid>";
392 
393 	//get_status_set
394 	set<string> status_set = domain_info_rsp->get_status_set();
395 	set<string>::const_iterator it;
396 	for (it = status_set.begin(); it != status_set.end(); it++) {
397 		response += "<domain:status s=\"" + (*it) + "\"/>";
398 	}
399 
400 	//get_registrant
401 	response +=
402 		"<domain:registrant>" + domain_info_rsp->get_registrant() +
403 		"</domain:registrant>";
404 
405 	//get_contacts
406 	map< string, string, less<string> > contacts = domain_info_rsp->get_contacts();
407 	map< string, string, less<string> >::const_iterator it_map;
408 	for (it_map = contacts.begin(); it_map != contacts.end(); it_map++) {
409 		response += "<domain:contact type=\"" + (*it_map).first + "\">" +
410 			(*it_map).second + "</domain:contact>";
411 	}
412 
413 	//get_nameservers
414 	response += "<domain:ns>";
415 	vector<struct NameServer> nameservers = domain_info_rsp->get_nameservers();
416 	vector<struct NameServer>::const_iterator it_ns;
417 	set<struct NSIPAddr>::const_iterator it_ip;
418 	for (it_ns = nameservers.begin(); it_ns != nameservers.end(); it_ns++) {
419 		response += "<domain:hostAttr>" ;
420 		response += "<domain:hostName>" + it_ns->name + "</domain:hostName>";
421 		for (it_ip = it_ns->ips.begin(); it_ip != it_ns->ips.end(); it_ip++) {
422 			response += "<domain:hostAddr";
423 			if ((*it_ip).version != "") {
424 				response += " ip='" + (*it_ip).version + "'";
425 			}
426 			response += ">" + (*it_ip).addr + "</domain:hostAddr>";
427 		}
428 		response += "</domain:hostAttr>";
429 	}
430 	response += "</domain:ns>";
431 
432 	//get_clID
433 	response += "<domain:clID>" + domain_info_rsp->get_clID() +
434 		"</domain:clID>";
435 
436 	//get_crID
437 	//get_crDate
438 	response += "<domain:crID>" + domain_info_rsp->get_crID() + "</domain:crID>"
439 		"<domain:crDate>" + domain_info_rsp->get_crDate() + "</domain:crDate>";
440 
441 	//get_upID
442 	response += "<domain:upID>" + domain_info_rsp->get_upID() + "</domain:upID>";
443 
444 	//get_upDate
445 	//get_exDate
446 	//get_trDate
447 	response +=
448 		"<domain:upDate>" + domain_info_rsp->get_upDate() + "</domain:upDate>"
449 		"<domain:exDate>" + domain_info_rsp->get_exDate() + "</domain:exDate>"
450 		"<domain:trDate>" + domain_info_rsp->get_trDate() + "</domain:trDate>";
451 
452 	//get_pw
453 	response +=
454 		"<domain:authInfo>"
455 		"<domain:pw>" + domain_info_rsp->get_authInfo().get_pw() + "</domain:pw>"
456 		"</domain:authInfo>";
457 
458 	response +=
459 		"</domain:infData>"
460 		"</resData>";
461 
462 	// secDNS extension
463 	list<DSInfo> dsInfoList = domain_info_rsp->get_dsInfo();
464 
465 	if (!dsInfoList.empty() ||
466 	    domain_info_rsp->get_rgpStatus() != RGPStatus::NONE ||
467 	    domain_info_rsp->get_launch().get_phase().get_phase() != LaunchPhase::NONE) {
468 		response += "<extension>";
469 	}
470 
471 	if (!dsInfoList.empty()) {
472 		response += "<secDNS:infData "
473 			"xmlns:secDNS=\"urn:ietf:params:xml:ns:secDNS-1.0\" "
474 			"xsi:schemaLocation=\"urn:ietf:params:xml:ns:secDNS-1.0 "
475 			"secDNS-1.0.xsd\">";
476 
477 		list<DSInfo>::iterator ds_it;
478 		for (ds_it = dsInfoList.begin(); ds_it != dsInfoList.end(); ds_it++) {
479 			response +=
480 				"<secDNS:dsData>"
481 				"<secDNS:keyTag>" + StrUtil::to_string("%d", (*ds_it).get_key_tag()) +
482 				"</secDNS:keyTag>"
483 				"<secDNS:alg>" + StrUtil::to_string("%d", (*ds_it).get_algo()) +
484 				"</secDNS:alg>"
485 				"<secDNS:digestType>" +
486 				StrUtil::to_string("%d", (*ds_it).get_digest_type()) +
487 				"</secDNS:digestType>"
488 				"<secDNS:digest>" + (*ds_it).get_digest() + "</secDNS:digest>";
489 
490 			unsigned int maxSigLife = (*ds_it).get_max_sig_life();
491 			if (maxSigLife > 0) {
492 				response += "<secDNS:maxSigLife>" +
493 					StrUtil::to_string("%d", maxSigLife) + "</secDNS:maxSigLife>";
494 			}
495 
496 			if ((*ds_it).hasKeyData()) {
497 				KeyData kd = (*ds_it).get_key_data();
498 				response +=
499 					"<secDNS:keyData>"
500 					"<secDNS:flags>" + StrUtil::to_string("%d", kd.get_flags()) +
501 					"</secDNS:flags>"
502 					"<secDNS:protocol>" + StrUtil::to_string("%d", kd.get_protocol()) +
503 					"</secDNS:protocol>"
504 					"<secDNS:alg>" + StrUtil::to_string("%d", kd.get_algorithm()) +
505 					"</secDNS:alg>"
506 					"<secDNS:pubKey>" + kd.get_pub_key() + "</secDNS:pubKey>"
507 					"</secDNS:keyData>";
508 			}
509 
510 			response += "</secDNS:dsData>";
511 		}
512 		response += "</secDNS:infData>";
513 	}
514 
515 	if (domain_info_rsp->get_rgpStatus() != RGPStatus::NONE) {
516 		string status = RGPStatus::statusToString(domain_info_rsp->get_rgpStatus());
517 		response += "<rgp:infData xmlns:rgp=\"urn:ietf:params:xml:ns:rgp-1.0\" "
518 			"xsi:schemaLocation=\"urn:ietf:params:xml:ns:rgp-1.0 rgp-1.0.xsd\">"
519 			"<rgp:rgpStatus s=\"" + status + "\"/>"
520 			"</rgp:infData>";
521 	}
522 
523 	if (domain_info_rsp->get_launch().get_phase().get_phase() != LaunchPhase::NONE) {
524 		LaunchInfoRsp launch = domain_info_rsp->get_launch();
525 
526 		response += "<launch:infData "
527 			"xmlns:launch=\"urn:ietf:params:xml:ns:launch-1.0\">"
528 			"<launch:phase>" + LaunchPhase::toStr(launch.get_phase().get_phase()) +
529 			"</launch:phase>"
530 			"<launch:applicationID>" + launch.get_applicationId() + "</launch:applicationID>"
531 			"<launch:status s=\"" + LaunchInfoRsp::Status::toStr(launch.get_status()) + "\"/>";
532 
533 		list<SMDMark> marks = launch.get_marks();
534 		list<SMDMark>::const_iterator markIt;
535 
536 		for (markIt = marks.begin(); markIt != marks.end(); markIt++) {
537 			list<SMDTrademark> trademarks = markIt->get_trademarks();
538 			list<SMDTrademark>::const_iterator trademarkIt;
539 
540 			response += "<mark:mark xmlns:mark=\"urn:ietf:params:xml:ns:mark-1.0\">";
541 
542 			for (trademarkIt = trademarks.begin();
543 			     trademarkIt != trademarks.end(); trademarkIt++) {
544 				response += "<mark:trademark>"
545 					"<mark:id>" + trademarkIt->get_id() + "</mark:id>"
546 					"<mark:markName>" + trademarkIt->get_markName() + "</mark:markName>";
547 
548 				list<pair<SMDHolder::Type::Value, SMDHolder> > holders =
549 					trademarkIt->get_holders();
550 				list<pair<SMDHolder::Type::Value, SMDHolder> >::const_iterator holderIt;
551 
552 				for (holderIt = holders.begin(); holderIt != holders.end(); holderIt++) {
553 					PostalInfo postalInfo = holderIt->second.get_postalInfo();
554 
555 					response += "<mark:holder entitlement=\"" +
556 						SMDHolder::Type::toStr(holderIt->first) + "\">"
557 						"<mark:org>" + holderIt->second.get_org() + "</mark:org>"
558 						"<mark:addr>"
559 						"<mark:street>" + postalInfo.get_str1() + "</mark:street>"
560 						"<mark:street>" + postalInfo.get_str2() + "</mark:street>"
561 						"<mark:city>" + postalInfo.get_city() + "</mark:city>"
562 						"<mark:sp>" + postalInfo.get_sp() + "</mark:sp>"
563 						"<mark:pc>" + postalInfo.get_pc() + "</mark:pc>"
564 						"<mark:cc>" + postalInfo.get_cc() + "</mark:cc>"
565 						"</mark:addr>"
566 						"</mark:holder>";
567 				}
568 
569 				response += "<mark:jurisdiction>" + trademarkIt->get_jurisdiction() +
570 					"</mark:jurisdiction>";
571 
572 				list<string> classes = trademarkIt->get_classes();
573 				list<string>::const_iterator classIt;
574 
575 				for (classIt = classes.begin(); classIt != classes.end(); classIt++) {
576 					response += "<mark:class>" + *classIt + "</mark:class>";
577 				}
578 
579 				list<string> labels = trademarkIt->get_labels();
580 				list<string>::const_iterator labelIt;
581 
582 				for (labelIt = labels.begin(); labelIt != labels.end(); labelIt++) {
583 					response += "<mark:label>" + *labelIt + "</mark:label>";
584 				}
585 
586 				response += "<mark:goodsAndServices>" + trademarkIt->get_goodsAndServices() +
587 					"</mark:goodsAndServices>"
588 					"<mark:regNum>" + trademarkIt->get_regNum() + "</mark:regNum>"
589 					"<mark:regDate>" + trademarkIt->get_regDate() + "</mark:regDate>"
590 					"<mark:exDate>" + trademarkIt->get_exDate() + "</mark:exDate>"
591 					"</mark:trademark>";
592 			}
593 
594 			response += "</mark:mark>";
595 		}
596 
597 		response +=	"</launch:infData>";
598 	}
599 
600 	if (!dsInfoList.empty() ||
601 	    domain_info_rsp->get_rgpStatus() != RGPStatus::NONE ||
602 	    domain_info_rsp->get_launch().get_phase().get_phase() != LaunchPhase::NONE) {
603 		response += "</extension>";
604 	}
605 
606 	response +=
607 		"<trID>"
608 		"<clTRID>" + domain_info_rsp->get_clTRID() + "</clTRID>"
609 		"<svTRID>" + domain_info_rsp->get_svTRID() + "</svTRID>"
610 		"</trID>"
611 		"</response>"
612 		"</epp>";
613 
614 	CPPUNIT_ASSERT_EQUAL(expected, response);
615 
616 	// tests reset method
617 	domain_info_rsp->reset();
618 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_name());
619 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_roid());
620 	CPPUNIT_ASSERT(domain_info_rsp->get_status_set().empty());
621 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_registrant());
622 	CPPUNIT_ASSERT(domain_info_rsp->get_contacts().empty());
623 	CPPUNIT_ASSERT(domain_info_rsp->get_nameservers().empty());
624 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_clID());
625 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_crID());
626 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_crDate());
627 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_upID());
628 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_exDate());
629 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_upDate());
630 	CPPUNIT_ASSERT_EQUAL((const string)"", domain_info_rsp->get_trDate());
631 	CPPUNIT_ASSERT_EQUAL(RGPStatus::NONE, domain_info_rsp->get_rgpStatus());
632 	CPPUNIT_ASSERT_EQUAL((const string)"",
633 	                     domain_info_rsp->get_authInfo().get_roid());
634 	CPPUNIT_ASSERT_EQUAL((const string)"",
635 	                     domain_info_rsp->get_authInfo().get_pw());
636 }
637