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/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"
20 using ::testing::Invoke
;
21 using ::testing::Return
;
27 // A mock SmsReceivedHandler.
28 class MockSmsReceivedHandler
{
30 MOCK_METHOD2(Run
, void(const dbus::ObjectPath
&sms
, bool complete
));
33 // A mock DeleteCallback.
34 class MockDeleteCallback
{
36 MOCK_METHOD0(Run
, void());
39 // A mock ListCallback.
40 class MockListCallback
{
42 MOCK_METHOD1(Run
, void(const std::vector
<dbus::ObjectPath
>& result
));
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";
52 class ModemMessagingClientTest
: public testing::Test
{
54 ModemMessagingClientTest() : response_(NULL
),
55 expected_result_(NULL
) {}
57 void SetUp() override
{
59 dbus::Bus::Options options
;
60 options
.bus_type
= dbus::Bus::SYSTEM
;
61 mock_bus_
= new dbus::MockBus(options
);
63 // Create a mock proxy.
64 mock_proxy_
= new dbus::MockObjectProxy(mock_bus_
.get(),
66 dbus::ObjectPath(kObjectPath
));
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
,
76 Invoke(this, &ModemMessagingClientTest::OnConnectToSignal
));
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()));
84 // ShutdownAndBlock() will be called in TearDown().
85 EXPECT_CALL(*mock_bus_
.get(), ShutdownAndBlock()).WillOnce(Return());
87 // Create a client with the mock bus.
88 client_
.reset(ModemMessagingClient::Create());
89 client_
->Init(mock_bus_
.get());
92 void TearDown() override
{ mock_bus_
->ShutdownAndBlock(); }
94 // Handles Delete method call.
95 void OnDelete(dbus::MethodCall
* method_call
,
97 const dbus::ObjectProxy::ResponseCallback
& callback
) {
98 EXPECT_EQ(modemmanager::kModemManager1MessagingInterface
,
99 method_call
->GetInterface());
100 EXPECT_EQ(modemmanager::kSMSDeleteFunction
, method_call
->GetMember());
101 dbus::ObjectPath sms_path
;
102 dbus::MessageReader
reader(method_call
);
103 EXPECT_TRUE(reader
.PopObjectPath(&sms_path
));
104 EXPECT_EQ(expected_sms_path_
, sms_path
);
105 EXPECT_FALSE(reader
.HasMoreData());
107 message_loop_
.PostTask(FROM_HERE
, base::Bind(callback
, response_
));
110 // Handles List method call.
111 void OnList(dbus::MethodCall
* method_call
,
113 const dbus::ObjectProxy::ResponseCallback
& callback
) {
114 EXPECT_EQ(modemmanager::kModemManager1MessagingInterface
,
115 method_call
->GetInterface());
116 EXPECT_EQ(modemmanager::kSMSListFunction
, method_call
->GetMember());
117 dbus::MessageReader
reader(method_call
);
118 EXPECT_FALSE(reader
.HasMoreData());
120 message_loop_
.PostTask(FROM_HERE
, base::Bind(callback
, response_
));
123 // Checks the results of List.
124 void CheckResult(const std::vector
<dbus::ObjectPath
>& result
) {
125 EXPECT_EQ(result
, *expected_result_
);
129 // The client to be tested.
130 scoped_ptr
<ModemMessagingClient
> client_
;
131 // A message loop to emulate asynchronous behavior.
132 base::MessageLoop message_loop_
;
134 scoped_refptr
<dbus::MockBus
> mock_bus_
;
135 // The mock object proxy.
136 scoped_refptr
<dbus::MockObjectProxy
> mock_proxy_
;
137 // The SmsReceived signal handler given by the tested client.
138 dbus::ObjectProxy::SignalCallback sms_received_callback_
;
139 // Expected argument for Delete method.
140 dbus::ObjectPath expected_sms_path_
;
141 // Response returned by mock methods.
142 dbus::Response
* response_
;
143 // Expected result of List method.
144 std::vector
<dbus::ObjectPath
>* expected_result_
;
147 // Used to implement the mock proxy.
148 void OnConnectToSignal(
149 const std::string
& interface_name
,
150 const std::string
& signal_name
,
151 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
152 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
153 sms_received_callback_
= signal_callback
;
154 const bool success
= true;
155 message_loop_
.PostTask(FROM_HERE
, base::Bind(on_connected_callback
,
162 TEST_F(ModemMessagingClientTest
, SmsReceived
) {
164 const dbus::ObjectPath
kSmsPath("/SMS/0");
165 const bool kComplete
= true;
166 MockSmsReceivedHandler handler
;
167 EXPECT_CALL(handler
, Run(kSmsPath
, kComplete
)).Times(1);
169 client_
->SetSmsReceivedHandler(kServiceName
, dbus::ObjectPath(kObjectPath
),
170 base::Bind(&MockSmsReceivedHandler::Run
,
171 base::Unretained(&handler
)));
173 // Run the message loop to run the signal connection result callback.
174 message_loop_
.RunUntilIdle();
177 dbus::Signal
signal(modemmanager::kModemManager1MessagingInterface
,
178 modemmanager::kSMSAddedSignal
);
179 dbus::MessageWriter
writer(&signal
);
180 writer
.AppendObjectPath(kSmsPath
);
181 writer
.AppendBool(kComplete
);
182 ASSERT_FALSE(sms_received_callback_
.is_null());
183 sms_received_callback_
.Run(&signal
);
185 client_
->ResetSmsReceivedHandler(kServiceName
, dbus::ObjectPath(kObjectPath
));
186 // Send signal again.
187 sms_received_callback_
.Run(&signal
);
190 TEST_F(ModemMessagingClientTest
, Delete
) {
192 const dbus::ObjectPath
kSmsPath("/SMS/0");
193 expected_sms_path_
= kSmsPath
;
194 EXPECT_CALL(*mock_proxy_
.get(), CallMethod(_
, _
, _
))
195 .WillOnce(Invoke(this, &ModemMessagingClientTest::OnDelete
));
196 MockDeleteCallback callback
;
197 EXPECT_CALL(callback
, Run()).Times(1);
199 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
200 response_
= response
.get();
202 client_
->Delete(kServiceName
, dbus::ObjectPath(kObjectPath
), kSmsPath
,
203 base::Bind(&MockDeleteCallback::Run
,
204 base::Unretained(&callback
)));
206 // Run the message loop.
207 message_loop_
.RunUntilIdle();
210 TEST_F(ModemMessagingClientTest
, List
) {
212 EXPECT_CALL(*mock_proxy_
.get(), CallMethod(_
, _
, _
))
213 .WillOnce(Invoke(this, &ModemMessagingClientTest::OnList
));
214 MockListCallback callback
;
215 EXPECT_CALL(callback
, Run(_
))
216 .WillOnce(Invoke(this, &ModemMessagingClientTest::CheckResult
));
218 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
219 dbus::ObjectPath
path1("/SMS/1");
220 dbus::ObjectPath
path2("/SMS/2");
221 std::vector
<dbus::ObjectPath
> expected_result
;
222 expected_result
.push_back(path1
);
223 expected_result
.push_back(path2
);
225 dbus::MessageWriter
writer(response
.get());
226 writer
.AppendArrayOfObjectPaths(expected_result
);
227 response_
= response
.get();
229 // Save expected result.
230 expected_result_
= &expected_result
;
232 client_
->List(kServiceName
, dbus::ObjectPath(kObjectPath
),
233 base::Bind(&MockListCallback::Run
,
234 base::Unretained(&callback
)));
236 // Run the message loop.
237 message_loop_
.RunUntilIdle();
240 } // namespace chromeos