cleanup: pass string as const reference from c/b/extension
[chromium-blink-merge.git] / remoting / protocol / jingle_messages_unittest.cc
blobd8ed4dcdd86d691ed696866373941e43384a54c4
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/libjingle/source/talk/xmllite/xmlelement.h"
11 #include "third_party/libjingle/source/talk/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 != NULL;
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 "<control transport='stream' version='2'/>"
109 "<event transport='stream' version='2'/>"
110 "<video transport='stream' version='2' codec='vp8'/>"
111 "<audio transport='stream' version='2' codec='verbatim'/>"
112 "<initial-resolution width='640' height='480'/>"
113 "<authentication><auth-token>"
114 "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
115 "</auth-token></authentication>"
116 "</description>"
117 "<transport xmlns='http://www.google.com/transport/p2p'/>"
118 "</content>"
119 "</jingle>"
120 "</iq>";
121 scoped_ptr<XmlElement> source_message(
122 XmlElement::ForStr(kTestSessionInitiateMessage));
123 ASSERT_TRUE(source_message.get());
125 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
127 JingleMessage message;
128 std::string error;
129 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
131 EXPECT_EQ(message.action, JingleMessage::SESSION_INITIATE);
133 scoped_ptr<XmlElement> formatted_message(message.ToXml());
134 ASSERT_TRUE(formatted_message.get());
135 EXPECT_TRUE(VerifyXml(formatted_message.get(), source_message.get(), &error))
136 << error;
139 TEST(JingleMessageTest, SessionAccept) {
140 const char* kTestSessionAcceptMessage =
141 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
142 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
143 "xmlns:cli='jabber:client'>"
144 "<jingle action='session-accept' sid='2227053353' "
145 "xmlns='urn:xmpp:jingle:1'>i"
146 "<content creator='initiator' name='chromoting'>"
147 "<description xmlns='google:remoting'>"
148 "<control transport='stream' version='2'/>"
149 "<event transport='stream' version='2'/>"
150 "<video codec='vp8' transport='stream' version='2'/>"
151 "<audio transport='stream' version='2' codec='verbatim'/>"
152 "<initial-resolution height='480' width='640'/>"
153 "<authentication><certificate>"
154 "MIICpjCCAY6gW0Cert0TANBgkqhkiG9w0BAQUFA="
155 "</certificate></authentication>"
156 "</description>"
157 "<transport xmlns='http://www.google.com/transport/p2p'/>"
158 "</content>"
159 "</jingle>"
160 "</cli:iq>";
162 scoped_ptr<XmlElement> source_message(
163 XmlElement::ForStr(kTestSessionAcceptMessage));
164 ASSERT_TRUE(source_message.get());
166 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
168 JingleMessage message;
169 std::string error;
170 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
172 EXPECT_EQ(message.action, JingleMessage::SESSION_ACCEPT);
174 scoped_ptr<XmlElement> formatted_message(message.ToXml());
175 ASSERT_TRUE(formatted_message.get());
176 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
177 << error;
180 TEST(JingleMessageTest, TransportInfo) {
181 const char* kTestTransportInfoMessage =
182 "<cli:iq to='user@gmail.com/chromoting016DBB07' type='set' "
183 "xmlns:cli='jabber:client'><jingle xmlns='urn:xmpp:jingle:1' "
184 "action='transport-info' sid='2227053353'><content name='chromoting' "
185 "creator='initiator'><transport "
186 "xmlns='http://www.google.com/transport/p2p'><candidate name='event' "
187 "address='172.23.164.186' port='57040' preference='1' "
188 "username='tPUyEAmQrEw3y7hi' protocol='udp' generation='0' "
189 "password='2iRdhLfawKZC5ydJ' type='local'/><candidate name='video' "
190 "address='172.23.164.186' port='42171' preference='1' "
191 "username='EPK3CXo5sTLJSez0' protocol='udp' generation='0' "
192 "password='eM0VUfUkZ+1Pyi0M' type='local'/></transport></content>"
193 "</jingle></cli:iq>";
195 scoped_ptr<XmlElement> source_message(
196 XmlElement::ForStr(kTestTransportInfoMessage));
197 ASSERT_TRUE(source_message.get());
199 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
201 JingleMessage message;
202 std::string error;
203 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
205 EXPECT_EQ(message.action, JingleMessage::TRANSPORT_INFO);
206 EXPECT_EQ(message.candidates.size(), 2U);
208 scoped_ptr<XmlElement> formatted_message(message.ToXml());
209 ASSERT_TRUE(formatted_message.get());
210 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
211 << error;
214 TEST(JingleMessageTest, SessionTerminate) {
215 const char* kTestSessionTerminateMessage =
216 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
217 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
218 "xmlns:cli='jabber:client'><jingle action='session-terminate' "
219 "sid='2227053353' xmlns='urn:xmpp:jingle:1'><reason><success/>"
220 "</reason></jingle></cli:iq>";
222 scoped_ptr<XmlElement> source_message(
223 XmlElement::ForStr(kTestSessionTerminateMessage));
224 ASSERT_TRUE(source_message.get());
226 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
228 JingleMessage message;
229 std::string error;
230 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
232 EXPECT_EQ(message.action, JingleMessage::SESSION_TERMINATE);
234 scoped_ptr<XmlElement> formatted_message(message.ToXml());
235 ASSERT_TRUE(formatted_message.get());
236 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
237 << error;
240 TEST(JingleMessageTest, SessionInfo) {
241 const char* kTestSessionTerminateMessage =
242 "<cli:iq from='user@gmail.com/chromoting016DBB07' "
243 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
244 "xmlns:cli='jabber:client'><jingle action='session-info' "
245 "sid='2227053353' xmlns='urn:xmpp:jingle:1'><test-info>TestMessage"
246 "</test-info></jingle></cli:iq>";
248 scoped_ptr<XmlElement> source_message(
249 XmlElement::ForStr(kTestSessionTerminateMessage));
250 ASSERT_TRUE(source_message.get());
252 EXPECT_TRUE(JingleMessage::IsJingleMessage(source_message.get()));
254 JingleMessage message;
255 std::string error;
256 EXPECT_TRUE(message.ParseXml(source_message.get(), &error)) << error;
258 EXPECT_EQ(message.action, JingleMessage::SESSION_INFO);
259 ASSERT_TRUE(message.info.get() != NULL);
260 EXPECT_TRUE(message.info->Name() ==
261 buzz::QName("urn:xmpp:jingle:1", "test-info"));
263 scoped_ptr<XmlElement> formatted_message(message.ToXml());
264 ASSERT_TRUE(formatted_message.get());
265 EXPECT_TRUE(VerifyXml(source_message.get(), formatted_message.get(), &error))
266 << error;
269 TEST(JingleMessageReplyTest, ToXml) {
270 const char* kTestIncomingMessage =
271 "<cli:iq from='user@gmail.com/chromoting016DBB07' id='4' "
272 "to='user@gmail.com/chromiumsy5C6A652D' type='set' "
273 "xmlns:cli='jabber:client'><jingle action='session-terminate' "
274 "sid='2227053353' xmlns='urn:xmpp:jingle:1'><reason><success/>"
275 "</reason></jingle></cli:iq>";
276 scoped_ptr<XmlElement> incoming_message(
277 XmlElement::ForStr(kTestIncomingMessage));
278 ASSERT_TRUE(incoming_message.get());
280 struct TestCase {
281 const JingleMessageReply::ErrorType error;
282 std::string error_text;
283 std::string expected_text;
284 } tests[] = {
285 { JingleMessageReply::BAD_REQUEST, "", "<iq xmlns='jabber:client' "
286 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
287 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
288 "<reason><success/></reason></jingle><error type='modify'><bad-request/>"
289 "</error></iq>" },
290 { JingleMessageReply::BAD_REQUEST, "ErrorText", "<iq xmlns='jabber:client' "
291 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
292 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
293 "<reason><success/></reason></jingle><error type='modify'><bad-request/>"
294 "<text xml:lang='en'>ErrorText</text></error></iq>" },
295 { JingleMessageReply::NOT_IMPLEMENTED, "", "<iq xmlns='jabber:client' "
296 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
297 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
298 "<reason><success/></reason></jingle><error type='cancel'>"
299 "<feature-bad-request/></error></iq>" },
300 { JingleMessageReply::INVALID_SID, "", "<iq xmlns='jabber:client' "
301 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
302 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
303 "<reason><success/></reason></jingle><error type='modify'>"
304 "<item-not-found/><text xml:lang='en'>Invalid SID</text></error></iq>" },
305 { JingleMessageReply::INVALID_SID, "ErrorText", "<iq xmlns='jabber:client' "
306 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
307 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
308 "<reason><success/></reason></jingle><error type='modify'>"
309 "<item-not-found/><text xml:lang='en'>ErrorText</text></error></iq>" },
310 { JingleMessageReply::UNEXPECTED_REQUEST, "", "<iq xmlns='jabber:client' "
311 "to='user@gmail.com/chromoting016DBB07' id='4' type='error'><jingle "
312 "action='session-terminate' sid='2227053353' xmlns='urn:xmpp:jingle:1'>"
313 "<reason><success/></reason></jingle><error type='modify'>"
314 "<unexpected-request/></error></iq>" },
317 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
318 JingleMessageReply reply_msg;
319 if (tests[i].error_text.empty()) {
320 reply_msg = JingleMessageReply(tests[i].error);
321 } else {
322 reply_msg = JingleMessageReply(tests[i].error, tests[i].error_text);
324 scoped_ptr<XmlElement> reply(reply_msg.ToXml(incoming_message.get()));
326 scoped_ptr<XmlElement> expected(XmlElement::ForStr(tests[i].expected_text));
327 ASSERT_TRUE(expected.get());
329 std::string error;
330 EXPECT_TRUE(VerifyXml(expected.get(), reply.get(), &error)) << error;
334 TEST(JingleMessageTest, ErrorMessage) {
335 const char* kTestSessionInitiateErrorMessage =
336 "<iq to='user@gmail.com/chromoting016DBB07' type='error' "
337 "from='user@gmail.com/chromiumsy5C6A652D' "
338 "xmlns='jabber:client'>"
339 "<jingle xmlns='urn:xmpp:jingle:1' "
340 "action='session-initiate' sid='2227053353' "
341 "initiator='user@gmail.com/chromiumsy5C6A652D'>"
342 "<content name='chromoting' creator='initiator'>"
343 "<description xmlns='google:remoting'>"
344 "<control transport='stream' version='2'/>"
345 "<event transport='stream' version='2'/>"
346 "<video transport='stream' version='2' codec='vp8'/>"
347 "<audio transport='stream' version='2' codec='verbatim'/>"
348 "<initial-resolution width='800' height='600'/>"
349 "<authentication><auth-token>"
350 "j7whCMii0Z0AAPwj7whCM/j7whCMii0Z0AAPw="
351 "</auth-token></authentication>"
352 "</description>"
353 "<transport xmlns='http://www.google.com/transport/p2p'/>"
354 "</content>"
355 "</jingle>"
356 "<error code='501' type='cancel'>"
357 "<feature-not-implemented "
358 "xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>"
359 "</error>"
360 "</iq>";
361 scoped_ptr<XmlElement> source_message(
362 XmlElement::ForStr(kTestSessionInitiateErrorMessage));
363 ASSERT_TRUE(source_message.get());
365 EXPECT_FALSE(JingleMessage::IsJingleMessage(source_message.get()));
367 JingleMessage message;
368 std::string error;
369 EXPECT_FALSE(message.ParseXml(source_message.get(), &error));
370 EXPECT_FALSE(error.empty());
373 } // namespace protocol
374 } // namespace remoting