Home | History | Annotate | Download | only in dbus
      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 "chromeos/dbus/modem_messaging_client.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/values.h"
     10 #include "dbus/message.h"
     11 #include "dbus/mock_bus.h"
     12 #include "dbus/mock_object_proxy.h"
     13 #include "dbus/object_path.h"
     14 #include "dbus/values_util.h"
     15 #include "testing/gmock/include/gmock/gmock.h"
     16 #include "testing/gtest/include/gtest/gtest.h"
     17 #include "third_party/cros_system_api/dbus/service_constants.h"
     18 
     19 using ::testing::_;
     20 using ::testing::Invoke;
     21 using ::testing::Return;
     22 
     23 namespace chromeos {
     24 
     25 namespace {
     26 
     27 // A mock SmsReceivedHandler.
     28 class MockSmsReceivedHandler {
     29  public:
     30   MOCK_METHOD2(Run, void(const dbus::ObjectPath &sms, bool complete));
     31 };
     32 
     33 // A mock DeleteCallback.
     34 class MockDeleteCallback {
     35  public:
     36   MOCK_METHOD0(Run, void());
     37 };
     38 
     39 // A mock ListCallback.
     40 class MockListCallback {
     41  public:
     42   MOCK_METHOD1(Run, void(const std::vector<dbus::ObjectPath>& result));
     43 };
     44 
     45 // D-Bus service name used by test.
     46 const char kServiceName[] = "service.name";
     47 // D-Bus object path used by test.
     48 const char kObjectPath[] = "/object/path";
     49 
     50 }  // namespace
     51 
     52 class ModemMessagingClientTest : public testing::Test {
     53  public:
     54   ModemMessagingClientTest() : response_(NULL),
     55                                expected_result_(NULL) {}
     56 
     57   virtual void SetUp() OVERRIDE {
     58     // Create a mock bus.
     59     dbus::Bus::Options options;
     60     options.bus_type = dbus::Bus::SYSTEM;
     61     mock_bus_ = new dbus::MockBus(options);
     62 
     63     // Create a mock proxy.
     64     mock_proxy_ = new dbus::MockObjectProxy(mock_bus_.get(),
     65                                             kServiceName,
     66                                             dbus::ObjectPath(kObjectPath));
     67 
     68     // Set an expectation so mock_proxy's ConnectToSignal() will use
     69     // OnConnectToSignal() to run the callback.
     70     EXPECT_CALL(*mock_proxy_.get(),
     71                 ConnectToSignal(modemmanager::kModemManager1MessagingInterface,
     72                                 modemmanager::kSMSAddedSignal,
     73                                 _,
     74                                 _))
     75         .WillRepeatedly(
     76              Invoke(this, &ModemMessagingClientTest::OnConnectToSignal));
     77 
     78     // Set an expectation so mock_bus's GetObjectProxy() for the given
     79     // service name and the object path will return mock_proxy_.
     80     EXPECT_CALL(*mock_bus_.get(),
     81                 GetObjectProxy(kServiceName, dbus::ObjectPath(kObjectPath)))
     82         .WillOnce(Return(mock_proxy_.get()));
     83 
     84     // ShutdownAndBlock() will be called in TearDown().
     85     EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
     86 
     87     // Create a client with the mock bus.
     88     client_.reset(ModemMessagingClient::Create());
     89     client_->Init(mock_bus_.get());
     90   }
     91 
     92   virtual void TearDown() OVERRIDE {
     93     mock_bus_->ShutdownAndBlock();
     94   }
     95 
     96   // Handles Delete method call.
     97   void OnDelete(dbus::MethodCall* method_call,
     98                 int timeout_ms,
     99                 const dbus::ObjectProxy::ResponseCallback& callback) {
    100     EXPECT_EQ(modemmanager::kModemManager1MessagingInterface,
    101               method_call->GetInterface());
    102     EXPECT_EQ(modemmanager::kSMSDeleteFunction, method_call->GetMember());
    103     dbus::ObjectPath sms_path;
    104     dbus::MessageReader reader(method_call);
    105     EXPECT_TRUE(reader.PopObjectPath(&sms_path));
    106     EXPECT_EQ(expected_sms_path_, sms_path);
    107     EXPECT_FALSE(reader.HasMoreData());
    108 
    109     message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
    110   }
    111 
    112   // Handles List method call.
    113   void OnList(dbus::MethodCall* method_call,
    114               int timeout_ms,
    115               const dbus::ObjectProxy::ResponseCallback& callback) {
    116     EXPECT_EQ(modemmanager::kModemManager1MessagingInterface,
    117               method_call->GetInterface());
    118     EXPECT_EQ(modemmanager::kSMSListFunction, method_call->GetMember());
    119     dbus::MessageReader reader(method_call);
    120     EXPECT_FALSE(reader.HasMoreData());
    121 
    122     message_loop_.PostTask(FROM_HERE, base::Bind(callback, response_));
    123   }
    124 
    125   // Checks the results of List.
    126   void CheckResult(const std::vector<dbus::ObjectPath>& result) {
    127     EXPECT_EQ(result, *expected_result_);
    128   }
    129 
    130  protected:
    131   // The client to be tested.
    132   scoped_ptr<ModemMessagingClient> client_;
    133   // A message loop to emulate asynchronous behavior.
    134   base::MessageLoop message_loop_;
    135   // The mock bus.
    136   scoped_refptr<dbus::MockBus> mock_bus_;
    137   // The mock object proxy.
    138   scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
    139   // The SmsReceived signal handler given by the tested client.
    140   dbus::ObjectProxy::SignalCallback sms_received_callback_;
    141   // Expected argument for Delete method.
    142   dbus::ObjectPath expected_sms_path_;
    143   // Response returned by mock methods.
    144   dbus::Response* response_;
    145   // Expected result of List method.
    146   std::vector<dbus::ObjectPath>* expected_result_;
    147 
    148  private:
    149   // Used to implement the mock proxy.
    150   void OnConnectToSignal(
    151       const std::string& interface_name,
    152       const std::string& signal_name,
    153       const dbus::ObjectProxy::SignalCallback& signal_callback,
    154       const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) {
    155     sms_received_callback_ = signal_callback;
    156     const bool success = true;
    157     message_loop_.PostTask(FROM_HERE, base::Bind(on_connected_callback,
    158                                                  interface_name,
    159                                                  signal_name,
    160                                                  success));
    161   }
    162 };
    163 
    164 TEST_F(ModemMessagingClientTest, SmsReceived) {
    165   // Set expectations.
    166   const dbus::ObjectPath kSmsPath("/SMS/0");
    167   const bool kComplete = true;
    168   MockSmsReceivedHandler handler;
    169   EXPECT_CALL(handler, Run(kSmsPath, kComplete)).Times(1);
    170   // Set handler.
    171   client_->SetSmsReceivedHandler(kServiceName, dbus::ObjectPath(kObjectPath),
    172                                  base::Bind(&MockSmsReceivedHandler::Run,
    173                                             base::Unretained(&handler)));
    174 
    175   // Run the message loop to run the signal connection result callback.
    176   message_loop_.RunUntilIdle();
    177 
    178   // Send signal.
    179   dbus::Signal signal(modemmanager::kModemManager1MessagingInterface,
    180                       modemmanager::kSMSAddedSignal);
    181   dbus::MessageWriter writer(&signal);
    182   writer.AppendObjectPath(kSmsPath);
    183   writer.AppendBool(kComplete);
    184   ASSERT_FALSE(sms_received_callback_.is_null());
    185   sms_received_callback_.Run(&signal);
    186   // Reset handler.
    187   client_->ResetSmsReceivedHandler(kServiceName, dbus::ObjectPath(kObjectPath));
    188   // Send signal again.
    189   sms_received_callback_.Run(&signal);
    190 }
    191 
    192 TEST_F(ModemMessagingClientTest, Delete) {
    193   // Set expectations.
    194   const dbus::ObjectPath kSmsPath("/SMS/0");
    195   expected_sms_path_ = kSmsPath;
    196   EXPECT_CALL(*mock_proxy_.get(), CallMethod(_, _, _))
    197       .WillOnce(Invoke(this, &ModemMessagingClientTest::OnDelete));
    198   MockDeleteCallback callback;
    199   EXPECT_CALL(callback, Run()).Times(1);
    200   // Create response.
    201   scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
    202   response_ = response.get();
    203   // Call Delete.
    204   client_->Delete(kServiceName, dbus::ObjectPath(kObjectPath), kSmsPath,
    205                   base::Bind(&MockDeleteCallback::Run,
    206                              base::Unretained(&callback)));
    207 
    208   // Run the message loop.
    209   message_loop_.RunUntilIdle();
    210 }
    211 
    212 TEST_F(ModemMessagingClientTest, List) {
    213   // Set expectations.
    214   EXPECT_CALL(*mock_proxy_.get(), CallMethod(_, _, _))
    215       .WillOnce(Invoke(this, &ModemMessagingClientTest::OnList));
    216   MockListCallback callback;
    217   EXPECT_CALL(callback, Run(_))
    218       .WillOnce(Invoke(this, &ModemMessagingClientTest::CheckResult));
    219   // Create response.
    220   scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
    221   dbus::ObjectPath path1("/SMS/1");
    222   dbus::ObjectPath path2("/SMS/2");
    223   std::vector<dbus::ObjectPath> expected_result;
    224   expected_result.push_back(path1);
    225   expected_result.push_back(path2);
    226 
    227   dbus::MessageWriter writer(response.get());
    228   writer.AppendArrayOfObjectPaths(expected_result);
    229   response_ = response.get();
    230 
    231   // Save expected result.
    232   expected_result_ = &expected_result;
    233   // Call List.
    234   client_->List(kServiceName, dbus::ObjectPath(kObjectPath),
    235                 base::Bind(&MockListCallback::Run,
    236                            base::Unretained(&callback)));
    237 
    238   // Run the message loop.
    239   message_loop_.RunUntilIdle();
    240 }
    241 
    242 }  // namespace chromeos
    243