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.
5 #include "chromeos/dbus/modem_messaging_client.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/values.h"
12 #include "dbus/message.h"
13 #include "dbus/mock_bus.h"
14 #include "dbus/mock_object_proxy.h"
15 #include "dbus/object_path.h"
16 #include "dbus/values_util.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
22 using ::testing::Invoke
;
23 using ::testing::Return
;
29 // A mock SmsReceivedHandler.
30 class MockSmsReceivedHandler
{
32 MOCK_METHOD2(Run
, void(const dbus::ObjectPath
&sms
, bool complete
));
35 // A mock DeleteCallback.
36 class MockDeleteCallback
{
38 MOCK_METHOD0(Run
, void());
41 // A mock ListCallback.
42 class MockListCallback
{
44 MOCK_METHOD1(Run
, void(const std::vector
<dbus::ObjectPath
>& result
));
47 // D-Bus service name used by test.
48 const char kServiceName
[] = "service.name";
49 // D-Bus object path used by test.
50 const char kObjectPath
[] = "/object/path";
54 class ModemMessagingClientTest
: public testing::Test
{
56 ModemMessagingClientTest() : response_(NULL
),
57 expected_result_(NULL
) {}
59 void SetUp() override
{
61 dbus::Bus::Options options
;
62 options
.bus_type
= dbus::Bus::SYSTEM
;
63 mock_bus_
= new dbus::MockBus(options
);
65 // Create a mock proxy.
66 mock_proxy_
= new dbus::MockObjectProxy(mock_bus_
.get(),
68 dbus::ObjectPath(kObjectPath
));
70 // Set an expectation so mock_proxy's ConnectToSignal() will use
71 // OnConnectToSignal() to run the callback.
72 EXPECT_CALL(*mock_proxy_
.get(),
73 ConnectToSignal(modemmanager::kModemManager1MessagingInterface
,
74 modemmanager::kSMSAddedSignal
,
78 Invoke(this, &ModemMessagingClientTest::OnConnectToSignal
));
80 // Set an expectation so mock_bus's GetObjectProxy() for the given
81 // service name and the object path will return mock_proxy_.
82 EXPECT_CALL(*mock_bus_
.get(),
83 GetObjectProxy(kServiceName
, dbus::ObjectPath(kObjectPath
)))
84 .WillOnce(Return(mock_proxy_
.get()));
86 // ShutdownAndBlock() will be called in TearDown().
87 EXPECT_CALL(*mock_bus_
.get(), ShutdownAndBlock()).WillOnce(Return());
89 // Create a client with the mock bus.
90 client_
.reset(ModemMessagingClient::Create());
91 client_
->Init(mock_bus_
.get());
94 void TearDown() override
{ mock_bus_
->ShutdownAndBlock(); }
96 // Handles Delete method call.
97 void OnDelete(dbus::MethodCall
* method_call
,
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());
109 message_loop_
.task_runner()->PostTask(FROM_HERE
,
110 base::Bind(callback
, response_
));
113 // Handles List method call.
114 void OnList(dbus::MethodCall
* method_call
,
116 const dbus::ObjectProxy::ResponseCallback
& callback
) {
117 EXPECT_EQ(modemmanager::kModemManager1MessagingInterface
,
118 method_call
->GetInterface());
119 EXPECT_EQ(modemmanager::kSMSListFunction
, method_call
->GetMember());
120 dbus::MessageReader
reader(method_call
);
121 EXPECT_FALSE(reader
.HasMoreData());
123 message_loop_
.task_runner()->PostTask(FROM_HERE
,
124 base::Bind(callback
, response_
));
127 // Checks the results of List.
128 void CheckResult(const std::vector
<dbus::ObjectPath
>& result
) {
129 EXPECT_EQ(result
, *expected_result_
);
133 // The client to be tested.
134 scoped_ptr
<ModemMessagingClient
> client_
;
135 // A message loop to emulate asynchronous behavior.
136 base::MessageLoop message_loop_
;
138 scoped_refptr
<dbus::MockBus
> mock_bus_
;
139 // The mock object proxy.
140 scoped_refptr
<dbus::MockObjectProxy
> mock_proxy_
;
141 // The SmsReceived signal handler given by the tested client.
142 dbus::ObjectProxy::SignalCallback sms_received_callback_
;
143 // Expected argument for Delete method.
144 dbus::ObjectPath expected_sms_path_
;
145 // Response returned by mock methods.
146 dbus::Response
* response_
;
147 // Expected result of List method.
148 std::vector
<dbus::ObjectPath
>* expected_result_
;
151 // Used to implement the mock proxy.
152 void OnConnectToSignal(
153 const std::string
& interface_name
,
154 const std::string
& signal_name
,
155 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
156 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
157 sms_received_callback_
= signal_callback
;
158 const bool success
= true;
159 message_loop_
.task_runner()->PostTask(
160 FROM_HERE
, base::Bind(on_connected_callback
, interface_name
,
161 signal_name
, success
));
165 TEST_F(ModemMessagingClientTest
, SmsReceived
) {
167 const dbus::ObjectPath
kSmsPath("/SMS/0");
168 const bool kComplete
= true;
169 MockSmsReceivedHandler handler
;
170 EXPECT_CALL(handler
, Run(kSmsPath
, kComplete
)).Times(1);
172 client_
->SetSmsReceivedHandler(kServiceName
, dbus::ObjectPath(kObjectPath
),
173 base::Bind(&MockSmsReceivedHandler::Run
,
174 base::Unretained(&handler
)));
176 // Run the message loop to run the signal connection result callback.
177 message_loop_
.RunUntilIdle();
180 dbus::Signal
signal(modemmanager::kModemManager1MessagingInterface
,
181 modemmanager::kSMSAddedSignal
);
182 dbus::MessageWriter
writer(&signal
);
183 writer
.AppendObjectPath(kSmsPath
);
184 writer
.AppendBool(kComplete
);
185 ASSERT_FALSE(sms_received_callback_
.is_null());
186 sms_received_callback_
.Run(&signal
);
188 client_
->ResetSmsReceivedHandler(kServiceName
, dbus::ObjectPath(kObjectPath
));
189 // Send signal again.
190 sms_received_callback_
.Run(&signal
);
193 TEST_F(ModemMessagingClientTest
, Delete
) {
195 const dbus::ObjectPath
kSmsPath("/SMS/0");
196 expected_sms_path_
= kSmsPath
;
197 EXPECT_CALL(*mock_proxy_
.get(), CallMethod(_
, _
, _
))
198 .WillOnce(Invoke(this, &ModemMessagingClientTest::OnDelete
));
199 MockDeleteCallback callback
;
200 EXPECT_CALL(callback
, Run()).Times(1);
202 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
203 response_
= response
.get();
205 client_
->Delete(kServiceName
, dbus::ObjectPath(kObjectPath
), kSmsPath
,
206 base::Bind(&MockDeleteCallback::Run
,
207 base::Unretained(&callback
)));
209 // Run the message loop.
210 message_loop_
.RunUntilIdle();
213 TEST_F(ModemMessagingClientTest
, List
) {
215 EXPECT_CALL(*mock_proxy_
.get(), CallMethod(_
, _
, _
))
216 .WillOnce(Invoke(this, &ModemMessagingClientTest::OnList
));
217 MockListCallback callback
;
218 EXPECT_CALL(callback
, Run(_
))
219 .WillOnce(Invoke(this, &ModemMessagingClientTest::CheckResult
));
221 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
222 dbus::ObjectPath
path1("/SMS/1");
223 dbus::ObjectPath
path2("/SMS/2");
224 std::vector
<dbus::ObjectPath
> expected_result
;
225 expected_result
.push_back(path1
);
226 expected_result
.push_back(path2
);
228 dbus::MessageWriter
writer(response
.get());
229 writer
.AppendArrayOfObjectPaths(expected_result
);
230 response_
= response
.get();
232 // Save expected result.
233 expected_result_
= &expected_result
;
235 client_
->List(kServiceName
, dbus::ObjectPath(kObjectPath
),
236 base::Bind(&MockListCallback::Run
,
237 base::Unretained(&callback
)));
239 // Run the message loop.
240 message_loop_
.RunUntilIdle();
243 } // namespace chromeos