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#include <string>
6
7#include "base/memory/ref_counted.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/message_loop/message_loop.h"
10#include "base/run_loop.h"
11#include "content/public/browser/notification_service.h"
12#include "content/public/test/test_browser_context.h"
13#include "content/public/test/test_browser_thread.h"
14#include "device/bluetooth/bluetooth_uuid.h"
15#include "device/bluetooth/test/mock_bluetooth_adapter.h"
16#include "extensions/browser/api/bluetooth/bluetooth_event_router.h"
17#include "extensions/browser/extension_registry.h"
18#include "extensions/browser/extensions_test.h"
19#include "extensions/common/api/bluetooth.h"
20#include "extensions/common/extension_builder.h"
21#include "testing/gmock/include/gmock/gmock.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24namespace {
25
26const char kTestExtensionId[] = "test extension id";
27const device::BluetoothUUID kAudioProfileUuid("1234");
28const device::BluetoothUUID kHealthProfileUuid("4321");
29
30}  // namespace
31
32namespace extensions {
33
34namespace bluetooth = core_api::bluetooth;
35
36class BluetoothEventRouterTest : public ExtensionsTest {
37 public:
38  BluetoothEventRouterTest()
39      : ui_thread_(content::BrowserThread::UI, &message_loop_),
40        mock_adapter_(new testing::StrictMock<device::MockBluetoothAdapter>()),
41        notification_service_(content::NotificationService::Create()),
42        router_(new BluetoothEventRouter(browser_context())) {
43    router_->SetAdapterForTest(mock_adapter_);
44  }
45
46  virtual void TearDown() OVERRIDE {
47    // It's important to destroy the router before the browser context keyed
48    // services so it removes itself as an ExtensionRegistry observer.
49    router_.reset(NULL);
50    ExtensionsTest::TearDown();
51  }
52
53 protected:
54  base::MessageLoopForUI message_loop_;
55  // Note: |ui_thread_| must be declared before |router_|.
56  content::TestBrowserThread ui_thread_;
57  testing::StrictMock<device::MockBluetoothAdapter>* mock_adapter_;
58  scoped_ptr<content::NotificationService> notification_service_;
59  scoped_ptr<BluetoothEventRouter> router_;
60};
61
62TEST_F(BluetoothEventRouterTest, BluetoothEventListener) {
63  router_->OnListenerAdded();
64  EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)).Times(1);
65  router_->OnListenerRemoved();
66}
67
68TEST_F(BluetoothEventRouterTest, MultipleBluetoothEventListeners) {
69  router_->OnListenerAdded();
70  router_->OnListenerAdded();
71  router_->OnListenerAdded();
72  router_->OnListenerRemoved();
73  router_->OnListenerRemoved();
74  EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)).Times(1);
75  router_->OnListenerRemoved();
76}
77
78TEST_F(BluetoothEventRouterTest, UnloadExtension) {
79  scoped_refptr<const Extension> extension =
80      ExtensionBuilder()
81          .SetManifest(DictionaryBuilder()
82              .Set("name", "BT event router test")
83              .Set("version", "1.0")
84              .Set("manifest_version", 2))
85          .SetID(kTestExtensionId)
86          .Build();
87
88  ExtensionRegistry::Get(browser_context())->TriggerOnUnloaded(
89      extension.get(), UnloadedExtensionInfo::REASON_DISABLE);
90
91  EXPECT_CALL(*mock_adapter_, RemoveObserver(testing::_)).Times(1);
92}
93
94}  // namespace extensions
95