Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / bluetooth_socket / bluetooth_socket_apitest.cc
1 // Copyright 2014 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 <string>
6
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/browser/extensions/extension_apitest.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/test/base/ui_test_utils.h"
13 #include "device/bluetooth/bluetooth_adapter_factory.h"
14 #include "device/bluetooth/bluetooth_uuid.h"
15 #include "device/bluetooth/test/mock_bluetooth_adapter.h"
16 #include "device/bluetooth/test/mock_bluetooth_device.h"
17 #include "device/bluetooth/test/mock_bluetooth_socket.h"
18 #include "extensions/browser/api/bluetooth_socket/bluetooth_socket_api.h"
19 #include "extensions/common/test_util.h"
20 #include "extensions/test/extension_test_message_listener.h"
21 #include "extensions/test/result_catcher.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23
24 using device::BluetoothAdapter;
25 using device::BluetoothAdapterFactory;
26 using device::BluetoothDevice;
27 using device::BluetoothSocket;
28 using device::BluetoothUUID;
29 using device::MockBluetoothAdapter;
30 using device::MockBluetoothDevice;
31 using device::MockBluetoothSocket;
32 using extensions::Extension;
33 using extensions::ResultCatcher;
34
35 namespace api = extensions::core_api;
36
37 namespace {
38
39 class BluetoothSocketApiTest : public ExtensionApiTest {
40  public:
41   BluetoothSocketApiTest() {}
42
43   void SetUpOnMainThread() override {
44     ExtensionApiTest::SetUpOnMainThread();
45     empty_extension_ = extensions::test_util::CreateEmptyExtension();
46     SetUpMockAdapter();
47   }
48
49   void SetUpMockAdapter() {
50     // The browser will clean this up when it is torn down.
51     mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>();
52     BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);
53
54     mock_device1_.reset(
55         new testing::NiceMock<MockBluetoothDevice>(mock_adapter_.get(),
56                                                    0,
57                                                    "d1",
58                                                    "11:12:13:14:15:16",
59                                                    true /* paired */,
60                                                    false /* connected */));
61     mock_device2_.reset(
62         new testing::NiceMock<MockBluetoothDevice>(mock_adapter_.get(),
63                                                    0,
64                                                    "d2",
65                                                    "21:22:23:24:25:26",
66                                                    true /* paired */,
67                                                    false /* connected */));
68   }
69
70  protected:
71   scoped_refptr<testing::StrictMock<MockBluetoothAdapter> > mock_adapter_;
72   scoped_ptr<testing::NiceMock<MockBluetoothDevice> > mock_device1_;
73   scoped_ptr<testing::NiceMock<MockBluetoothDevice> > mock_device2_;
74
75  private:
76   scoped_refptr<Extension> empty_extension_;
77 };
78
79 // testing::InvokeArgument<N> does not work with base::Callback, fortunately
80 // gmock makes it simple to create action templates that do for the various
81 // possible numbers of arguments.
82 ACTION_TEMPLATE(InvokeCallbackArgument,
83                 HAS_1_TEMPLATE_PARAMS(int, k),
84                 AND_0_VALUE_PARAMS()) {
85   ::std::tr1::get<k>(args).Run();
86 }
87
88 ACTION_TEMPLATE(InvokeCallbackArgument,
89                 HAS_1_TEMPLATE_PARAMS(int, k),
90                 AND_1_VALUE_PARAMS(p0)) {
91   ::std::tr1::get<k>(args).Run(p0);
92 }
93
94 ACTION_TEMPLATE(InvokeCallbackArgument,
95                 HAS_1_TEMPLATE_PARAMS(int, k),
96                 AND_2_VALUE_PARAMS(p0, p1)) {
97   ::std::tr1::get<k>(args).Run(p0, p1);
98 }
99
100 }  // namespace
101
102 IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, Connect) {
103   ResultCatcher catcher;
104   catcher.RestrictToBrowserContext(browser()->profile());
105
106   // Return the right mock device object for the address used by the test,
107   // return NULL for the "Device not found" test.
108   EXPECT_CALL(*mock_adapter_.get(), GetDevice(mock_device1_->GetAddress()))
109       .WillRepeatedly(testing::Return(mock_device1_.get()));
110   EXPECT_CALL(*mock_adapter_.get(), GetDevice(std::string("aa:aa:aa:aa:aa:aa")))
111       .WillOnce(testing::Return(static_cast<BluetoothDevice*>(NULL)));
112
113   // Return a mock socket object as a successful result to the connect() call.
114   BluetoothUUID service_uuid("8e3ad063-db38-4289-aa8f-b30e4223cf40");
115   scoped_refptr<testing::StrictMock<MockBluetoothSocket> > mock_socket
116       = new testing::StrictMock<MockBluetoothSocket>();
117   EXPECT_CALL(*mock_device1_,
118               ConnectToService(service_uuid, testing::_, testing::_))
119       .WillOnce(InvokeCallbackArgument<1>(mock_socket));
120
121   // Since the socket is unpaused, expect a call to Receive() from the socket
122   // dispatcher. Since there is no data, this will not call its callback.
123   EXPECT_CALL(*mock_socket.get(), Receive(testing::_, testing::_, testing::_));
124
125   // The test also cleans up by calling Disconnect and Close.
126   EXPECT_CALL(*mock_socket.get(), Disconnect(testing::_))
127       .WillOnce(InvokeCallbackArgument<0>());
128   EXPECT_CALL(*mock_socket.get(), Close());
129
130   // Run the test.
131   ExtensionTestMessageListener listener("ready", true);
132   scoped_refptr<const Extension> extension(
133       LoadExtension(test_data_dir_.AppendASCII("bluetooth_socket/connect")));
134   ASSERT_TRUE(extension.get());
135   EXPECT_TRUE(listener.WaitUntilSatisfied());
136
137   listener.Reply("go");
138   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
139 }
140
141 #if defined(_LIBCPP_VERSION)
142 // This test fails in libc++ builds, see http://crbug.com/392205.
143 #define MAYBE_Listen DISABLED_Listen
144 #else
145 #define MAYBE_Listen Listen
146 #endif
147 IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, MAYBE_Listen) {
148   ResultCatcher catcher;
149   catcher.RestrictToBrowserContext(browser()->profile());
150
151   // Return a mock socket object as a successful result to the create service
152   // call.
153   BluetoothUUID service_uuid("2de497f9-ab28-49db-b6d2-066ea69f1737");
154   scoped_refptr<testing::StrictMock<MockBluetoothSocket> > mock_server_socket
155       = new testing::StrictMock<MockBluetoothSocket>();
156   BluetoothAdapter::ServiceOptions service_options;
157   service_options.name.reset(new std::string("MyServiceName"));
158   EXPECT_CALL(
159       *mock_adapter_.get(),
160       CreateRfcommService(
161           service_uuid,
162           testing::Field(&BluetoothAdapter::ServiceOptions::name,
163                          testing::Pointee(testing::Eq("MyServiceName"))),
164           testing::_,
165           testing::_)).WillOnce(InvokeCallbackArgument<2>(mock_server_socket));
166
167   // Since the socket is unpaused, expect a call to Accept() from the socket
168   // dispatcher. We'll immediately send back another mock socket to represent
169   // the client API. Further calls will return no data and behave as if
170   // pending.
171   scoped_refptr<testing::StrictMock<MockBluetoothSocket> > mock_client_socket
172       = new testing::StrictMock<MockBluetoothSocket>();
173   EXPECT_CALL(*mock_server_socket.get(), Accept(testing::_, testing::_))
174       .Times(2)
175       .WillOnce(
176            InvokeCallbackArgument<0>(mock_device1_.get(), mock_client_socket))
177       .WillOnce(testing::Return());
178
179   // Run the test, it sends a ready signal once it's ready for us to dispatch
180   // a client connection to it.
181   ExtensionTestMessageListener socket_listening("ready", true);
182   scoped_refptr<const Extension> extension(
183       LoadExtension(test_data_dir_.AppendASCII("bluetooth_socket/listen")));
184   ASSERT_TRUE(extension.get());
185   EXPECT_TRUE(socket_listening.WaitUntilSatisfied());
186
187   // Connection events are dispatched using a couple of PostTask to the UI
188   // thread. Waiting until idle ensures the event is dispatched to the
189   // receiver(s).
190   base::RunLoop().RunUntilIdle();
191   ExtensionTestMessageListener listener("ready", true);
192   socket_listening.Reply("go");
193
194   // Second stage of tests checks for error conditions, and will clean up
195   // the existing server and client sockets.
196   EXPECT_CALL(*mock_server_socket.get(), Disconnect(testing::_))
197       .WillOnce(InvokeCallbackArgument<0>());
198   EXPECT_CALL(*mock_server_socket.get(), Close());
199
200   EXPECT_CALL(*mock_client_socket.get(), Disconnect(testing::_))
201       .WillOnce(InvokeCallbackArgument<0>());
202   EXPECT_CALL(*mock_client_socket.get(), Close());
203
204   EXPECT_TRUE(listener.WaitUntilSatisfied());
205   listener.Reply("go");
206   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
207 }
208
209 IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, PermissionDenied) {
210   ResultCatcher catcher;
211   catcher.RestrictToBrowserContext(browser()->profile());
212
213   // Run the test.
214   scoped_refptr<const Extension> extension(
215       LoadExtension(test_data_dir_.AppendASCII(
216           "bluetooth_socket/permission_denied")));
217   ASSERT_TRUE(extension.get());
218
219   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
220 }