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