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.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";
50 // Keys of SMS dictionary.
51 const char kNumberKey
[] = "number";
52 const char kTextKey
[] = "text";
54 // Example values of SMS dictionary.
55 const char kExampleNumber
[] = "00012345678";
56 const char kExampleText
[] = "Hello.";
60 class ModemMessagingClientTest
: public testing::Test
{
62 ModemMessagingClientTest() : response_(NULL
),
63 expected_result_(NULL
) {}
65 virtual void SetUp() OVERRIDE
{
67 dbus::Bus::Options options
;
68 options
.bus_type
= dbus::Bus::SYSTEM
;
69 mock_bus_
= new dbus::MockBus(options
);
71 // Create a mock proxy.
72 mock_proxy_
= new dbus::MockObjectProxy(mock_bus_
.get(),
74 dbus::ObjectPath(kObjectPath
));
76 // Set an expectation so mock_proxy's ConnectToSignal() will use
77 // OnConnectToSignal() to run the callback.
78 EXPECT_CALL(*mock_proxy_
, ConnectToSignal(
79 modemmanager::kModemManager1MessagingInterface
,
80 modemmanager::kSMSAddedSignal
, _
, _
))
82 Invoke(this, &ModemMessagingClientTest::OnConnectToSignal
));
84 // Set an expectation so mock_bus's GetObjectProxy() for the given
85 // service name and the object path will return mock_proxy_.
86 EXPECT_CALL(*mock_bus_
, GetObjectProxy(kServiceName
,
87 dbus::ObjectPath(kObjectPath
)))
88 .WillOnce(Return(mock_proxy_
.get()));
90 // ShutdownAndBlock() will be called in TearDown().
91 EXPECT_CALL(*mock_bus_
, ShutdownAndBlock()).WillOnce(Return());
93 // Create a client with the mock bus.
94 client_
.reset(ModemMessagingClient::Create(REAL_DBUS_CLIENT_IMPLEMENTATION
,
98 virtual void TearDown() OVERRIDE
{
99 mock_bus_
->ShutdownAndBlock();
102 // Handles Delete method call.
103 void OnDelete(dbus::MethodCall
* method_call
,
105 const dbus::ObjectProxy::ResponseCallback
& callback
) {
106 EXPECT_EQ(modemmanager::kModemManager1MessagingInterface
,
107 method_call
->GetInterface());
108 EXPECT_EQ(modemmanager::kSMSDeleteFunction
, method_call
->GetMember());
109 dbus::ObjectPath sms_path
;
110 dbus::MessageReader
reader(method_call
);
111 EXPECT_TRUE(reader
.PopObjectPath(&sms_path
));
112 EXPECT_EQ(expected_sms_path_
, sms_path
);
113 EXPECT_FALSE(reader
.HasMoreData());
115 message_loop_
.PostTask(FROM_HERE
, base::Bind(callback
, response_
));
118 // Handles List method call.
119 void OnList(dbus::MethodCall
* method_call
,
121 const dbus::ObjectProxy::ResponseCallback
& callback
) {
122 EXPECT_EQ(modemmanager::kModemManager1MessagingInterface
,
123 method_call
->GetInterface());
124 EXPECT_EQ(modemmanager::kSMSListFunction
, method_call
->GetMember());
125 dbus::MessageReader
reader(method_call
);
126 EXPECT_FALSE(reader
.HasMoreData());
128 message_loop_
.PostTask(FROM_HERE
, base::Bind(callback
, response_
));
131 // Checks the results of List.
132 void CheckResult(const std::vector
<dbus::ObjectPath
>& result
) {
133 EXPECT_EQ(result
, *expected_result_
);
137 // The client to be tested.
138 scoped_ptr
<ModemMessagingClient
> client_
;
139 // A message loop to emulate asynchronous behavior.
140 base::MessageLoop message_loop_
;
142 scoped_refptr
<dbus::MockBus
> mock_bus_
;
143 // The mock object proxy.
144 scoped_refptr
<dbus::MockObjectProxy
> mock_proxy_
;
145 // The SmsReceived signal handler given by the tested client.
146 dbus::ObjectProxy::SignalCallback sms_received_callback_
;
147 // Expected argument for Delete method.
148 dbus::ObjectPath expected_sms_path_
;
149 // Response returned by mock methods.
150 dbus::Response
* response_
;
151 // Expected result of List method.
152 std::vector
<dbus::ObjectPath
>* expected_result_
;
155 // Used to implement the mock proxy.
156 void OnConnectToSignal(
157 const std::string
& interface_name
,
158 const std::string
& signal_name
,
159 const dbus::ObjectProxy::SignalCallback
& signal_callback
,
160 const dbus::ObjectProxy::OnConnectedCallback
& on_connected_callback
) {
161 sms_received_callback_
= signal_callback
;
162 const bool success
= true;
163 message_loop_
.PostTask(FROM_HERE
, base::Bind(on_connected_callback
,
170 TEST_F(ModemMessagingClientTest
, SmsReceived
) {
172 const dbus::ObjectPath
kSmsPath("/SMS/0");
173 const bool kComplete
= true;
174 MockSmsReceivedHandler handler
;
175 EXPECT_CALL(handler
, Run(kSmsPath
, kComplete
)).Times(1);
177 client_
->SetSmsReceivedHandler(kServiceName
, dbus::ObjectPath(kObjectPath
),
178 base::Bind(&MockSmsReceivedHandler::Run
,
179 base::Unretained(&handler
)));
181 // Run the message loop to run the signal connection result callback.
182 message_loop_
.RunUntilIdle();
185 dbus::Signal
signal(modemmanager::kModemManager1MessagingInterface
,
186 modemmanager::kSMSAddedSignal
);
187 dbus::MessageWriter
writer(&signal
);
188 writer
.AppendObjectPath(kSmsPath
);
189 writer
.AppendBool(kComplete
);
190 ASSERT_FALSE(sms_received_callback_
.is_null());
191 sms_received_callback_
.Run(&signal
);
193 client_
->ResetSmsReceivedHandler(kServiceName
, dbus::ObjectPath(kObjectPath
));
194 // Send signal again.
195 sms_received_callback_
.Run(&signal
);
198 TEST_F(ModemMessagingClientTest
, Delete
) {
200 const dbus::ObjectPath
kSmsPath("/SMS/0");
201 expected_sms_path_
= kSmsPath
;
202 EXPECT_CALL(*mock_proxy_
, CallMethod(_
, _
, _
))
203 .WillOnce(Invoke(this, &ModemMessagingClientTest::OnDelete
));
204 MockDeleteCallback callback
;
205 EXPECT_CALL(callback
, Run()).Times(1);
207 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
208 response_
= response
.get();
210 client_
->Delete(kServiceName
, dbus::ObjectPath(kObjectPath
), kSmsPath
,
211 base::Bind(&MockDeleteCallback::Run
,
212 base::Unretained(&callback
)));
214 // Run the message loop.
215 message_loop_
.RunUntilIdle();
218 TEST_F(ModemMessagingClientTest
, List
) {
220 EXPECT_CALL(*mock_proxy_
, CallMethod(_
, _
, _
))
221 .WillOnce(Invoke(this, &ModemMessagingClientTest::OnList
));
222 MockListCallback callback
;
223 EXPECT_CALL(callback
, Run(_
))
224 .WillOnce(Invoke(this, &ModemMessagingClientTest::CheckResult
));
226 scoped_ptr
<dbus::Response
> response(dbus::Response::CreateEmpty());
227 dbus::ObjectPath
path1("/SMS/1");
228 dbus::ObjectPath
path2("/SMS/2");
229 std::vector
<dbus::ObjectPath
> expected_result
;
230 expected_result
.push_back(path1
);
231 expected_result
.push_back(path2
);
233 dbus::MessageWriter
writer(response
.get());
234 writer
.AppendArrayOfObjectPaths(expected_result
);
235 response_
= response
.get();
237 // Save expected result.
238 expected_result_
= &expected_result
;
240 client_
->List(kServiceName
, dbus::ObjectPath(kObjectPath
),
241 base::Bind(&MockListCallback::Run
,
242 base::Unretained(&callback
)));
244 // Run the message loop.
245 message_loop_
.RunUntilIdle();
248 } // namespace chromeos