• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "base/bind.h"
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"
15 
16 using ::testing::_;
17 using ::testing::DeleteArg;
18 using ::testing::InvokeWithoutArgs;
19 using ::testing::NotNull;
20 using ::testing::Return;
21 using ::testing::SaveArg;
22 
23 using ::buzz::QName;
24 using ::buzz::XmlElement;
25 
26 namespace remoting {
27 
28 namespace {
29 
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";
36 
37 class MockCallback {
38  public:
39   MOCK_METHOD2(OnReply, void(IqRequest* request, const XmlElement* reply));
40 };
41 
42 MATCHER_P(XmlEq, expected, "") {
43   return arg->Str() == expected->Str();
44 }
45 
46 }  // namespace
47 
48 class IqSenderTest : public testing::Test {
49  public:
IqSenderTest()50   IqSenderTest() {
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())));
55   }
56 
57  protected:
SendTestMessage()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_)));
68 
69     std::string expected_xml_string =
70         base::StringPrintf(
71             "<cli:iq type=\"%s\" to=\"%s\" id=\"%s\" "
72             "xmlns:cli=\"jabber:client\">"
73             "<%s:%s xmlns:%s=\"%s\"/>"
74             "</cli:iq>",
75             kType, kTo, kStanzaId, kNamespacePrefix, kBodyTag,
76             kNamespacePrefix, kNamespace);
77     EXPECT_EQ(expected_xml_string, sent_stanza->Str());
78     delete sent_stanza;
79   }
80 
81   base::MessageLoop message_loop_;
82   MockSignalStrategy signal_strategy_;
83   scoped_ptr<IqSender> sender_;
84   MockCallback callback_;
85   scoped_ptr<IqRequest> request_;
86 };
87 
TEST_F(IqSenderTest,SendIq)88 TEST_F(IqSenderTest, SendIq) {
89   ASSERT_NO_FATAL_FAILURE({
90     SendTestMessage();
91   });
92 
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);
97 
98   XmlElement* result = new XmlElement(
99       QName("test:namespace", "response-body"));
100   response->AddElement(result);
101 
102   EXPECT_TRUE(sender_->OnSignalStrategyIncomingStanza(response.get()));
103 
104   EXPECT_CALL(callback_, OnReply(request_.get(), XmlEq(response.get())));
105   message_loop_.RunUntilIdle();
106 }
107 
TEST_F(IqSenderTest,Timeout)108 TEST_F(IqSenderTest, Timeout) {
109   ASSERT_NO_FATAL_FAILURE({
110     SendTestMessage();
111   });
112 
113   request_->SetTimeout(base::TimeDelta::FromMilliseconds(2));
114 
115   EXPECT_CALL(callback_, OnReply(request_.get(), NULL))
116       .WillOnce(InvokeWithoutArgs(&message_loop_, &base::MessageLoop::Quit));
117   message_loop_.Run();
118 }
119 
TEST_F(IqSenderTest,InvalidFrom)120 TEST_F(IqSenderTest, InvalidFrom) {
121   ASSERT_NO_FATAL_FAILURE({
122     SendTestMessage();
123   });
124 
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");
129 
130   XmlElement* result = new XmlElement(
131       QName("test:namespace", "response-body"));
132   response->AddElement(result);
133 
134   EXPECT_CALL(callback_, OnReply(_, _))
135       .Times(0);
136   EXPECT_FALSE(sender_->OnSignalStrategyIncomingStanza(response.get()));
137   message_loop_.RunUntilIdle();
138 }
139 
TEST_F(IqSenderTest,IdMatchingHack)140 TEST_F(IqSenderTest, IdMatchingHack) {
141   ASSERT_NO_FATAL_FAILURE({
142     SendTestMessage();
143   });
144 
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);
149 
150   XmlElement* result = new XmlElement(
151       QName("test:namespace", "response-body"));
152   response->AddElement(result);
153 
154   EXPECT_TRUE(sender_->OnSignalStrategyIncomingStanza(response.get()));
155 
156   EXPECT_CALL(callback_, OnReply(request_.get(), XmlEq(response.get())));
157   message_loop_.RunUntilIdle();
158 }
159 
160 }  // namespace remoting
161