1// Copyright 2013 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 "chrome/browser/content_settings/permission_queue_controller.h"
6
7#include "base/synchronization/waitable_event.h"
8#include "chrome/browser/chrome_notification_types.h"
9#include "chrome/browser/infobars/infobar_service.h"
10#include "chrome/test/base/chrome_render_view_host_test_harness.h"
11#include "chrome/test/base/testing_profile.h"
12#include "components/content_settings/core/common/content_settings_types.h"
13#include "components/content_settings/core/common/permission_request_id.h"
14#include "content/public/browser/web_contents.h"
15#include "content/public/test/mock_render_process_host.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18
19// PermissionQueueControllerTests ---------------------------------------------
20
21class PermissionQueueControllerTests : public ChromeRenderViewHostTestHarness {
22 protected:
23  PermissionQueueControllerTests() {}
24  virtual ~PermissionQueueControllerTests() {}
25
26  PermissionRequestID RequestID(int bridge_id) {
27    return PermissionRequestID(
28        web_contents()->GetRenderProcessHost()->GetID(),
29        web_contents()->GetRenderViewHost()->GetRoutingID(),
30        bridge_id,
31        GURL());
32  }
33
34 private:
35  // ChromeRenderViewHostTestHarness:
36  virtual void SetUp() OVERRIDE {
37    ChromeRenderViewHostTestHarness::SetUp();
38    InfoBarService::CreateForWebContents(web_contents());
39  }
40
41  DISALLOW_COPY_AND_ASSIGN(PermissionQueueControllerTests);
42};
43
44
45// ObservationCountingQueueController -----------------------------------------
46
47class ObservationCountingQueueController : public PermissionQueueController {
48 public:
49  explicit ObservationCountingQueueController(Profile* profile);
50  virtual ~ObservationCountingQueueController();
51
52  int call_count() const { return call_count_; }
53
54 private:
55  int call_count_;
56
57  // PermissionQueueController:
58  virtual void Observe(int type,
59                       const content::NotificationSource& source,
60                       const content::NotificationDetails& details) OVERRIDE;
61
62  DISALLOW_COPY_AND_ASSIGN(ObservationCountingQueueController);
63};
64
65ObservationCountingQueueController::ObservationCountingQueueController(
66    Profile* profile)
67    : PermissionQueueController(profile, CONTENT_SETTINGS_TYPE_GEOLOCATION),
68      call_count_(0) {
69}
70
71ObservationCountingQueueController::~ObservationCountingQueueController() {
72}
73
74void ObservationCountingQueueController::Observe(
75    int type,
76    const content::NotificationSource& source,
77    const content::NotificationDetails& details) {
78  DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
79  ++call_count_;
80  PermissionQueueController::Observe(type, source, details);
81}
82
83
84// Actual tests ---------------------------------------------------------------
85
86TEST_F(PermissionQueueControllerTests, OneObservationPerInfoBarCancelled) {
87  // When an infobar is cancelled, the infobar helper sends a notification to
88  // the controller. If the controller has another infobar queued, it should
89  // maintain its registration for notifications with the helper, but on the
90  // last infobar cancellation it should unregister for notifications.
91  //
92  // What we don't want is for the controller to unregister and then re-register
93  // for notifications, which can lead to getting notified multiple times.  This
94  // test checks that in the case where the controller should remain registered
95  // for notifications, it gets notified exactly once."
96  ObservationCountingQueueController queue_controller(profile());
97  GURL url("http://www.example.com/geolocation");
98  base::Callback<void(bool)> callback;
99  queue_controller.CreateInfoBarRequest(
100      RequestID(0), url, url, callback);
101  queue_controller.CreateInfoBarRequest(
102      RequestID(1), url, url, callback);
103  queue_controller.CancelInfoBarRequest(RequestID(0));
104  EXPECT_EQ(1, queue_controller.call_count());
105};
106
107TEST_F(PermissionQueueControllerTests, FailOnBadPattern) {
108  ObservationCountingQueueController queue_controller(profile());
109  GURL url("chrome://settings");
110  base::Callback<void(bool)> callback;
111  queue_controller.CreateInfoBarRequest(
112      RequestID(0), url, url, callback);
113  queue_controller.CancelInfoBarRequest(RequestID(0));
114  EXPECT_EQ(0, queue_controller.call_count());
115};
116