[M120 Migration][VD] Fix url crash in RequestCertificateConfirm
[platform/framework/web/chromium-efl.git] / dbus / mock_unittest.cc
1 // Copyright 2012 The Chromium Authors
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 <memory>
6
7 #include "base/functional/bind.h"
8 #include "base/logging.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/run_loop.h"
11 #include "base/task/single_thread_task_runner.h"
12 #include "base/test/task_environment.h"
13 #include "dbus/error.h"
14 #include "dbus/message.h"
15 #include "dbus/mock_bus.h"
16 #include "dbus/mock_exported_object.h"
17 #include "dbus/mock_object_proxy.h"
18 #include "dbus/object_path.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 using ::testing::_;
23 using ::testing::Invoke;
24 using ::testing::Return;
25 using ::testing::Unused;
26
27 namespace dbus {
28
29 class MockTest : public testing::Test {
30  public:
31   MockTest() = default;
32
33   void SetUp() override {
34     // Create a mock bus.
35     Bus::Options options;
36     options.bus_type = Bus::SYSTEM;
37     mock_bus_ = new MockBus(options);
38
39     // Create a mock proxy.
40     mock_proxy_ = new MockObjectProxy(
41         mock_bus_.get(),
42         "org.chromium.TestService",
43         ObjectPath("/org/chromium/TestObject"));
44
45     // Set an expectation so mock_proxy's CallMethodAndBlock() will use
46     // CreateMockProxyResponse() to return responses.
47     EXPECT_CALL(*mock_proxy_.get(), CallMethodAndBlock(_, _))
48         .WillRepeatedly(Invoke(this, &MockTest::CreateMockProxyResponse));
49
50     // Set an expectation so mock_proxy's CallMethod() will use
51     // HandleMockProxyResponseWithMessageLoop() to return responses.
52     EXPECT_CALL(*mock_proxy_.get(), DoCallMethod(_, _, _))
53         .WillRepeatedly(
54             Invoke(this, &MockTest::HandleMockProxyResponseWithMessageLoop));
55
56     // Set an expectation so mock_bus's GetObjectProxy() for the given
57     // service name and the object path will return mock_proxy_.
58     EXPECT_CALL(*mock_bus_.get(),
59                 GetObjectProxy("org.chromium.TestService",
60                                ObjectPath("/org/chromium/TestObject")))
61         .WillOnce(Return(mock_proxy_.get()));
62
63     // ShutdownAndBlock() will be called in TearDown().
64     EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
65   }
66
67   void TearDown() override { mock_bus_->ShutdownAndBlock(); }
68
69   // Called when the response is received.
70   void OnResponse(Response* response) {
71     // |response| will be deleted on exit of the function. Copy the
72     // payload to |response_string_|.
73     if (response) {
74       MessageReader reader(response);
75       ASSERT_TRUE(reader.PopString(&response_string_));
76     }
77     run_loop_->Quit();
78   }
79
80  protected:
81   std::string response_string_;
82   base::test::SingleThreadTaskEnvironment task_environment_;
83   std::unique_ptr<base::RunLoop> run_loop_;
84   scoped_refptr<MockBus> mock_bus_;
85   scoped_refptr<MockObjectProxy> mock_proxy_;
86
87  private:
88   // Returns a response for the given method call. Used to implement
89   // CallMethodAndBlock() for |mock_proxy_|.
90   base::expected<std::unique_ptr<Response>, Error> CreateMockProxyResponse(
91       MethodCall* method_call,
92       int timeout_ms) {
93     if (method_call->GetInterface() == "org.chromium.TestInterface" &&
94         method_call->GetMember() == "Echo") {
95       MessageReader reader(method_call);
96       std::string text_message;
97       if (reader.PopString(&text_message)) {
98         std::unique_ptr<Response> response = Response::CreateEmpty();
99         MessageWriter writer(response.get());
100         writer.AppendString(text_message);
101         return base::ok(std::move(response));
102       }
103
104       LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
105       return base::unexpected(Error());
106     }
107
108     return base::unexpected(Error(DBUS_ERROR_NOT_SUPPORTED, "Not implemented"));
109   }
110
111   // Creates a response and posts the given response callback with the
112   // response. Used to implement for |mock_proxy_|.
113   void HandleMockProxyResponseWithMessageLoop(
114       MethodCall* method_call,
115       int timeout_ms,
116       ObjectProxy::ResponseCallback* response_callback) {
117     std::unique_ptr<Response> response =
118         CreateMockProxyResponse(method_call, timeout_ms).value_or(nullptr);
119     task_environment_.GetMainThreadTaskRunner()->PostTask(
120         FROM_HERE,
121         base::BindOnce(&MockTest::RunResponseCallback, base::Unretained(this),
122                        std::move(*response_callback), std::move(response)));
123   }
124
125   // Runs the given response callback with the given response.
126   void RunResponseCallback(
127       ObjectProxy::ResponseCallback response_callback,
128       std::unique_ptr<Response> response) {
129     std::move(response_callback).Run(response.get());
130   }
131 };
132
133 // This test demonstrates how to mock a synchronous method call using the
134 // mock classes.
135 TEST_F(MockTest, CallMethodAndBlock) {
136   const char kHello[] = "Hello";
137   // Get an object proxy from the mock bus.
138   ObjectProxy* proxy = mock_bus_->GetObjectProxy(
139       "org.chromium.TestService",
140       ObjectPath("/org/chromium/TestObject"));
141
142   // Create a method call.
143   MethodCall method_call("org.chromium.TestInterface", "Echo");
144   MessageWriter writer(&method_call);
145   writer.AppendString(kHello);
146
147   // Call the method.
148   auto result =
149       proxy->CallMethodAndBlock(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT);
150
151   // Check the response.
152   ASSERT_TRUE(result.has_value());
153   MessageReader reader(result->get());
154   std::string text_message;
155   ASSERT_TRUE(reader.PopString(&text_message));
156   // The text message should be echo'ed back.
157   EXPECT_EQ(kHello, text_message);
158 }
159
160 TEST_F(MockTest, CallMethodAndBlockOnError) {
161   // Get an object proxy from the mock bus.
162   ObjectProxy* proxy = mock_bus_->GetObjectProxy(
163       "org.chromium.TestService",
164       ObjectPath("/org/chromium/TestObject"));
165
166   // Create a method call.
167   MethodCall method_call("org.chromium.TestInterface", "MissingMethod");
168
169   // Call the method.
170   auto result =
171       proxy->CallMethodAndBlock(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT);
172
173   // Check the response.
174   ASSERT_FALSE(result.has_value());
175   const Error& error = result.error();
176   EXPECT_EQ(DBUS_ERROR_NOT_SUPPORTED, error.name());
177   EXPECT_EQ("Not implemented", error.message());
178 }
179
180 // This test demonstrates how to mock an asynchronous method call using the
181 // mock classes.
182 TEST_F(MockTest, CallMethod) {
183   const char kHello[] = "hello";
184
185   // Get an object proxy from the mock bus.
186   ObjectProxy* proxy = mock_bus_->GetObjectProxy(
187       "org.chromium.TestService",
188       ObjectPath("/org/chromium/TestObject"));
189
190   // Create a method call.
191   MethodCall method_call("org.chromium.TestInterface", "Echo");
192   MessageWriter writer(&method_call);
193   writer.AppendString(kHello);
194
195   // Call the method.
196   run_loop_ = std::make_unique<base::RunLoop>();
197   proxy->CallMethod(
198       &method_call, ObjectProxy::TIMEOUT_USE_DEFAULT,
199       base::BindOnce(&MockTest::OnResponse, base::Unretained(this)));
200   // Run the message loop to let OnResponse be called.
201   run_loop_->Run();
202
203   EXPECT_EQ(kHello, response_string_);
204 }
205
206 }  // namespace dbus