Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / download / download_request_limiter_unittest.cc
blob998da34b079bca1413c0ff667b3bd4ae56f1db8b
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.
5 #include "chrome/browser/download/download_request_limiter.h"
7 #include "base/bind.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/content_settings/host_content_settings_map.h"
10 #include "chrome/browser/download/download_request_infobar_delegate.h"
11 #include "chrome/browser/infobars/infobar_service.h"
12 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
13 #include "chrome/test/base/testing_profile.h"
14 #include "content/public/browser/navigation_controller.h"
15 #include "content/public/browser/web_contents.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 using content::WebContents;
20 class DownloadRequestLimiterTest : public ChromeRenderViewHostTestHarness {
21 public:
22 enum TestingAction {
23 ACCEPT,
24 CANCEL,
25 WAIT
28 virtual void SetUp() {
29 ChromeRenderViewHostTestHarness::SetUp();
30 InfoBarService::CreateForWebContents(web_contents());
31 testing_action_ = ACCEPT;
32 ask_allow_count_ = cancel_count_ = continue_count_ = 0;
33 download_request_limiter_ = new DownloadRequestLimiter();
34 fake_create_callback_ = base::Bind(
35 &DownloadRequestLimiterTest::FakeCreate, base::Unretained(this));
36 DownloadRequestInfoBarDelegate::SetCallbackForTesting(
37 &fake_create_callback_);
38 content_settings_ = new HostContentSettingsMap(profile_.GetPrefs(), false);
39 DownloadRequestLimiter::SetContentSettingsForTesting(
40 content_settings_.get());
43 void FakeCreate(
44 InfoBarService* infobar_service,
45 base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host) {
46 ask_allow_count_++;
47 switch (testing_action_) {
48 case ACCEPT:
49 host->Accept();
50 break;
51 case CANCEL:
52 host->Cancel();
53 break;
54 case WAIT:
55 break;
59 virtual void TearDown() {
60 content_settings_->ShutdownOnUIThread();
61 content_settings_ = NULL;
62 UnsetDelegate();
63 ChromeRenderViewHostTestHarness::TearDown();
66 virtual void UnsetDelegate() {
67 DownloadRequestInfoBarDelegate::SetCallbackForTesting(NULL);
70 void CanDownload() {
71 CanDownloadFor(web_contents());
74 void CanDownloadFor(WebContents* web_contents) {
75 download_request_limiter_->CanDownloadImpl(
76 web_contents,
77 -1, // request id
78 "GET", // request method
79 base::Bind(&DownloadRequestLimiterTest::ContinueDownload,
80 base::Unretained(this)));
81 base::RunLoop().RunUntilIdle();
84 void OnUserGesture() {
85 OnUserGestureFor(web_contents());
88 void OnUserGestureFor(WebContents* web_contents) {
89 DownloadRequestLimiter::TabDownloadState* state =
90 download_request_limiter_->GetDownloadState(web_contents, NULL, false);
91 if (state)
92 state->DidGetUserGesture();
95 void AboutToNavigateRenderView() {
96 DownloadRequestLimiter::TabDownloadState* state =
97 download_request_limiter_->GetDownloadState(
98 web_contents(), NULL, false);
99 state->AboutToNavigateRenderView(NULL);
102 void ExpectAndResetCounts(
103 int expect_continues,
104 int expect_cancels,
105 int expect_asks,
106 int line) {
107 EXPECT_EQ(expect_continues, continue_count_) << "line " << line;
108 EXPECT_EQ(expect_cancels, cancel_count_) << "line " << line;
109 EXPECT_EQ(expect_asks, ask_allow_count_) << "line " << line;
110 continue_count_ = cancel_count_ = ask_allow_count_ = 0;
113 protected:
114 void ContinueDownload(bool allow) {
115 if (allow) {
116 continue_count_++;
117 } else {
118 cancel_count_++;
122 void SetHostContentSetting(WebContents* contents, ContentSetting setting) {
123 content_settings_->SetContentSetting(
124 ContentSettingsPattern::FromURL(contents->GetURL()),
125 ContentSettingsPattern::Wildcard(),
126 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
127 std::string(),
128 setting);
131 scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
133 // The action that FakeCreate() should take.
134 TestingAction testing_action_;
136 // Number of times ContinueDownload was invoked.
137 int continue_count_;
139 // Number of times CancelDownload was invoked.
140 int cancel_count_;
142 // Number of times ShouldAllowDownload was invoked.
143 int ask_allow_count_;
145 scoped_refptr<HostContentSettingsMap> content_settings_;
147 private:
148 DownloadRequestInfoBarDelegate::FakeCreateCallback fake_create_callback_;
149 TestingProfile profile_;
152 TEST_F(DownloadRequestLimiterTest,
153 DownloadRequestLimiter_Allow) {
154 // All tabs should initially start at ALLOW_ONE_DOWNLOAD.
155 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
156 download_request_limiter_->GetDownloadStatus(web_contents()));
158 // Ask if the tab can do a download. This moves to PROMPT_BEFORE_DOWNLOAD.
159 CanDownload();
160 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
161 download_request_limiter_->GetDownloadStatus(web_contents()));
162 // We should have been told we can download.
163 ExpectAndResetCounts(1, 0, 0, __LINE__);
165 // Ask again. This triggers asking the delegate for allow/disallow.
166 testing_action_ = ACCEPT;
167 CanDownload();
168 // This should ask us if the download is allowed.
169 // We should have been told we can download.
170 ExpectAndResetCounts(1, 0, 1, __LINE__);
171 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
172 download_request_limiter_->GetDownloadStatus(web_contents()));
174 // Ask again and make sure continue is invoked.
175 CanDownload();
176 // The state is at allow_all, which means the delegate shouldn't be asked.
177 // We should have been told we can download.
178 ExpectAndResetCounts(1, 0, 0, __LINE__);
179 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
180 download_request_limiter_->GetDownloadStatus(web_contents()));
183 TEST_F(DownloadRequestLimiterTest,
184 DownloadRequestLimiter_ResetOnNavigation) {
185 NavigateAndCommit(GURL("http://foo.com/bar"));
187 // Do two downloads, allowing the second so that we end up with allow all.
188 CanDownload();
189 ExpectAndResetCounts(1, 0, 0, __LINE__);
190 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
191 download_request_limiter_->GetDownloadStatus(web_contents()));
193 testing_action_ = ACCEPT;
194 CanDownload();
195 ExpectAndResetCounts(1, 0, 1, __LINE__);
196 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
197 download_request_limiter_->GetDownloadStatus(web_contents()));
199 // Navigate to a new URL with the same host, which shouldn't reset the allow
200 // all state.
201 NavigateAndCommit(GURL("http://foo.com/bar2"));
202 CanDownload();
203 ExpectAndResetCounts(1, 0, 0, __LINE__);
204 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
205 download_request_limiter_->GetDownloadStatus(web_contents()));
207 // Do a user gesture, because we're at allow all, this shouldn't change the
208 // state.
209 OnUserGesture();
210 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
211 download_request_limiter_->GetDownloadStatus(web_contents()));
213 // Navigate to a completely different host, which should reset the state.
214 NavigateAndCommit(GURL("http://fooey.com"));
215 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
216 download_request_limiter_->GetDownloadStatus(web_contents()));
218 // Do two downloads, allowing the second so that we end up with allow all.
219 CanDownload();
220 ExpectAndResetCounts(1, 0, 0, __LINE__);
221 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
222 download_request_limiter_->GetDownloadStatus(web_contents()));
224 testing_action_ = CANCEL;
225 CanDownload();
226 ExpectAndResetCounts(0, 1, 1, __LINE__);
227 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
228 download_request_limiter_->GetDownloadStatus(web_contents()));
230 // Navigate to a new URL with the same host, which shouldn't reset the allow
231 // all state.
232 NavigateAndCommit(GURL("http://fooey.com/bar2"));
233 CanDownload();
234 ExpectAndResetCounts(0, 1, 0, __LINE__);
235 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
236 download_request_limiter_->GetDownloadStatus(web_contents()));
239 TEST_F(DownloadRequestLimiterTest,
240 DownloadRequestLimiter_ResetOnUserGesture) {
241 NavigateAndCommit(GURL("http://foo.com/bar"));
243 // Do one download, which should change to prompt before download.
244 CanDownload();
245 ExpectAndResetCounts(1, 0, 0, __LINE__);
246 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
247 download_request_limiter_->GetDownloadStatus(web_contents()));
249 // Do a user gesture, which should reset back to allow one.
250 OnUserGesture();
251 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
252 download_request_limiter_->GetDownloadStatus(web_contents()));
254 // Ask twice, which triggers calling the delegate. Don't allow the download
255 // so that we end up with not allowed.
256 CanDownload();
257 ExpectAndResetCounts(1, 0, 0, __LINE__);
258 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
259 download_request_limiter_->GetDownloadStatus(web_contents()));
261 testing_action_ = CANCEL;
262 CanDownload();
263 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
264 download_request_limiter_->GetDownloadStatus(web_contents()));
265 ExpectAndResetCounts(0, 1, 1, __LINE__);
267 // A user gesture now should NOT change the state.
268 OnUserGesture();
269 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
270 download_request_limiter_->GetDownloadStatus(web_contents()));
271 // And make sure we really can't download.
272 CanDownload();
273 ExpectAndResetCounts(0, 1, 0, __LINE__);
274 // And the state shouldn't have changed.
275 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
276 download_request_limiter_->GetDownloadStatus(web_contents()));
279 TEST_F(DownloadRequestLimiterTest,
280 DownloadRequestLimiter_ResetOnReload) {
281 NavigateAndCommit(GURL("http://foo.com/bar"));
282 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
283 download_request_limiter_->GetDownloadStatus(web_contents()));
285 // If the user refreshes the page without responding to the infobar, pretend
286 // like the refresh is the initial load: they get 1 free download (probably
287 // the same as the actual initial load), then an infobar.
288 testing_action_ = WAIT;
290 CanDownload();
291 ExpectAndResetCounts(1, 0, 0, __LINE__);
292 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
293 download_request_limiter_->GetDownloadStatus(web_contents()));
295 CanDownload();
296 ExpectAndResetCounts(0, 0, 1, __LINE__);
297 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
298 download_request_limiter_->GetDownloadStatus(web_contents()));
300 AboutToNavigateRenderView();
301 base::RunLoop().RunUntilIdle();
302 ExpectAndResetCounts(0, 1, 0, __LINE__);
303 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
304 download_request_limiter_->GetDownloadStatus(web_contents()));
306 CanDownload();
307 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
308 download_request_limiter_->GetDownloadStatus(web_contents()));
309 ExpectAndResetCounts(1, 0, 0, __LINE__);
311 testing_action_ = CANCEL;
312 CanDownload();
313 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
314 download_request_limiter_->GetDownloadStatus(web_contents()));
315 ExpectAndResetCounts(0, 1, 1, __LINE__);
317 AboutToNavigateRenderView();
318 base::RunLoop().RunUntilIdle();
319 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
320 download_request_limiter_->GetDownloadStatus(web_contents()));
321 CanDownload();
322 ExpectAndResetCounts(0, 1, 0, __LINE__);
323 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
324 download_request_limiter_->GetDownloadStatus(web_contents()));
327 TEST_F(DownloadRequestLimiterTest,
328 DownloadRequestLimiter_RawWebContents) {
329 scoped_ptr<WebContents> web_contents(CreateTestWebContents());
330 // DownloadRequestLimiter won't try to make an infobar if it doesn't have an
331 // InfoBarService, and we want to test that it will Cancel() instead of
332 // prompting when it doesn't have a InfoBarService, so unset the delegate.
333 UnsetDelegate();
334 ExpectAndResetCounts(0, 0, 0, __LINE__);
335 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
336 download_request_limiter_->GetDownloadStatus(web_contents.get()));
337 // You get one freebie.
338 CanDownloadFor(web_contents.get());
339 ExpectAndResetCounts(1, 0, 0, __LINE__);
340 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
341 download_request_limiter_->GetDownloadStatus(web_contents.get()));
342 OnUserGestureFor(web_contents.get());
343 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
344 download_request_limiter_->GetDownloadStatus(web_contents.get()));
345 CanDownloadFor(web_contents.get());
346 ExpectAndResetCounts(1, 0, 0, __LINE__);
347 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
348 download_request_limiter_->GetDownloadStatus(web_contents.get()));
349 CanDownloadFor(web_contents.get());
350 ExpectAndResetCounts(0, 1, 0, __LINE__);
351 EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
352 download_request_limiter_->GetDownloadStatus(web_contents.get()));
353 OnUserGestureFor(web_contents.get());
354 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
355 download_request_limiter_->GetDownloadStatus(web_contents.get()));
356 CanDownloadFor(web_contents.get());
357 ExpectAndResetCounts(1, 0, 0, __LINE__);
358 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
359 download_request_limiter_->GetDownloadStatus(web_contents.get()));
362 TEST_F(DownloadRequestLimiterTest,
363 DownloadRequestLimiter_SetHostContentSetting) {
364 NavigateAndCommit(GURL("http://foo.com/bar"));
365 SetHostContentSetting(web_contents(), CONTENT_SETTING_ALLOW);
367 CanDownload();
368 ExpectAndResetCounts(1, 0, 0, __LINE__);
369 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
370 download_request_limiter_->GetDownloadStatus(web_contents()));
372 CanDownload();
373 ExpectAndResetCounts(1, 0, 0, __LINE__);
374 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
375 download_request_limiter_->GetDownloadStatus(web_contents()));
377 SetHostContentSetting(web_contents(), CONTENT_SETTING_BLOCK);
379 CanDownload();
380 ExpectAndResetCounts(0, 1, 0, __LINE__);
381 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
382 download_request_limiter_->GetDownloadStatus(web_contents()));
384 CanDownload();
385 ExpectAndResetCounts(0, 1, 0, __LINE__);
386 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
387 download_request_limiter_->GetDownloadStatus(web_contents()));