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.
6 #include "base/memory/ref_counted.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/strings/stringprintf.h"
9 #include "remoting/jingle_glue/iq_sender.h"
10 #include "remoting/jingle_glue/mock_objects.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
14 #include "third_party/libjingle/source/talk/xmpp/constants.h"
17 using ::testing::DeleteArg
;
18 using ::testing::InvokeWithoutArgs
;
19 using ::testing::NotNull
;
20 using ::testing::Return
;
21 using ::testing::SaveArg
;
24 using ::buzz::XmlElement
;
30 const char kStanzaId
[] = "123";
31 const char kNamespace
[] = "chromium:testns";
32 const char kNamespacePrefix
[] = "tes";
33 const char kBodyTag
[] = "test";
34 const char kType
[] = "get";
35 const char kTo
[] = "user@domain.com";
39 MOCK_METHOD2(OnReply
, void(IqRequest
* request
, const XmlElement
* reply
));
42 MATCHER_P(XmlEq
, expected
, "") {
43 return arg
->Str() == expected
->Str();
48 class IqSenderTest
: public testing::Test
{
51 EXPECT_CALL(signal_strategy_
, AddListener(NotNull()));
52 sender_
.reset(new IqSender(&signal_strategy_
));
53 EXPECT_CALL(signal_strategy_
, RemoveListener(
54 static_cast<SignalStrategy::Listener
*>(sender_
.get())));
58 void SendTestMessage() {
59 scoped_ptr
<XmlElement
> iq_body(
60 new XmlElement(QName(kNamespace
, kBodyTag
)));
61 XmlElement
* sent_stanza
;
62 EXPECT_CALL(signal_strategy_
, GetNextId())
63 .WillOnce(Return(kStanzaId
));
64 EXPECT_CALL(signal_strategy_
, SendStanzaPtr(_
))
65 .WillOnce(DoAll(SaveArg
<0>(&sent_stanza
), Return(true)));
66 request_
= sender_
->SendIq(kType
, kTo
, iq_body
.Pass(), base::Bind(
67 &MockCallback::OnReply
, base::Unretained(&callback_
)));
69 std::string expected_xml_string
=
71 "<cli:iq type=\"%s\" to=\"%s\" id=\"%s\" "
72 "xmlns:cli=\"jabber:client\">"
73 "<%s:%s xmlns:%s=\"%s\"/>"
75 kType
, kTo
, kStanzaId
, kNamespacePrefix
, kBodyTag
,
76 kNamespacePrefix
, kNamespace
);
77 EXPECT_EQ(expected_xml_string
, sent_stanza
->Str());
81 base::MessageLoop message_loop_
;
82 MockSignalStrategy signal_strategy_
;
83 scoped_ptr
<IqSender
> sender_
;
84 MockCallback callback_
;
85 scoped_ptr
<IqRequest
> request_
;
88 TEST_F(IqSenderTest
, SendIq
) {
89 ASSERT_NO_FATAL_FAILURE({
93 scoped_ptr
<XmlElement
> response(new XmlElement(buzz::QN_IQ
));
94 response
->AddAttr(QName(std::string(), "type"), "result");
95 response
->AddAttr(QName(std::string(), "id"), kStanzaId
);
96 response
->AddAttr(QName(std::string(), "from"), kTo
);
98 XmlElement
* result
= new XmlElement(
99 QName("test:namespace", "response-body"));
100 response
->AddElement(result
);
102 EXPECT_TRUE(sender_
->OnSignalStrategyIncomingStanza(response
.get()));
104 EXPECT_CALL(callback_
, OnReply(request_
.get(), XmlEq(response
.get())));
105 message_loop_
.RunUntilIdle();
108 TEST_F(IqSenderTest
, Timeout
) {
109 ASSERT_NO_FATAL_FAILURE({
113 request_
->SetTimeout(base::TimeDelta::FromMilliseconds(2));
115 EXPECT_CALL(callback_
, OnReply(request_
.get(), NULL
))
116 .WillOnce(InvokeWithoutArgs(&message_loop_
, &base::MessageLoop::Quit
));
120 TEST_F(IqSenderTest
, InvalidFrom
) {
121 ASSERT_NO_FATAL_FAILURE({
125 scoped_ptr
<XmlElement
> response(new XmlElement(buzz::QN_IQ
));
126 response
->AddAttr(QName(std::string(), "type"), "result");
127 response
->AddAttr(QName(std::string(), "id"), kStanzaId
);
128 response
->AddAttr(QName(std::string(), "from"), "different_user@domain.com");
130 XmlElement
* result
= new XmlElement(
131 QName("test:namespace", "response-body"));
132 response
->AddElement(result
);
134 EXPECT_CALL(callback_
, OnReply(_
, _
))
136 EXPECT_FALSE(sender_
->OnSignalStrategyIncomingStanza(response
.get()));
137 message_loop_
.RunUntilIdle();
140 TEST_F(IqSenderTest
, IdMatchingHack
) {
141 ASSERT_NO_FATAL_FAILURE({
145 scoped_ptr
<XmlElement
> response(new XmlElement(buzz::QN_IQ
));
146 response
->AddAttr(QName(std::string(), "type"), "result");
147 response
->AddAttr(QName(std::string(), "id"), "DIFFERENT_ID");
148 response
->AddAttr(QName(std::string(), "from"), kTo
);
150 XmlElement
* result
= new XmlElement(
151 QName("test:namespace", "response-body"));
152 response
->AddElement(result
);
154 EXPECT_TRUE(sender_
->OnSignalStrategyIncomingStanza(response
.get()));
156 EXPECT_CALL(callback_
, OnReply(request_
.get(), XmlEq(response
.get())));
157 message_loop_
.RunUntilIdle();
160 } // namespace remoting