Home | History | Annotate | Download | only in content_settings
      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 
     21 class 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 
     47 class 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 
     65 ObservationCountingQueueController::ObservationCountingQueueController(
     66     Profile* profile)
     67     : PermissionQueueController(profile, CONTENT_SETTINGS_TYPE_GEOLOCATION),
     68       call_count_(0) {
     69 }
     70 
     71 ObservationCountingQueueController::~ObservationCountingQueueController() {
     72 }
     73 
     74 void 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 
     86 TEST_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 
    107 TEST_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