Mandoline: Disable slimming paint
[chromium-blink-merge.git] / remoting / protocol / jingle_messages_unittest.cc
blobaa95d0757785b15b24f04349547bf0390444726a
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/protocol/jingle_messages.h"
7 #include "base/logging.h"
8 #include "testing/gmock/include/gmock/gmock.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
11 #include "third_party/webrtc/libjingle/xmpp/constants.h"
13 using buzz::QName;
14 using buzz::XmlAttr;
15 using buzz::XmlElement;
17 namespace remoting {
18 namespace protocol {
20 namespace {
22 const char kXmlNsNs[] = "http://www.w3.org/2000/xmlns/";
23 const char kXmlNs[] = "xmlns";
25 // Compares two XML blobs and returns true if they are
26 // equivalent. Otherwise |error| is set to error message that
27 // specifies the first test.
28 bool VerifyXml(const XmlElement* exp,
29 const XmlElement* val,
30 std::string* error) {
31 if (exp->Name() != val->Name()) {
32 *error = "<" + exp->Name().Merged() + ">" + " is expected, but " +
33 "<" + val->Name().Merged() + ">" + " found";
34 return false;
36 if (exp->BodyText() != val->BodyText()) {
37 *error = "<" + exp->Name().LocalPart() + ">" + exp->BodyText() +
38 "</" + exp->Name().LocalPart() + ">" " is expected, but found " +
39 "<" + exp->Name().LocalPart() + ">" + val->BodyText() +
40 "</" + exp->Name().LocalPart() + ">";
41 return false;
44 for (const XmlAttr* exp_attr = exp->FirstAttr(); exp_attr != nullptr;
45 exp_attr = exp_attr->NextAttr()) {
46 if (exp_attr->Name().Namespace() == kXmlNsNs ||
47 exp_attr->Name() == QName(kXmlNs)) {
48 continue; // Skip NS attributes.
50 if (val->Attr(exp_attr->Name()) != exp_attr->Value()) {
51 *error = "In <" + exp->Name().LocalPart() + "> attribute " +
52 exp_attr->Name().LocalPart() + " is expected to be set to " +
53 exp_attr->Value();
54 return false;
58 for (const XmlAttr* val_attr = val->FirstAttr(); val_attr;
59 val_attr = val_attr->NextAttr()) {
60 if (val_attr->Name().Namespace() == kXmlNsNs ||
61 val_attr->Name() == QName(kXmlNs)) {
62 continue; // Skip NS attributes.
64 if (exp->Attr(val_attr->Name()) != val_attr->Value()) {
65 *error = "In <" + exp->Name().LocalPart() + "> unexpected attribute " +
66 val_attr->Name().LocalPart();
67 return false;
71 const XmlElement* exp_child = exp->FirstElement();
72 const XmlElement* val_child = val->FirstElement();
73 while (exp_child && val_child) {
74 if (!VerifyXml(exp_child, val_child, error))
75 return false;
76 exp_child = exp_child->NextElement();
77 val_child = val_child->NextElement();
79 if (exp_child) {
80 *error = "<" + exp_child->Name().Merged() + "> is expected, but not found";
81 return false;
84 if (val_child) {
85 *error = "Unexpected <" + val_child->Name().Merged() + "> found";
86 return false;
89 return true;
92 } // namespace
94 // Each of the tests below try to parse a message, format it again,
95 // and then verify that the formatted message is the same as the
96 // original stanza. The sample messages were generated by libjingle.
98 TEST(JingleMessageTest, SessionInitiate) {
99 const char* kTestSessionInitiateMessage =
100 "<iq to='user@gmail.com/chromoting016DBB07' type='set' "
101 "from='user@gmail.com/chromiumsy5C6A652D' "
102 "xmlns='jabber:client'>"
103 "<jingle xmlns='urn:xmpp:jingle:1' "
104 "action='session-initiate' sid='2227053353' "
105 "initiator='user@gmail.com/chromiumsy5C6A652D'>"
106 "<content name='chromoting' creator='initiator'>"
107 "<description xmlns='google:remoting'>"
108 "<standard-ice/>"
109 "<control transport='stream' version='2'/>"
110 "<event transport='stream' version='2'/>"
111 "<video transport='stream' version='2' codec='vp8'/>"
112 "<audio transport='stream' version='2' codec='verbatim'/>"
113 "<initial-resolution width='640' height='480'/>"
114 "<authentication><auth-token>"
115 "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
116 "</auth-token></authentication>"
117 "</description>"
118 "<transport xmlns='http://www.google.com/transport/p2p'/>"
119 "</content>"
120 "</jingle>"
121 "</iq>";
122 scoped_ptr<XmlElement> source_message(
123 XmlElement::ForStr(kTestSessionInitiateMessage));
124 ASSERT_TRUE(source_message.get());
126 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
128 JingleMessage message;
129 std::string error;
130 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
132 EXPECT_EQ(message.action, JingleMessage::SESSION_INITIATE);
134 scoped_ptr<XmlElement> formatted_message(message.ToXml());
135 ASSERT_TRUE(formatted_message.get());
136 EXPECT_TRUE(VerifyXml(formatted_message.get(), source_message.get(), &error))
137 << error;
140 TEST(JingleMessageTest, SessionAccept) {
141 const char* kTestSessionAcceptMessage =
142 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
143 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
144 "xmlns:cli='jabber:client'>"
145 "<jingle action='session-accept' sid='2227053353' "
146 "xmlns='urn:xmpp:jingle:1'>i"
147 "<content creator='initiator' name='chromoting'>"
148 "<description xmlns='google:remoting'>"
149 "<standard-ice/>"
150 "<control transport='stream' version='2'/>"
151 "<event transport='stream' version='2'/>"
152 "<video codec='vp8' transport='stream' version='2'/>"
153 "<audio transport='stream' version='2' codec='verbatim'/>"
154 "<initial-resolution height='480' width='640'/>"
155 "<authentication><certificate>"
156 "MIICpjCCAY6gW0Cert0TANBgkqhkiG9w0BAQUFA="
157 "</certificate></authentication>"
158 "</description>"
159 "<transport xmlns='http://www.google.com/transport/p2p'/>"
160 "</content>"
161 "</jingle>"
162 "</cli:iq>";
164 scoped_ptr<XmlElement> source_message(
165 XmlElement::ForStr(kTestSessionAcceptMessage));
166 ASSERT_TRUE(source_message.get());
168 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
170 JingleMessage message;
171 std::string error;
172 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
174 EXPECT_EQ(message.action, JingleMessage::SESSION_ACCEPT);
176 scoped_ptr<XmlElement> formatted_message(message.ToXml());
177 ASSERT_TRUE(formatted_message.get());
178 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
179 << error;
182 TEST(JingleMessageTest, SessionAcceptNoIce) {
183 const char* kTestSessionAcceptMessage =
184 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
185 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
186 "xmlns:cli='jabber:client'>"
187 "<jingle action='session-accept' sid='2227053353' "
188 "xmlns='urn:xmpp:jingle:1'>i"
189 "<content creator='initiator' name='chromoting'>"
190 "<description xmlns='google:remoting'>"
191 "<control transport='stream' version='2'/>"
192 "<event transport='stream' version='2'/>"
193 "<video codec='vp8' transport='stream' version='2'/>"
194 "<audio transport='stream' version='2' codec='verbatim'/>"
195 "<initial-resolution height='480' width='640'/>"
196 "<authentication><certificate>"
197 "MIICpjCCAY6gW0Cert0TANBgkqhkiG9w0BAQUFA="
198 "</certificate></authentication>"
199 "</description>"
200 "<transport xmlns='http://www.google.com/transport/p2p'/>"
201 "</content>"
202 "</jingle>"
203 "</cli:iq>";
205 scoped_ptr<XmlElement> source_message(
206 XmlElement::ForStr(kTestSessionAcceptMessage));
207 ASSERT_TRUE(source_message.get());
209 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
211 JingleMessage message;
212 std::string error;
213 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
215 EXPECT_EQ(message.action, JingleMessage::SESSION_ACCEPT);
217 scoped_ptr<XmlElement> formatted_message(message.ToXml());
218 ASSERT_TRUE(formatted_message.get());
219 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
220 << error;
223 TEST(JingleMessageTest, IceTransportInfo) {
224 const char* kTestIceTransportInfoMessage =
225 "<cli:iq to='user@gmail.com/chromoting016DBB07' type='set' "
226 "xmlns:cli='jabber:client'>"
227 "<jingle xmlns='urn:xmpp:jingle:1' action='transport-info' "
228 "sid='2227053353'>"
229 "<content name='chromoting' creator='initiator'>"
230 "<transport xmlns='google:remoting:ice'>"
231 "<credentials channel='event' ufrag='tPUyEAmQrEw3y7hi' "
232 "password='2iRdhLfawKZC5ydJ'/>"
233 "<credentials channel='video' ufrag='EPK3CXo5sTLJSez0' "
234 "password='eM0VUfUkZ+1Pyi0M'/>"
235 "<candidate name='event' foundation='725747215' "
236 "address='172.23.164.186' port='59089' type='local' "
237 "protocol='udp' priority='2122194688' generation='0'/>"
238 "<candidate name='video' foundation='3623806809' "
239 "address='172.23.164.186' port='57040' type='local' "
240 "protocol='udp' priority='2122194688' generation='0'/>"
241 "</transport>"
242 "</content>"
243 "</jingle>"
244 "</cli:iq>";
246 scoped_ptr<XmlElement> source_message(
247 XmlElement::ForStr(kTestIceTransportInfoMessage));
248 ASSERT_TRUE(source_message.get());
250 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
252 JingleMessage message;
253 std::string error;
254 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
256 EXPECT_EQ(message.action, JingleMessage::TRANSPORT_INFO);
257 EXPECT_EQ(message.candidates.size(), 2U);
259 scoped_ptr<XmlElement> formatted_message(message.ToXml());
260 ASSERT_TRUE(formatted_message.get());
261 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
262 << error;
265 TEST(JingleMessageTest, GiceTransportInfo) {
266 const char* kTestGiceTransportInfoMessage =
267 "<cli:iq to='user@gmail.com/chromoting016DBB07' type='set' "
268 "xmlns:cli='jabber:client'>"
269 "<jingle xmlns='urn:xmpp:jingle:1' action='transport-info' "
270 "sid='2227053353'>"
271 "<content name='chromoting' creator='initiator'>"
272 "<transport xmlns='http://www.google.com/transport/p2p'>"
273 "<candidate name='event' address='172.23.164.186' port='57040' "
274 "preference='1' username='tPUyEAmQrEw3y7hi' "
275 "protocol='udp' generation='0' "
276 "password='2iRdhLfawKZC5ydJ' type='local'/>"
277 "<candidate name='video' address='172.23.164.186' port='42171' "
278 "preference='1' username='EPK3CXo5sTLJSez0' "
279 "protocol='udp' generation='0' "
280 "password='eM0VUfUkZ+1Pyi0M' type='local'/>"
281 "</transport>"
282 "</content>"
283 "</jingle>"
284 "</cli:iq>";
286 scoped_ptr<XmlElement> source_message(
287 XmlElement::ForStr(kTestGiceTransportInfoMessage));
288 ASSERT_TRUE(source_message.get());
290 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
292 JingleMessage message;
293 std::string error;
294 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
296 EXPECT_EQ(message.action, JingleMessage::TRANSPORT_INFO);
297 EXPECT_EQ(message.candidates.size(), 2U);
299 scoped_ptr<XmlElement> formatted_message(message.ToXml());
300 ASSERT_TRUE(formatted_message.get());
301 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
302 << error;
305 TEST(JingleMessageTest, SessionTerminate) {
306 const char* kTestSessionTerminateMessage =
307 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
308 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
309 "xmlns:cli='jabber:client'><jingle action='session-terminate' "
310 "sid='2227053353' xmlns='urn:xmpp:jingle:1'><reason><success/>"
311 "</reason></jingle></cli:iq>";
313 scoped_ptr<XmlElement> source_message(
314 XmlElement::ForStr(kTestSessionTerminateMessage));
315 ASSERT_TRUE(source_message.get());
317 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
319 JingleMessage message;
320 std::string error;
321 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
323 EXPECT_EQ(message.action, JingleMessage::SESSION_TERMINATE);
325 scoped_ptr<XmlElement> formatted_message(message.ToXml());
326 ASSERT_TRUE(formatted_message.get());
327 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
328 << error;
331 TEST(JingleMessageTest, SessionInfo) {
332 const char* kTestSessionTerminateMessage =
333 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
334 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
335 "xmlns:cli='jabber:client'><jingle action='session-info' "
336 "sid='2227053353' xmlns='urn:xmpp:jingle:1'><test-info>TestMessage"
337 "</test-info></jingle></cli:iq>";
339 scoped_ptr<XmlElement> source_message(
340 XmlElement::ForStr(kTestSessionTerminateMessage));
341 ASSERT_TRUE(source_message.get());
343 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
345 JingleMessage message;
346 std::string error;
347 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
349 EXPECT_EQ(message.action, JingleMessage::SESSION_INFO);
350 ASSERT_TRUE(message.info.get() != nullptr);
351 EXPECT_TRUE(message.info->Name() ==
352 buzz::QName("urn:xmpp:jingle:1", "test-info"));
354 scoped_ptr<XmlElement> formatted_message(message.ToXml());
355 ASSERT_TRUE(formatted_message.get());
356 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
357 << error;
360 TEST(JingleMessageReplyTest, ToXml) {
361 const char* kTestIncomingMessage =
362 "<cli:iq from='user@gmail.com/chromoting016DBB07' id='4' "
363 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
364 "xmlns:cli='jabber:client'><jingle action='session-terminate' "
365 "sid='2227053353' xmlns='urn:xmpp:jingle:1'><reason><success/>"
366 "</reason></jingle></cli:iq>";
367 scoped_ptr<XmlElement> incoming_message(
368 XmlElement::ForStr(kTestIncomingMessage));
369 ASSERT_TRUE(incoming_message.get());
371 struct TestCase {
372 const JingleMessageReply::ErrorType error;
373 std::string error_text;
374 std::string expected_text;
375 } tests[] = {
376 { JingleMessageReply::BAD_REQUEST, "", "<iq xmlns='jabber:client' "
377 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
378 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
379 "<reason><success/></reason></jingle><error type='modify'><bad-request/>"
380 "</error></iq>" },
381 { JingleMessageReply::BAD_REQUEST, "ErrorText", "<iq xmlns='jabber:client' "
382 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
383 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
384 "<reason><success/></reason></jingle><error type='modify'><bad-request/>"
385 "<text xml:lang='en'>ErrorText</text></error></iq>" },
386 { JingleMessageReply::NOT_IMPLEMENTED, "", "<iq xmlns='jabber:client' "
387 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
388 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
389 "<reason><success/></reason></jingle><error type='cancel'>"
390 "<feature-bad-request/></error></iq>" },
391 { JingleMessageReply::INVALID_SID, "", "<iq xmlns='jabber:client' "
392 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
393 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
394 "<reason><success/></reason></jingle><error type='modify'>"
395 "<item-not-found/><text xml:lang='en'>Invalid SID</text></error></iq>" },
396 { JingleMessageReply::INVALID_SID, "ErrorText", "<iq xmlns='jabber:client' "
397 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
398 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
399 "<reason><success/></reason></jingle><error type='modify'>"
400 "<item-not-found/><text xml:lang='en'>ErrorText</text></error></iq>" },
401 { JingleMessageReply::UNEXPECTED_REQUEST, "", "<iq xmlns='jabber:client' "
402 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
403 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
404 "<reason><success/></reason></jingle><error type='modify'>"
405 "<unexpected-request/></error></iq>" },
408 for (size_t i = 0; i < arraysize(tests); ++i) {
409 JingleMessageReply reply_msg;
410 if (tests[i].error_text.empty()) {
411 reply_msg = JingleMessageReply(tests[i].error);
412 } else {
413 reply_msg = JingleMessageReply(tests[i].error, tests[i].error_text);
415 scoped_ptr<XmlElement> reply(reply_msg.ToXml(incoming_message.get()));
417 scoped_ptr<XmlElement> expected(XmlElement::ForStr(tests[i].expected_text));
418 ASSERT_TRUE(expected.get());
420 std::string error;
421 EXPECT_TRUE(VerifyXml(expected.get(), reply.get(), &error)) << error;
425 TEST(JingleMessageTest, ErrorMessage) {
426 const char* kTestSessionInitiateErrorMessage =
427 "<iq to='user@gmail.com/chromoting016DBB07' type='error' "
428 "from='user@gmail.com/chromiumsy5C6A652D' "
429 "xmlns='jabber:client'>"
430 "<jingle xmlns='urn:xmpp:jingle:1' "
431 "action='session-initiate' sid='2227053353' "
432 "initiator='user@gmail.com/chromiumsy5C6A652D'>"
433 "<content name='chromoting' creator='initiator'>"
434 "<description xmlns='google:remoting'>"
435 "<control transport='stream' version='2'/>"
436 "<event transport='stream' version='2'/>"
437 "<video transport='stream' version='2' codec='vp8'/>"
438 "<audio transport='stream' version='2' codec='verbatim'/>"
439 "<initial-resolution width='800' height='600'/>"
440 "<authentication><auth-token>"
441 "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
442 "</auth-token></authentication>"
443 "</description>"
444 "<transport xmlns='http://www.google.com/transport/p2p'/>"
445 "</content>"
446 "</jingle>"
447 "<error code='501' type='cancel'>"
448 "<feature-not-implemented "
449 "xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
450 "</error>"
451 "</iq>";
452 scoped_ptr<XmlElement> source_message(
453 XmlElement::ForStr(kTestSessionInitiateErrorMessage));
454 ASSERT_TRUE(source_message.get());
456 EXPECT_FALSE(JingleMessage::IsJingleMessage(source_message.get()));
458 JingleMessage message;
459 std::string error;
460 EXPECT_FALSE(message.ParseXml(source_message.get(), &error));
461 EXPECT_FALSE(error.empty());
464 } // namespace protocol
465 } // namespace remoting