Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2006-2008 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/download/download_request_limiter.h"
      6 #include "chrome/test/testing_profile.h"
      7 #include "content/browser/browser_thread.h"
      8 #include "content/browser/renderer_host/test_render_view_host.h"
      9 #include "content/browser/tab_contents/navigation_controller.h"
     10 #include "testing/gtest/include/gtest/gtest.h"
     11 
     12 class DownloadRequestLimiterTest
     13     : public RenderViewHostTestHarness,
     14       public DownloadRequestLimiter::Callback {
     15  public:
     16   DownloadRequestLimiterTest() : io_thread_(BrowserThread::IO, &message_loop_) {
     17   }
     18 
     19   virtual void SetUp() {
     20     RenderViewHostTestHarness::SetUp();
     21 
     22     allow_download_ = true;
     23     ask_allow_count_ = cancel_count_ = continue_count_ = 0;
     24 
     25     download_request_limiter_ = new DownloadRequestLimiter();
     26     test_delegate_.reset(new DownloadRequestLimiterTestDelegate(this));
     27     DownloadRequestLimiter::SetTestingDelegate(test_delegate_.get());
     28   }
     29 
     30   virtual void TearDown() {
     31     DownloadRequestLimiter::SetTestingDelegate(NULL);
     32 
     33     RenderViewHostTestHarness::TearDown();
     34   }
     35 
     36   virtual void ContinueDownload() {
     37     continue_count_++;
     38   }
     39   virtual void CancelDownload() {
     40     cancel_count_++;
     41   }
     42 
     43   void CanDownload() {
     44     download_request_limiter_->CanDownloadImpl(
     45         controller().tab_contents(), -1, this);
     46     message_loop_.RunAllPending();
     47   }
     48 
     49   bool ShouldAllowDownload() {
     50     ask_allow_count_++;
     51     return allow_download_;
     52   }
     53 
     54  protected:
     55   class DownloadRequestLimiterTestDelegate
     56       : public DownloadRequestLimiter::TestingDelegate {
     57    public:
     58     explicit DownloadRequestLimiterTestDelegate(
     59         DownloadRequestLimiterTest* test)
     60         : test_(test) { }
     61 
     62     virtual bool ShouldAllowDownload() {
     63       return test_->ShouldAllowDownload();
     64     }
     65 
     66    private:
     67     DownloadRequestLimiterTest* test_;
     68   };
     69 
     70   scoped_ptr<DownloadRequestLimiterTestDelegate> test_delegate_;
     71   scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
     72 
     73   // Number of times ContinueDownload was invoked.
     74   int continue_count_;
     75 
     76   // Number of times CancelDownload was invoked.
     77   int cancel_count_;
     78 
     79   // Whether the download should be allowed.
     80   bool allow_download_;
     81 
     82   // Number of times ShouldAllowDownload was invoked.
     83   int ask_allow_count_;
     84 
     85   BrowserThread io_thread_;
     86 };
     87 
     88 TEST_F(DownloadRequestLimiterTest, Allow) {
     89   // All tabs should initially start at ALLOW_ONE_DOWNLOAD.
     90   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
     91             download_request_limiter_->GetDownloadStatus(
     92                 controller().tab_contents()));
     93 
     94   // Ask if the tab can do a download. This moves to PROMPT_BEFORE_DOWNLOAD.
     95   CanDownload();
     96   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
     97             download_request_limiter_->GetDownloadStatus(
     98                 controller().tab_contents()));
     99   // We should have been told we can download.
    100   ASSERT_EQ(1, continue_count_);
    101   ASSERT_EQ(0, cancel_count_);
    102   ASSERT_EQ(0, ask_allow_count_);
    103   continue_count_ = 0;
    104 
    105   // Ask again. This triggers asking the delegate for allow/disallow.
    106   allow_download_ = true;
    107   CanDownload();
    108   // This should ask us if the download is allowed.
    109   ASSERT_EQ(1, ask_allow_count_);
    110   ask_allow_count_ = 0;
    111   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
    112             download_request_limiter_->GetDownloadStatus(
    113                 controller().tab_contents()));
    114   // We should have been told we can download.
    115   ASSERT_EQ(1, continue_count_);
    116   ASSERT_EQ(0, cancel_count_);
    117   continue_count_ = 0;
    118 
    119   // Ask again and make sure continue is invoked.
    120   CanDownload();
    121   // The state is at allow_all, which means the delegate shouldn't be asked.
    122   ASSERT_EQ(0, ask_allow_count_);
    123   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
    124             download_request_limiter_->GetDownloadStatus(
    125                 controller().tab_contents()));
    126   // We should have been told we can download.
    127   ASSERT_EQ(1, continue_count_);
    128   ASSERT_EQ(0, cancel_count_);
    129   continue_count_ = 0;
    130 }
    131 
    132 TEST_F(DownloadRequestLimiterTest, ResetOnNavigation) {
    133   NavigateAndCommit(GURL("http://foo.com/bar"));
    134 
    135   // Do two downloads, allowing the second so that we end up with allow all.
    136   CanDownload();
    137   allow_download_ = true;
    138   CanDownload();
    139   ask_allow_count_ = continue_count_ = cancel_count_ = 0;
    140   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
    141             download_request_limiter_->GetDownloadStatus(
    142                 controller().tab_contents()));
    143 
    144   // Navigate to a new URL with the same host, which shouldn't reset the allow
    145   // all state.
    146   NavigateAndCommit(GURL("http://foo.com/bar2"));
    147   CanDownload();
    148   ASSERT_EQ(1, continue_count_);
    149   ASSERT_EQ(0, cancel_count_);
    150   ASSERT_EQ(0, ask_allow_count_);
    151   ask_allow_count_ = continue_count_ = cancel_count_ = 0;
    152   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
    153             download_request_limiter_->GetDownloadStatus(
    154                 controller().tab_contents()));
    155 
    156   // Do a user gesture, because we're at allow all, this shouldn't change the
    157   // state.
    158   download_request_limiter_->OnUserGesture(controller().tab_contents());
    159   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
    160             download_request_limiter_->GetDownloadStatus(
    161                 controller().tab_contents()));
    162 
    163   // Navigate to a completely different host, which should reset the state.
    164   NavigateAndCommit(GURL("http://fooey.com"));
    165   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
    166             download_request_limiter_->GetDownloadStatus(
    167                 controller().tab_contents()));
    168 }
    169 
    170 TEST_F(DownloadRequestLimiterTest, ResetOnUserGesture) {
    171   NavigateAndCommit(GURL("http://foo.com/bar"));
    172 
    173   // Do one download, which should change to prompt before download.
    174   CanDownload();
    175   ask_allow_count_ = continue_count_ = cancel_count_ = 0;
    176   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
    177             download_request_limiter_->GetDownloadStatus(
    178                 controller().tab_contents()));
    179 
    180   // Do a user gesture, which should reset back to allow one.
    181   download_request_limiter_->OnUserGesture(controller().tab_contents());
    182   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
    183             download_request_limiter_->GetDownloadStatus(
    184                 controller().tab_contents()));
    185 
    186   // Ask twice, which triggers calling the delegate. Don't allow the download
    187   // so that we end up with not allowed.
    188   allow_download_ = false;
    189   CanDownload();
    190   CanDownload();
    191   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
    192             download_request_limiter_->GetDownloadStatus(
    193                 controller().tab_contents()));
    194 
    195   // A user gesture now should NOT change the state.
    196   download_request_limiter_->OnUserGesture(controller().tab_contents());
    197   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
    198             download_request_limiter_->GetDownloadStatus(
    199                 controller().tab_contents()));
    200   // And make sure we really can't download.
    201   ask_allow_count_ = continue_count_ = cancel_count_ = 0;
    202   CanDownload();
    203   ASSERT_EQ(0, ask_allow_count_);
    204   ASSERT_EQ(0, continue_count_);
    205   ASSERT_EQ(1, cancel_count_);
    206   // And the state shouldn't have changed.
    207   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
    208             download_request_limiter_->GetDownloadStatus(
    209                 controller().tab_contents()));
    210 }
    211