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