Home | History | Annotate | Download | only in jingle_glue
      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 (at) 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:
     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:
     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 
     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 
    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 
    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 (at) 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 
    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