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