network_configuration_handler_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/json/json_writer.h"
7#include "base/message_loop.h"
8#include "base/strings/string_piece.h"
9#include "base/values.h"
10#include "chromeos/dbus/dbus_thread_manager.h"
11#include "chromeos/dbus/mock_dbus_thread_manager.h"
12#include "chromeos/dbus/mock_shill_manager_client.h"
13#include "chromeos/dbus/mock_shill_service_client.h"
14#include "chromeos/network/network_configuration_handler.h"
15#include "testing/gmock/include/gmock/gmock.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18using ::testing::_;
19using ::testing::Invoke;
20using ::testing::Pointee;
21using ::testing::Return;
22using ::testing::SaveArg;
23using ::testing::StrEq;
24
25// Matcher to match base::Value.
26MATCHER_P(IsEqualTo, value, "") { return arg.Equals(value); }
27
28namespace chromeos {
29
30namespace {
31
32static std::string PrettyJson(const base::DictionaryValue& value) {
33  std::string pretty;
34  base::JSONWriter::WriteWithOptions(&value,
35                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
36                                     &pretty);
37  return pretty;
38}
39
40void DictionaryValueCallback(
41    const std::string& expected_id,
42    const std::string& expected_json,
43    const std::string& service_path,
44    const base::DictionaryValue& dictionary) {
45  std::string dict_str = PrettyJson(dictionary);
46  EXPECT_EQ(expected_json, dict_str);
47  EXPECT_EQ(expected_id, service_path);
48}
49
50void ErrorCallback(bool error_expected,
51                   const std::string& expected_id,
52                   const std::string& error_name,
53                   const scoped_ptr<base::DictionaryValue> error_data) {
54  EXPECT_TRUE(error_expected) << "Unexpected error: " << error_name
55      << " with associated data: \n"
56      << PrettyJson(*error_data);
57}
58
59void StringResultCallback(const std::string& expected_result,
60                          const std::string& result) {
61  EXPECT_EQ(expected_result, result);
62}
63
64void DBusErrorCallback(const std::string& error_name,
65                       const std::string& error_message) {
66  EXPECT_TRUE(false) << "DBus Error: " << error_name << "("
67      << error_message << ")";
68}
69
70}  // namespace
71
72class NetworkConfigurationHandlerTest : public testing::Test {
73 public:
74  NetworkConfigurationHandlerTest()
75 : mock_manager_client_(NULL),
76   mock_service_client_(NULL),
77   dictionary_value_result_(NULL) {}
78  virtual ~NetworkConfigurationHandlerTest() {}
79
80  virtual void SetUp() OVERRIDE {
81    MockDBusThreadManager* mock_dbus_thread_manager = new MockDBusThreadManager;
82    EXPECT_CALL(*mock_dbus_thread_manager, GetSystemBus())
83    .WillRepeatedly(Return(reinterpret_cast<dbus::Bus*>(NULL)));
84    DBusThreadManager::InitializeForTesting(mock_dbus_thread_manager);
85    mock_manager_client_ =
86        mock_dbus_thread_manager->mock_shill_manager_client();
87    mock_service_client_ =
88        mock_dbus_thread_manager->mock_shill_service_client();
89
90    // Initialize DBusThreadManager with a stub implementation.
91    NetworkConfigurationHandler::Initialize();
92    message_loop_.RunUntilIdle();
93  }
94
95  virtual void TearDown() OVERRIDE {
96    NetworkConfigurationHandler::Shutdown();
97    DBusThreadManager::Shutdown();
98  }
99
100  // Handles responses for GetProperties method calls.
101  void OnGetProperties(
102      const dbus::ObjectPath& path,
103      const ShillClientHelper::DictionaryValueCallback& callback) {
104    callback.Run(DBUS_METHOD_CALL_SUCCESS, *dictionary_value_result_);
105  }
106
107  // Handles responses for SetProperties method calls.
108  void OnSetProperties(const base::DictionaryValue& properties,
109                       const ObjectPathCallback& callback,
110                       const ShillClientHelper::ErrorCallback& error_callback) {
111    callback.Run(dbus::ObjectPath());
112  }
113
114  // Handles responses for ClearProperties method calls.
115  void OnClearProperties(
116      const dbus::ObjectPath& service_path,
117      const std::vector<std::string>& names,
118      const ShillClientHelper::ListValueCallback& callback,
119      const ShillClientHelper::ErrorCallback& error_callback) {
120    base::ListValue result;
121    result.AppendBoolean(true);
122    callback.Run(result);
123  }
124
125  // Handles responses for ClearProperties method calls, and simulates an error
126  // result.
127  void OnClearPropertiesError(
128      const dbus::ObjectPath& service_path,
129      const std::vector<std::string>& names,
130      const ShillClientHelper::ListValueCallback& callback,
131      const ShillClientHelper::ErrorCallback& error_callback) {
132    base::ListValue result;
133    result.AppendBoolean(false);
134    callback.Run(result);
135  }
136
137  void OnConnect(const dbus::ObjectPath& service_path,
138                 const base::Closure& callback,
139                 const ShillClientHelper::ErrorCallback& error_callback) {
140    callback.Run();
141  }
142
143  void OnDisconnect(const dbus::ObjectPath& service_path,
144                    const base::Closure& callback,
145                    const ShillClientHelper::ErrorCallback& error_callback) {
146    callback.Run();
147  }
148
149  void OnGetService(const base::DictionaryValue& properties,
150                    const ObjectPathCallback& callback,
151                    const ShillClientHelper::ErrorCallback& error_callback) {
152    callback.Run(dbus::ObjectPath("/service/2"));
153  }
154
155  void OnRemove(const dbus::ObjectPath& service_path,
156                    const base::Closure& callback,
157                    const ShillClientHelper::ErrorCallback& error_callback) {
158    callback.Run();
159  }
160
161 protected:
162  MockShillManagerClient* mock_manager_client_;
163  MockShillServiceClient* mock_service_client_;
164  MessageLoop message_loop_;
165  base::DictionaryValue* dictionary_value_result_;
166};
167
168TEST_F(NetworkConfigurationHandlerTest, GetProperties) {
169  std::string service_path = "/service/1";
170  std::string expected_json = "{\n   \"SSID\": \"MyNetwork\"\n}\n";
171  std::string networkName = "MyNetwork";
172  std::string key = "SSID";
173  scoped_ptr<base::StringValue> networkNameValue(
174      base::Value::CreateStringValue(networkName));
175
176  base::DictionaryValue value;
177  value.Set(key, base::Value::CreateStringValue(networkName));
178  dictionary_value_result_ = &value;
179  EXPECT_CALL(*mock_service_client_,
180              SetProperty(dbus::ObjectPath(service_path), key,
181                          IsEqualTo(networkNameValue.get()), _, _)).Times(1);
182  DBusThreadManager::Get()->GetShillServiceClient()->SetProperty(
183      dbus::ObjectPath(service_path), key, *networkNameValue,
184      base::Bind(&base::DoNothing),
185      base::Bind(&DBusErrorCallback));
186  message_loop_.RunUntilIdle();
187
188  ShillServiceClient::DictionaryValueCallback get_properties_callback;
189  EXPECT_CALL(*mock_service_client_,
190              GetProperties(_, _)).WillOnce(
191                  Invoke(this,
192                         &NetworkConfigurationHandlerTest::OnGetProperties));
193  NetworkConfigurationHandler::Get()->GetProperties(
194      service_path,
195      base::Bind(&DictionaryValueCallback,
196                 service_path,
197                 expected_json),
198                 base::Bind(&ErrorCallback, false, service_path));
199  message_loop_.RunUntilIdle();
200}
201
202TEST_F(NetworkConfigurationHandlerTest, SetProperties) {
203  std::string service_path = "/service/1";
204  std::string networkName = "MyNetwork";
205  std::string key = "SSID";
206  scoped_ptr<base::StringValue> networkNameValue(
207      base::Value::CreateStringValue(networkName));
208
209  base::DictionaryValue value;
210  value.Set(key, base::Value::CreateStringValue(networkName));
211  dictionary_value_result_ = &value;
212  EXPECT_CALL(*mock_manager_client_,
213              ConfigureService(_, _, _)).WillOnce(
214                  Invoke(this,
215                         &NetworkConfigurationHandlerTest::OnSetProperties));
216  NetworkConfigurationHandler::Get()->SetProperties(
217      service_path,
218      value,
219      base::Bind(&base::DoNothing),
220      base::Bind(&ErrorCallback, false, service_path));
221  message_loop_.RunUntilIdle();
222}
223
224TEST_F(NetworkConfigurationHandlerTest, ClearProperties) {
225  std::string service_path = "/service/1";
226  std::string networkName = "MyNetwork";
227  std::string key = "SSID";
228  scoped_ptr<base::StringValue> networkNameValue(
229      base::Value::CreateStringValue(networkName));
230
231  // First set up a value to clear.
232  base::DictionaryValue value;
233  value.Set(key, base::Value::CreateStringValue(networkName));
234  dictionary_value_result_ = &value;
235  EXPECT_CALL(*mock_manager_client_,
236              ConfigureService(_, _, _)).WillOnce(
237                  Invoke(this,
238                         &NetworkConfigurationHandlerTest::OnSetProperties));
239  NetworkConfigurationHandler::Get()->SetProperties(
240      service_path,
241      value,
242      base::Bind(&base::DoNothing),
243      base::Bind(&ErrorCallback, false, service_path));
244  message_loop_.RunUntilIdle();
245
246  // Now clear it.
247  std::vector<std::string> values_to_clear;
248  values_to_clear.push_back(key);
249  EXPECT_CALL(*mock_service_client_,
250              ClearProperties(_, _, _, _)).WillOnce(
251                  Invoke(this,
252                         &NetworkConfigurationHandlerTest::OnClearProperties));
253  NetworkConfigurationHandler::Get()->ClearProperties(
254      service_path,
255      values_to_clear,
256      base::Bind(&base::DoNothing),
257      base::Bind(&ErrorCallback, false, service_path));
258  message_loop_.RunUntilIdle();
259}
260
261TEST_F(NetworkConfigurationHandlerTest, ClearPropertiesError) {
262  std::string service_path = "/service/1";
263  std::string networkName = "MyNetwork";
264  std::string key = "SSID";
265  scoped_ptr<base::StringValue> networkNameValue(
266      base::Value::CreateStringValue(networkName));
267
268  // First set up a value to clear.
269  base::DictionaryValue value;
270  value.Set(key, base::Value::CreateStringValue(networkName));
271  dictionary_value_result_ = &value;
272  EXPECT_CALL(*mock_manager_client_,
273              ConfigureService(_, _, _)).WillOnce(
274                  Invoke(this,
275                         &NetworkConfigurationHandlerTest::OnSetProperties));
276  NetworkConfigurationHandler::Get()->SetProperties(
277      service_path,
278      value,
279      base::Bind(&base::DoNothing),
280      base::Bind(&ErrorCallback, false, service_path));
281  message_loop_.RunUntilIdle();
282
283  // Now clear it.
284  std::vector<std::string> values_to_clear;
285  values_to_clear.push_back(key);
286  EXPECT_CALL(
287      *mock_service_client_,
288      ClearProperties(_, _, _, _)).WillOnce(
289          Invoke(this,
290                 &NetworkConfigurationHandlerTest::OnClearPropertiesError));
291  NetworkConfigurationHandler::Get()->ClearProperties(
292      service_path,
293      values_to_clear,
294      base::Bind(&base::DoNothing),
295      base::Bind(&ErrorCallback, true, service_path));
296  message_loop_.RunUntilIdle();
297}
298
299TEST_F(NetworkConfigurationHandlerTest, Connect) {
300  std::string service_path = "/service/1";
301
302  EXPECT_CALL(*mock_service_client_,
303              Connect(_, _, _)).WillOnce(
304                  Invoke(this,
305                         &NetworkConfigurationHandlerTest::OnConnect));
306  NetworkConfigurationHandler::Get()->Connect(
307      service_path,
308      base::Bind(&base::DoNothing),
309      base::Bind(&ErrorCallback, false, service_path));
310  message_loop_.RunUntilIdle();
311}
312
313TEST_F(NetworkConfigurationHandlerTest, Disconnect) {
314  std::string service_path = "/service/1";
315
316  EXPECT_CALL(*mock_service_client_,
317              Disconnect(_, _, _)).WillOnce(
318                  Invoke(this,
319                         &NetworkConfigurationHandlerTest::OnDisconnect));
320  NetworkConfigurationHandler::Get()->Disconnect(
321      service_path,
322      base::Bind(&base::DoNothing),
323      base::Bind(&ErrorCallback, false, service_path));
324  message_loop_.RunUntilIdle();
325}
326
327TEST_F(NetworkConfigurationHandlerTest, CreateConfiguration) {
328  std::string expected_json = "{\n   \"SSID\": \"MyNetwork\"\n}\n";
329  std::string networkName = "MyNetwork";
330  std::string key = "SSID";
331  scoped_ptr<base::StringValue> networkNameValue(
332      base::Value::CreateStringValue(networkName));
333  base::DictionaryValue value;
334  value.Set(key, base::Value::CreateStringValue(networkName));
335
336  EXPECT_CALL(
337      *mock_manager_client_,
338      GetService(_, _, _)).WillOnce(
339          Invoke(this,
340                 &NetworkConfigurationHandlerTest::OnGetService));
341  NetworkConfigurationHandler::Get()->CreateConfiguration(
342      value,
343      base::Bind(&StringResultCallback, std::string("/service/2")),
344      base::Bind(&ErrorCallback, false, std::string("")));
345  message_loop_.RunUntilIdle();
346}
347
348TEST_F(NetworkConfigurationHandlerTest, RemoveConfiguration) {
349  std::string service_path = "/service/1";
350
351  EXPECT_CALL(
352      *mock_service_client_,
353      Remove(_, _, _)).WillOnce(
354          Invoke(this,
355                 &NetworkConfigurationHandlerTest::OnRemove));
356  NetworkConfigurationHandler::Get()->RemoveConfiguration(
357      service_path,
358      base::Bind(&base::DoNothing),
359      base::Bind(&ErrorCallback, false, service_path));
360  message_loop_.RunUntilIdle();
361}
362
363}  // namespace chromeos
364