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.
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"
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;
33 namespace utils = extension_function_test_utils;
34 namespace api = extensions::api;
38 class BluetoothSocketApiTest : public ExtensionApiTest {
40 BluetoothSocketApiTest() {}
42 virtual void SetUpOnMainThread() OVERRIDE {
43 ExtensionApiTest::SetUpOnMainThread();
44 empty_extension_ = utils::CreateEmptyExtension();
48 virtual void CleanUpOnMainThread() OVERRIDE {
49 ExtensionApiTest::CleanUpOnMainThread();
52 void SetUpMockAdapter() {
53 // The browser will clean this up when it is torn down.
54 mock_adapter_ = new testing::StrictMock<MockBluetoothAdapter>();
55 BluetoothAdapterFactory::SetAdapterForTesting(mock_adapter_);
57 mock_device1_.reset(new testing::NiceMock<MockBluetoothDevice>(
58 mock_adapter_, 0, "d1", "11:12:13:14:15:16",
59 true /* paired */, false /* connected */));
60 mock_device2_.reset(new testing::NiceMock<MockBluetoothDevice>(
61 mock_adapter_, 0, "d2", "21:22:23:24:25:26",
62 true /* paired */, false /* connected */));
66 scoped_refptr<testing::StrictMock<MockBluetoothAdapter> > mock_adapter_;
67 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > mock_device1_;
68 scoped_ptr<testing::NiceMock<MockBluetoothDevice> > mock_device2_;
71 scoped_refptr<Extension> empty_extension_;
74 // testing::InvokeArgument<N> does not work with base::Callback, fortunately
75 // gmock makes it simple to create action templates that do for the various
76 // possible numbers of arguments.
77 ACTION_TEMPLATE(InvokeCallbackArgument,
78 HAS_1_TEMPLATE_PARAMS(int, k),
79 AND_0_VALUE_PARAMS()) {
80 ::std::tr1::get<k>(args).Run();
83 ACTION_TEMPLATE(InvokeCallbackArgument,
84 HAS_1_TEMPLATE_PARAMS(int, k),
85 AND_1_VALUE_PARAMS(p0)) {
86 ::std::tr1::get<k>(args).Run(p0);
89 ACTION_TEMPLATE(InvokeCallbackArgument,
90 HAS_1_TEMPLATE_PARAMS(int, k),
91 AND_2_VALUE_PARAMS(p0, p1)) {
92 ::std::tr1::get<k>(args).Run(p0, p1);
97 IN_PROC_BROWSER_TEST_F(BluetoothSocketApiTest, Connect) {
98 ResultCatcher catcher;
99 catcher.RestrictToProfile(browser()->profile());
101 // Return the right mock device object for the address used by the test,
102 // return NULL for the "Device not found" test.
103 EXPECT_CALL(*mock_adapter_, GetDevice(mock_device1_->GetAddress()))
104 .WillRepeatedly(testing::Return(mock_device1_.get()));
105 EXPECT_CALL(*mock_adapter_, GetDevice(std::string("aa:aa:aa:aa:aa:aa")))
106 .WillOnce(testing::Return(static_cast<BluetoothDevice*>(NULL)));
108 // Return a mock socket object as a successful result to the connect() call.
109 BluetoothUUID service_uuid("8e3ad063-db38-4289-aa8f-b30e4223cf40");
110 scoped_refptr<testing::StrictMock<MockBluetoothSocket> > mock_socket
111 = new testing::StrictMock<MockBluetoothSocket>();
112 EXPECT_CALL(*mock_device1_,
113 ConnectToService(service_uuid, testing::_, testing::_))
114 .WillOnce(InvokeCallbackArgument<1>(mock_socket));
116 // Since the socket is unpaused, expect a call to Receive() from the socket
117 // dispatcher. Since there is no data, this will not call its callback.
118 EXPECT_CALL(*mock_socket, Receive(testing::_, testing::_, testing::_));
120 // The test also cleans up by calling Disconnect and Close.
121 EXPECT_CALL(*mock_socket, Disconnect(testing::_))
122 .WillOnce(InvokeCallbackArgument<0>());
123 EXPECT_CALL(*mock_socket, Close());
126 ExtensionTestMessageListener listener("ready", true);
127 scoped_refptr<const Extension> extension(
128 LoadExtension(test_data_dir_.AppendASCII("bluetooth_socket/connect")));
129 ASSERT_TRUE(extension.get());
130 EXPECT_TRUE(listener.WaitUntilSatisfied());
132 listener.Reply("go");
133 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();