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/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "remoting/jingle_glue/iq_sender.h"
11 #include "remoting/jingle_glue/mock_objects.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
15 #include "third_party/libjingle/source/talk/xmpp/constants.h"
18 using ::testing::DeleteArg
;
19 using ::testing::InvokeWithoutArgs
;
20 using ::testing::NotNull
;
21 using ::testing::Return
;
22 using ::testing::SaveArg
;
25 using ::buzz::XmlElement
;
31 const char kStanzaId
[] = "123";
32 const char kNamespace
[] = "chromium:testns";
33 const char kNamespacePrefix
[] = "tes";
34 const char kBodyTag
[] = "test";
35 const char kType
[] = "get";
36 const char kTo
[] = "user@domain.com";
40 MOCK_METHOD2(OnReply
, void(IqRequest
* request
, const XmlElement
* reply
));
43 MATCHER_P(XmlEq
, expected
, "") {
44 return arg
->Str() == expected
->Str();
49 class IqSenderTest
: public testing::Test
{
52 EXPECT_CALL(signal_strategy_
, AddListener(NotNull()));
53 sender_
.reset(new IqSender(&signal_strategy_
));
54 EXPECT_CALL(signal_strategy_
, RemoveListener(
55 static_cast<SignalStrategy::Listener
*>(sender_
.get())));
59 void SendTestMessage() {
60 scoped_ptr
<XmlElement
> iq_body(
61 new XmlElement(QName(kNamespace
, kBodyTag
)));
62 XmlElement
* sent_stanza
;
63 EXPECT_CALL(signal_strategy_
, GetNextId())
64 .WillOnce(Return(kStanzaId
));
65 EXPECT_CALL(signal_strategy_
, SendStanzaPtr(_
))
66 .WillOnce(DoAll(SaveArg
<0>(&sent_stanza
), Return(true)));
67 request_
= sender_
->SendIq(kType
, kTo
, iq_body
.Pass(), base::Bind(
68 &MockCallback::OnReply
, base::Unretained(&callback_
)));
70 std::string expected_xml_string
=
72 "<cli:iq type=\"%s\" to=\"%s\" id=\"%s\" "
73 "xmlns:cli=\"jabber:client\">"
74 "<%s:%s xmlns:%s=\"%s\"/>"
76 kType
, kTo
, kStanzaId
, kNamespacePrefix
, kBodyTag
,
77 kNamespacePrefix
, kNamespace
);
78 EXPECT_EQ(expected_xml_string
, sent_stanza
->Str());
82 base::MessageLoop message_loop_
;
83 MockSignalStrategy signal_strategy_
;
84 scoped_ptr
<IqSender
> sender_
;
85 MockCallback callback_
;
86 scoped_ptr
<IqRequest
> request_
;
89 TEST_F(IqSenderTest
, SendIq
) {
90 ASSERT_NO_FATAL_FAILURE({
94 scoped_ptr
<XmlElement
> response(new XmlElement(buzz::QN_IQ
));
95 response
->AddAttr(QName(std::string(), "type"), "result");
96 response
->AddAttr(QName(std::string(), "id"), kStanzaId
);
97 response
->AddAttr(QName(std::string(), "from"), kTo
);
99 XmlElement
* result
= new XmlElement(
100 QName("test:namespace", "response-body"));
101 response
->AddElement(result
);
103 EXPECT_TRUE(sender_
->OnSignalStrategyIncomingStanza(response
.get()));
105 EXPECT_CALL(callback_
, OnReply(request_
.get(), XmlEq(response
.get())));
106 base::RunLoop().RunUntilIdle();
109 TEST_F(IqSenderTest
, Timeout
) {
110 ASSERT_NO_FATAL_FAILURE({
114 request_
->SetTimeout(base::TimeDelta::FromMilliseconds(2));
116 EXPECT_CALL(callback_
, OnReply(request_
.get(), NULL
))
117 .WillOnce(InvokeWithoutArgs(&message_loop_
, &base::MessageLoop::Quit
));
121 TEST_F(IqSenderTest
, InvalidFrom
) {
122 ASSERT_NO_FATAL_FAILURE({
126 scoped_ptr
<XmlElement
> response(new XmlElement(buzz::QN_IQ
));
127 response
->AddAttr(QName(std::string(), "type"), "result");
128 response
->AddAttr(QName(std::string(), "id"), kStanzaId
);
129 response
->AddAttr(QName(std::string(), "from"), "different_user@domain.com");
131 XmlElement
* result
= new XmlElement(
132 QName("test:namespace", "response-body"));
133 response
->AddElement(result
);
135 EXPECT_CALL(callback_
, OnReply(_
, _
))
137 EXPECT_FALSE(sender_
->OnSignalStrategyIncomingStanza(response
.get()));
138 base::RunLoop().RunUntilIdle();
141 TEST_F(IqSenderTest
, IdMatchingHack
) {
142 ASSERT_NO_FATAL_FAILURE({
146 scoped_ptr
<XmlElement
> response(new XmlElement(buzz::QN_IQ
));
147 response
->AddAttr(QName(std::string(), "type"), "result");
148 response
->AddAttr(QName(std::string(), "id"), "DIFFERENT_ID");
149 response
->AddAttr(QName(std::string(), "from"), kTo
);
151 XmlElement
* result
= new XmlElement(
152 QName("test:namespace", "response-body"));
153 response
->AddElement(result
);
155 EXPECT_TRUE(sender_
->OnSignalStrategyIncomingStanza(response
.get()));
157 EXPECT_CALL(callback_
, OnReply(request_
.get(), XmlEq(response
.get())));
158 base::RunLoop().RunUntilIdle();
161 } // namespace remoting