Add ENABLE_MEDIA_ROUTER define to builds other than Android and iOS.
[chromium-blink-merge.git] / chrome / browser / download / download_request_limiter_unittest.cc
bloba343335328ff08d25fbf2ec963a78c826d267b14
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/command_line.h"
9 #include "base/run_loop.h"
10 #include "chrome/browser/download/download_permission_request.h"
11 #include "chrome/browser/download/download_request_infobar_delegate.h"
12 #include "chrome/browser/infobars/infobar_service.h"
13 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/content_settings/core/browser/host_content_settings_map.h"
18 #include "content/public/browser/navigation_controller.h"
19 #include "content/public/browser/navigation_details.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/common/frame_navigate_params.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 using content::WebContents;
26 class DownloadRequestLimiterTest;
28 class FakePermissionBubbleView : public PermissionBubbleView {
29 public:
30 explicit FakePermissionBubbleView(DownloadRequestLimiterTest *test)
31 : test_(test), delegate_(NULL) {}
33 ~FakePermissionBubbleView() override {
34 if (delegate_)
35 delegate_->SetView(NULL);
38 void Close() {
39 if (delegate_)
40 delegate_->Closing();
43 // PermissionBubbleView:
44 void SetDelegate(Delegate* delegate) override { delegate_ = delegate; }
46 void Show(const std::vector<PermissionBubbleRequest*>& requests,
47 const std::vector<bool>& accept_state) override;
49 bool CanAcceptRequestUpdate() override { return false; }
51 void Hide() override {}
52 bool IsVisible() override { return false; }
54 private:
55 DownloadRequestLimiterTest* test_;
56 Delegate* delegate_;
59 class DownloadRequestLimiterTest : public ChromeRenderViewHostTestHarness {
60 public:
61 enum TestingAction {
62 ACCEPT,
63 CANCEL,
64 WAIT
67 void SetUp() override {
68 ChromeRenderViewHostTestHarness::SetUp();
69 InfoBarService::CreateForWebContents(web_contents());
71 PermissionBubbleManager::CreateForWebContents(web_contents());
72 view_.reset(new FakePermissionBubbleView(this));
73 PermissionBubbleManager::FromWebContents(web_contents())->
74 SetView(view_.get());
76 testing_action_ = ACCEPT;
77 ask_allow_count_ = cancel_count_ = continue_count_ = 0;
78 download_request_limiter_ = new DownloadRequestLimiter();
79 fake_create_callback_ = base::Bind(
80 &DownloadRequestLimiterTest::FakeCreate, base::Unretained(this));
81 DownloadRequestInfoBarDelegate::SetCallbackForTesting(
82 &fake_create_callback_);
83 content_settings_ = new HostContentSettingsMap(profile_.GetPrefs(), false);
84 DownloadRequestLimiter::SetContentSettingsForTesting(
85 content_settings_.get());
88 int GetAction() {
89 return testing_action_;
92 void AskAllow() {
93 ask_allow_count_++;
96 void FakeCreate(
97 InfoBarService* infobar_service,
98 base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host) {
99 AskAllow();
100 switch (testing_action_) {
101 case ACCEPT:
102 host->Accept();
103 break;
104 case CANCEL:
105 host->Cancel();
106 break;
107 case WAIT:
108 break;
112 void TearDown() override {
113 content_settings_->ShutdownOnUIThread();
114 content_settings_ = NULL;
115 UnsetDelegate();
116 ChromeRenderViewHostTestHarness::TearDown();
119 virtual void UnsetDelegate() {
120 DownloadRequestInfoBarDelegate::SetCallbackForTesting(NULL);
123 void CanDownload() {
124 CanDownloadFor(web_contents());
127 void CanDownloadFor(WebContents* web_contents) {
128 download_request_limiter_->CanDownloadImpl(
129 web_contents,
130 "GET", // request method
131 base::Bind(&DownloadRequestLimiterTest::ContinueDownload,
132 base::Unretained(this)));
133 base::RunLoop().RunUntilIdle();
136 void OnUserGesture() {
137 OnUserGestureFor(web_contents());
140 void OnUserGestureFor(WebContents* web_contents) {
141 DownloadRequestLimiter::TabDownloadState* state =
142 download_request_limiter_->GetDownloadState(web_contents, NULL, false);
143 if (state)
144 state->DidGetUserGesture();
147 void DidNavigateMainFrame() {
148 view_->Close();
149 DownloadRequestLimiter::TabDownloadState* state =
150 download_request_limiter_->GetDownloadState(
151 web_contents(), NULL, false);
152 content::LoadCommittedDetails details;
153 content::FrameNavigateParams params;
154 state->DidNavigateMainFrame(details, params);
157 void ExpectAndResetCounts(
158 int expect_continues,
159 int expect_cancels,
160 int expect_asks,
161 int line) {
162 EXPECT_EQ(expect_continues, continue_count_) << "line " << line;
163 EXPECT_EQ(expect_cancels, cancel_count_) << "line " << line;
164 EXPECT_EQ(expect_asks, ask_allow_count_) << "line " << line;
165 continue_count_ = cancel_count_ = ask_allow_count_ = 0;
168 protected:
169 void ContinueDownload(bool allow) {
170 if (allow) {
171 continue_count_++;
172 } else {
173 cancel_count_++;
177 void SetHostContentSetting(WebContents* contents, ContentSetting setting) {
178 content_settings_->SetContentSetting(
179 ContentSettingsPattern::FromURL(contents->GetURL()),
180 ContentSettingsPattern::Wildcard(),
181 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
182 std::string(),
183 setting);
186 void BubbleManagerDocumentLoadCompleted(bool bubbles_enabled) {
187 if (!bubbles_enabled)
188 return;
189 PermissionBubbleManager::FromWebContents(web_contents())->
190 DocumentOnLoadCompletedInMainFrame();
193 scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
195 // The action that FakeCreate() should take.
196 TestingAction testing_action_;
198 // Number of times ContinueDownload was invoked.
199 int continue_count_;
201 // Number of times CancelDownload was invoked.
202 int cancel_count_;
204 // Number of times ShouldAllowDownload was invoked.
205 int ask_allow_count_;
207 scoped_refptr<HostContentSettingsMap> content_settings_;
209 private:
210 DownloadRequestInfoBarDelegate::FakeCreateCallback fake_create_callback_;
211 TestingProfile profile_;
212 scoped_ptr<FakePermissionBubbleView> view_;
215 void FakePermissionBubbleView::Show(
216 const std::vector<PermissionBubbleRequest*>& requests,
217 const std::vector<bool>& accept_state) {
218 test_->AskAllow();
219 int action = test_->GetAction();
220 if (action == DownloadRequestLimiterTest::ACCEPT) {
221 delegate_->Accept();
222 } else if (action == DownloadRequestLimiterTest::CANCEL) {
223 delegate_->Deny();
224 } else if (action == DownloadRequestLimiterTest::WAIT) {
225 // do nothing.
226 } else {
227 delegate_->Closing();
231 class DownloadRequestLimiterParamTests
232 : public DownloadRequestLimiterTest,
233 public ::testing::WithParamInterface<bool> {
234 protected:
235 DownloadRequestLimiterParamTests() {}
236 ~DownloadRequestLimiterParamTests() override {}
238 void SetUp() override {
239 DownloadRequestLimiterTest::SetUp();
240 #if !defined(OS_ANDROID)
241 if (GetParam()) {
242 base::CommandLine::ForCurrentProcess()->AppendSwitch(
243 switches::kEnablePermissionsBubbles);
244 EXPECT_TRUE(PermissionBubbleManager::Enabled());
245 } else {
246 base::CommandLine::ForCurrentProcess()->AppendSwitch(
247 switches::kDisablePermissionsBubbles);
249 #endif
252 void BubbleManagerDocumentLoadCompleted() {
253 #if defined(OS_ANDROID)
254 DownloadRequestLimiterTest::BubbleManagerDocumentLoadCompleted(false);
255 #else
256 DownloadRequestLimiterTest::BubbleManagerDocumentLoadCompleted(GetParam());
257 #endif
259 private:
260 DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiterParamTests);
263 TEST_P(DownloadRequestLimiterParamTests,
264 DownloadRequestLimiter_Allow) {
265 BubbleManagerDocumentLoadCompleted();
267 // All tabs should initially start at ALLOW_ONE_DOWNLOAD.
268 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
269 download_request_limiter_->GetDownloadStatus(web_contents()));
271 // Ask if the tab can do a download. This moves to PROMPT_BEFORE_DOWNLOAD.
272 CanDownload();
273 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
274 download_request_limiter_->GetDownloadStatus(web_contents()));
275 // We should have been told we can download.
276 ExpectAndResetCounts(1, 0, 0, __LINE__);
278 // Ask again. This triggers asking the delegate for allow/disallow.
279 testing_action_ = ACCEPT;
280 CanDownload();
281 // This should ask us if the download is allowed.
282 // We should have been told we can download.
283 ExpectAndResetCounts(1, 0, 1, __LINE__);
284 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
285 download_request_limiter_->GetDownloadStatus(web_contents()));
287 // Ask again and make sure continue is invoked.
288 CanDownload();
289 // The state is at allow_all, which means the delegate shouldn't be asked.
290 // We should have been told we can download.
291 ExpectAndResetCounts(1, 0, 0, __LINE__);
292 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
293 download_request_limiter_->GetDownloadStatus(web_contents()));
296 TEST_P(DownloadRequestLimiterParamTests,
297 DownloadRequestLimiter_ResetOnNavigation) {
298 NavigateAndCommit(GURL("http://foo.com/bar"));
299 BubbleManagerDocumentLoadCompleted();
301 // Do two downloads, allowing the second so that we end up with allow all.
302 CanDownload();
303 ExpectAndResetCounts(1, 0, 0, __LINE__);
304 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
305 download_request_limiter_->GetDownloadStatus(web_contents()));
307 testing_action_ = ACCEPT;
308 CanDownload();
309 ExpectAndResetCounts(1, 0, 1, __LINE__);
310 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
311 download_request_limiter_->GetDownloadStatus(web_contents()));
313 // Navigate to a new URL with the same host, which shouldn't reset the allow
314 // all state.
315 NavigateAndCommit(GURL("http://foo.com/bar2"));
316 BubbleManagerDocumentLoadCompleted();
317 CanDownload();
318 ExpectAndResetCounts(1, 0, 0, __LINE__);
319 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
320 download_request_limiter_->GetDownloadStatus(web_contents()));
322 // Do a user gesture, because we're at allow all, this shouldn't change the
323 // state.
324 OnUserGesture();
325 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
326 download_request_limiter_->GetDownloadStatus(web_contents()));
328 // Navigate to a completely different host, which should reset the state.
329 NavigateAndCommit(GURL("http://fooey.com"));
330 BubbleManagerDocumentLoadCompleted();
331 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
332 download_request_limiter_->GetDownloadStatus(web_contents()));
334 // Do two downloads, allowing the second so that we end up with allow all.
335 CanDownload();
336 ExpectAndResetCounts(1, 0, 0, __LINE__);
337 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
338 download_request_limiter_->GetDownloadStatus(web_contents()));
340 testing_action_ = CANCEL;
341 CanDownload();
342 ExpectAndResetCounts(0, 1, 1, __LINE__);
343 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
344 download_request_limiter_->GetDownloadStatus(web_contents()));
346 // Navigate to a new URL with the same host, which shouldn't reset the allow
347 // all state.
348 NavigateAndCommit(GURL("http://fooey.com/bar2"));
349 BubbleManagerDocumentLoadCompleted();
350 CanDownload();
351 ExpectAndResetCounts(0, 1, 0, __LINE__);
352 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
353 download_request_limiter_->GetDownloadStatus(web_contents()));
356 TEST_P(DownloadRequestLimiterParamTests,
357 DownloadRequestLimiter_ResetOnUserGesture) {
358 NavigateAndCommit(GURL("http://foo.com/bar"));
359 BubbleManagerDocumentLoadCompleted();
361 // Do one download, which should change to prompt before download.
362 CanDownload();
363 ExpectAndResetCounts(1, 0, 0, __LINE__);
364 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
365 download_request_limiter_->GetDownloadStatus(web_contents()));
367 // Do a user gesture, which should reset back to allow one.
368 OnUserGesture();
369 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
370 download_request_limiter_->GetDownloadStatus(web_contents()));
372 // Ask twice, which triggers calling the delegate. Don't allow the download
373 // so that we end up with not allowed.
374 CanDownload();
375 ExpectAndResetCounts(1, 0, 0, __LINE__);
376 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
377 download_request_limiter_->GetDownloadStatus(web_contents()));
379 testing_action_ = CANCEL;
380 CanDownload();
381 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
382 download_request_limiter_->GetDownloadStatus(web_contents()));
383 ExpectAndResetCounts(0, 1, 1, __LINE__);
385 // A user gesture now should NOT change the state.
386 OnUserGesture();
387 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
388 download_request_limiter_->GetDownloadStatus(web_contents()));
389 // And make sure we really can't download.
390 CanDownload();
391 ExpectAndResetCounts(0, 1, 0, __LINE__);
392 // And the state shouldn't have changed.
393 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
394 download_request_limiter_->GetDownloadStatus(web_contents()));
397 TEST_P(DownloadRequestLimiterParamTests,
398 DownloadRequestLimiter_ResetOnReload) {
399 NavigateAndCommit(GURL("http://foo.com/bar"));
400 BubbleManagerDocumentLoadCompleted();
401 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
402 download_request_limiter_->GetDownloadStatus(web_contents()));
404 // If the user refreshes the page without responding to the infobar, pretend
405 // like the refresh is the initial load: they get 1 free download (probably
406 // the same as the actual initial load), then an infobar.
407 testing_action_ = WAIT;
409 CanDownload();
410 ExpectAndResetCounts(1, 0, 0, __LINE__);
411 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
412 download_request_limiter_->GetDownloadStatus(web_contents()));
414 CanDownload();
415 ExpectAndResetCounts(0, 0, 1, __LINE__);
416 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
417 download_request_limiter_->GetDownloadStatus(web_contents()));
419 DidNavigateMainFrame();
420 base::RunLoop().RunUntilIdle();
421 ExpectAndResetCounts(0, 1, 0, __LINE__);
422 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
423 download_request_limiter_->GetDownloadStatus(web_contents()));
425 CanDownload();
426 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
427 download_request_limiter_->GetDownloadStatus(web_contents()));
428 ExpectAndResetCounts(1, 0, 0, __LINE__);
430 testing_action_ = CANCEL;
431 CanDownload();
432 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
433 download_request_limiter_->GetDownloadStatus(web_contents()));
434 ExpectAndResetCounts(0, 1, 1, __LINE__);
436 DidNavigateMainFrame();
437 base::RunLoop().RunUntilIdle();
438 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
439 download_request_limiter_->GetDownloadStatus(web_contents()));
440 CanDownload();
441 ExpectAndResetCounts(0, 1, 0, __LINE__);
442 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
443 download_request_limiter_->GetDownloadStatus(web_contents()));
446 TEST_P(DownloadRequestLimiterParamTests,
447 DownloadRequestLimiter_RawWebContents) {
448 scoped_ptr<WebContents> web_contents(CreateTestWebContents());
450 // DownloadRequestLimiter won't try to make a permission bubble if there's
451 // no permission bubble manager, so don't put one on the test WebContents.
453 // DownloadRequestLimiter won't try to make an infobar if it doesn't have an
454 // InfoBarService, and we want to test that it will Cancel() instead of
455 // prompting when it doesn't have a InfoBarService, so unset the delegate.
456 UnsetDelegate();
457 ExpectAndResetCounts(0, 0, 0, __LINE__);
458 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
459 download_request_limiter_->GetDownloadStatus(web_contents.get()));
460 // You get one freebie.
461 CanDownloadFor(web_contents.get());
462 ExpectAndResetCounts(1, 0, 0, __LINE__);
463 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
464 download_request_limiter_->GetDownloadStatus(web_contents.get()));
465 OnUserGestureFor(web_contents.get());
466 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
467 download_request_limiter_->GetDownloadStatus(web_contents.get()));
468 CanDownloadFor(web_contents.get());
469 ExpectAndResetCounts(1, 0, 0, __LINE__);
470 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
471 download_request_limiter_->GetDownloadStatus(web_contents.get()));
472 CanDownloadFor(web_contents.get());
473 ExpectAndResetCounts(0, 1, 0, __LINE__);
474 EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
475 download_request_limiter_->GetDownloadStatus(web_contents.get()));
476 OnUserGestureFor(web_contents.get());
477 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
478 download_request_limiter_->GetDownloadStatus(web_contents.get()));
479 CanDownloadFor(web_contents.get());
480 ExpectAndResetCounts(1, 0, 0, __LINE__);
481 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
482 download_request_limiter_->GetDownloadStatus(web_contents.get()));
485 TEST_P(DownloadRequestLimiterParamTests,
486 DownloadRequestLimiter_SetHostContentSetting) {
487 NavigateAndCommit(GURL("http://foo.com/bar"));
488 BubbleManagerDocumentLoadCompleted();
489 SetHostContentSetting(web_contents(), CONTENT_SETTING_ALLOW);
491 CanDownload();
492 ExpectAndResetCounts(1, 0, 0, __LINE__);
493 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
494 download_request_limiter_->GetDownloadStatus(web_contents()));
496 CanDownload();
497 ExpectAndResetCounts(1, 0, 0, __LINE__);
498 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
499 download_request_limiter_->GetDownloadStatus(web_contents()));
501 SetHostContentSetting(web_contents(), CONTENT_SETTING_BLOCK);
503 CanDownload();
504 ExpectAndResetCounts(0, 1, 0, __LINE__);
505 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
506 download_request_limiter_->GetDownloadStatus(web_contents()));
508 CanDownload();
509 ExpectAndResetCounts(0, 1, 0, __LINE__);
510 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
511 download_request_limiter_->GetDownloadStatus(web_contents()));
514 INSTANTIATE_TEST_CASE_P(DownloadRequestLimiterTestsWithAndWithoutBubbles,
515 DownloadRequestLimiterParamTests,
516 ::testing::Values(false, true));