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#ifndef CHROMEOS_DBUS_SHILL_CLIENT_UNITTEST_BASE_H_
6#define CHROMEOS_DBUS_SHILL_CLIENT_UNITTEST_BASE_H_
7
8#include <string>
9
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/message_loop/message_loop.h"
13#include "chromeos/dbus/dbus_method_call_status.h"
14#include "chromeos/dbus/shill_client_helper.h"
15#include "chromeos/dbus/shill_property_changed_observer.h"
16#include "dbus/mock_bus.h"
17#include "dbus/mock_object_proxy.h"
18#include "dbus/object_proxy.h"
19#include "testing/gtest/include/gtest/gtest.h"
20
21using ::testing::MatcherInterface;
22using ::testing::MatchResultListener;
23using ::testing::Matcher;
24using ::testing::MakeMatcher;
25
26namespace base {
27
28class Value;
29class DictionaryValue;
30
31}  // namespace base
32
33namespace dbus {
34
35class MessageReader;
36
37}  // namespace dbus
38
39namespace chromeos {
40
41// A gmock matcher for base::Value types, so we can match them in expectations.
42class ValueMatcher : public MatcherInterface<const base::Value&> {
43 public:
44  explicit ValueMatcher(const base::Value& value);
45
46  // MatcherInterface overrides.
47  virtual bool MatchAndExplain(const base::Value& value,
48                               MatchResultListener* listener) const OVERRIDE;
49  virtual void DescribeTo(::std::ostream* os) const OVERRIDE;
50  virtual void DescribeNegationTo(::std::ostream* os) const OVERRIDE;
51
52 private:
53  scoped_ptr<base::Value> expected_value_;
54};
55
56inline Matcher<const base::Value&> ValueEq(const base::Value& expected_value) {
57  return MakeMatcher(new ValueMatcher(expected_value));
58}
59
60// A class to provide functionalities needed for testing Shill D-Bus clients.
61class ShillClientUnittestBase : public testing::Test {
62 public:
63  // A mock Closure.
64  class MockClosure {
65   public:
66    MockClosure();
67    ~MockClosure();
68    MOCK_METHOD0(Run, void());
69    base::Closure GetCallback();
70  };
71
72  class MockListValueCallback {
73   public:
74    MockListValueCallback();
75    ~MockListValueCallback();
76    MOCK_METHOD1(Run, void(const base::ListValue& list));
77    ShillClientHelper::ListValueCallback GetCallback();
78  };
79
80  // A mock ErrorCallback.
81  class MockErrorCallback {
82   public:
83    MockErrorCallback();
84    ~MockErrorCallback();
85    MOCK_METHOD2(Run, void(const std::string& error_name,
86                           const std::string& error_message));
87    ShillClientHelper::ErrorCallback GetCallback();
88  };
89
90  // A mock PropertyChangedObserver that can be used to check expected values.
91  class MockPropertyChangeObserver
92      : public ShillPropertyChangedObserver {
93   public:
94    MockPropertyChangeObserver();
95    ~MockPropertyChangeObserver();
96    MOCK_METHOD2(OnPropertyChanged, void(const std::string& name,
97                                         const base::Value& value));
98  };
99
100  explicit ShillClientUnittestBase(const std::string& interface_name,
101                                      const dbus::ObjectPath& object_path);
102  virtual ~ShillClientUnittestBase();
103
104  virtual void SetUp() OVERRIDE;
105  virtual void TearDown() OVERRIDE;
106
107 protected:
108  // A callback to intercept and check the method call arguments.
109  typedef base::Callback<void(
110      dbus::MessageReader* reader)> ArgumentCheckCallback;
111
112  // Sets expectations for called method name and arguments, and sets response.
113  void PrepareForMethodCall(const std::string& method_name,
114                            const ArgumentCheckCallback& argument_checker,
115                            dbus::Response* response);
116
117  // Sends property changed signal to the tested client.
118  void SendPropertyChangedSignal(dbus::Signal* signal);
119
120  // Checks the name and the value which are sent by PropertyChanged signal.
121  static void ExpectPropertyChanged(const std::string& expected_name,
122                                    const base::Value* expected_value,
123                                    const std::string& name,
124                                    const base::Value& value);
125
126  // Expects the reader to be empty.
127  static void ExpectNoArgument(dbus::MessageReader* reader);
128
129  // Expects the reader to have a string.
130  static void ExpectStringArgument(const std::string& expected_string,
131                                   dbus::MessageReader* reader);
132
133  static void ExpectArrayOfStringsArgument(
134      const std::vector<std::string>& expected_strings,
135      dbus::MessageReader* reader);
136
137  // Expects the reader to have a Value.
138  static void ExpectValueArgument(const base::Value* expected_value,
139                                  dbus::MessageReader* reader);
140
141  // Expects the reader to have a string and a Value.
142  static void ExpectStringAndValueArguments(const std::string& expected_string,
143                                            const base::Value* expected_value,
144                                            dbus::MessageReader* reader);
145
146  // Expects the reader to have a string-to-variant dictionary.
147  static void ExpectDictionaryValueArgument(
148      const base::DictionaryValue* expected_dictionary,
149      dbus::MessageReader* reader);
150
151  // Creates a DictionaryValue with example Service properties. The caller owns
152  // the result.
153  static base::DictionaryValue* CreateExampleServiceProperties();
154
155  // Expects the call status to be SUCCESS.
156  static void ExpectNoResultValue(DBusMethodCallStatus call_status);
157
158  // Checks the result and expects the call status to be SUCCESS.
159  static void ExpectObjectPathResult(const dbus::ObjectPath& expected_result,
160                                     DBusMethodCallStatus call_status,
161                                     const dbus::ObjectPath& result);
162
163  static void ExpectObjectPathResultWithoutStatus(
164      const dbus::ObjectPath& expected_result,
165      const dbus::ObjectPath& result);
166
167  static void ExpectBoolResultWithoutStatus(
168      bool expected_result,
169      bool result);
170
171  static void ExpectStringResultWithoutStatus(
172      const std::string& expected_result,
173      const std::string& result);
174
175  // Checks the result and expects the call status to be SUCCESS.
176  static void ExpectDictionaryValueResult(
177      const base::DictionaryValue* expected_result,
178      DBusMethodCallStatus call_status,
179      const base::DictionaryValue& result);
180
181  // Expects the |expected_result| to match the |result|.
182  static void ExpectDictionaryValueResultWithoutStatus(
183      const base::DictionaryValue* expected_result,
184      const base::DictionaryValue& result);
185
186  // A message loop to emulate asynchronous behavior.
187  base::MessageLoop message_loop_;
188  // The mock bus.
189  scoped_refptr<dbus::MockBus> mock_bus_;
190
191 private:
192  // Checks the requested interface name and signal name.
193  // Used to implement the mock proxy.
194  void OnConnectToSignal(
195      const std::string& interface_name,
196      const std::string& signal_name,
197      const dbus::ObjectProxy::SignalCallback& signal_callback,
198      const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback);
199
200  // Checks the content of the method call and returns the response.
201  // Used to implement the mock proxy.
202  void OnCallMethod(
203      dbus::MethodCall* method_call,
204      int timeout_ms,
205      const dbus::ObjectProxy::ResponseCallback& response_callback);
206
207  // Checks the content of the method call and returns the response.
208  // Used to implement the mock proxy.
209  void OnCallMethodWithErrorCallback(
210      dbus::MethodCall* method_call,
211      int timeout_ms,
212      const dbus::ObjectProxy::ResponseCallback& response_callback,
213      const dbus::ObjectProxy::ErrorCallback& error_callback);
214
215  // The interface name.
216  const std::string interface_name_;
217  // The object path.
218  const dbus::ObjectPath object_path_;
219  // The mock object proxy.
220  scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
221  // The PropertyChanged signal handler given by the tested client.
222  dbus::ObjectProxy::SignalCallback property_changed_handler_;
223  // The name of the method which is expected to be called.
224  std::string expected_method_name_;
225  // The response which the mock object proxy returns.
226  dbus::Response* response_;
227  // A callback to intercept and check the method call arguments.
228  ArgumentCheckCallback argument_checker_;
229};
230
231}  // namespace chromeos
232
233#endif  // CHROMEOS_DBUS_SHILL_CLIENT_UNITTEST_BASE_H_
234