Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / download / download_request_limiter_unittest.cc
blobfba91b9a065b11ad602c0e7bd617c744b812edb7
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 class Factory : public base::RefCounted<FakePermissionBubbleView::Factory> {
31 public:
32 explicit Factory(DownloadRequestLimiterTest* test) : test_(test) {}
34 scoped_ptr<PermissionBubbleView> Create(Browser* browser) {
35 return make_scoped_ptr(new FakePermissionBubbleView(test_));
38 private:
39 friend class base::RefCounted<FakePermissionBubbleView::Factory>;
41 ~Factory() {}
42 DownloadRequestLimiterTest* test_;
45 explicit FakePermissionBubbleView(DownloadRequestLimiterTest *test)
46 : test_(test), delegate_(NULL) {}
48 ~FakePermissionBubbleView() override {
51 void Close() {
52 if (delegate_)
53 delegate_->Closing();
56 // PermissionBubbleView:
57 void SetDelegate(Delegate* delegate) override { delegate_ = delegate; }
59 void Show(const std::vector<PermissionBubbleRequest*>& requests,
60 const std::vector<bool>& accept_state) override;
62 bool CanAcceptRequestUpdate() override { return false; }
64 void Hide() override {}
65 bool IsVisible() override { return false; }
66 void UpdateAnchorPosition() override{};
67 gfx::NativeWindow GetNativeWindow() override { return nullptr; }
69 private:
70 DownloadRequestLimiterTest* test_;
71 Delegate* delegate_;
74 class DownloadRequestLimiterTest : public ChromeRenderViewHostTestHarness {
75 public:
76 enum TestingAction {
77 ACCEPT,
78 CANCEL,
79 WAIT
82 void SetUp() override {
83 ChromeRenderViewHostTestHarness::SetUp();
84 profile_.reset(new TestingProfile());
85 InfoBarService::CreateForWebContents(web_contents());
87 PermissionBubbleManager::CreateForWebContents(web_contents());
88 scoped_refptr<FakePermissionBubbleView::Factory> factory =
89 new FakePermissionBubbleView::Factory(this);
90 PermissionBubbleManager::FromWebContents(web_contents())->view_factory_ =
91 base::Bind(&FakePermissionBubbleView::Factory::Create, factory);
92 PermissionBubbleManager::FromWebContents(web_contents())
93 ->DisplayPendingRequests(nullptr);
95 testing_action_ = ACCEPT;
96 ask_allow_count_ = cancel_count_ = continue_count_ = 0;
97 download_request_limiter_ = new DownloadRequestLimiter();
98 fake_create_callback_ = base::Bind(
99 &DownloadRequestLimiterTest::FakeCreate, base::Unretained(this));
100 DownloadRequestInfoBarDelegate::SetCallbackForTesting(
101 &fake_create_callback_);
102 content_settings_ = new HostContentSettingsMap(profile_->GetPrefs(), false);
103 DownloadRequestLimiter::SetContentSettingsForTesting(
104 content_settings_.get());
107 int GetAction() {
108 return testing_action_;
111 void AskAllow() {
112 ask_allow_count_++;
115 void FakeCreate(
116 InfoBarService* infobar_service,
117 base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host) {
118 AskAllow();
119 switch (testing_action_) {
120 case ACCEPT:
121 host->Accept();
122 break;
123 case CANCEL:
124 host->Cancel();
125 break;
126 case WAIT:
127 break;
131 void TearDown() override {
132 content_settings_->ShutdownOnUIThread();
133 content_settings_ = NULL;
134 UnsetDelegate();
135 ChromeRenderViewHostTestHarness::TearDown();
138 virtual void UnsetDelegate() {
139 DownloadRequestInfoBarDelegate::SetCallbackForTesting(NULL);
142 void CanDownload() {
143 CanDownloadFor(web_contents());
146 void CanDownloadFor(WebContents* web_contents) {
147 download_request_limiter_->CanDownloadImpl(
148 web_contents,
149 "GET", // request method
150 base::Bind(&DownloadRequestLimiterTest::ContinueDownload,
151 base::Unretained(this)));
152 base::RunLoop().RunUntilIdle();
155 void OnUserGesture() {
156 OnUserGestureFor(web_contents());
159 void OnUserGestureFor(WebContents* web_contents) {
160 DownloadRequestLimiter::TabDownloadState* state =
161 download_request_limiter_->GetDownloadState(web_contents, NULL, false);
162 if (state)
163 state->DidGetUserGesture();
166 void ExpectAndResetCounts(
167 int expect_continues,
168 int expect_cancels,
169 int expect_asks,
170 int line) {
171 EXPECT_EQ(expect_continues, continue_count_) << "line " << line;
172 EXPECT_EQ(expect_cancels, cancel_count_) << "line " << line;
173 EXPECT_EQ(expect_asks, ask_allow_count_) << "line " << line;
174 continue_count_ = cancel_count_ = ask_allow_count_ = 0;
177 protected:
178 void ContinueDownload(bool allow) {
179 if (allow) {
180 continue_count_++;
181 } else {
182 cancel_count_++;
186 void SetHostContentSetting(WebContents* contents, ContentSetting setting) {
187 content_settings_->SetContentSetting(
188 ContentSettingsPattern::FromURL(contents->GetURL()),
189 ContentSettingsPattern::Wildcard(),
190 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
191 std::string(),
192 setting);
195 void BubbleManagerDocumentLoadCompleted(bool bubbles_enabled) {
196 if (!bubbles_enabled)
197 return;
198 PermissionBubbleManager::FromWebContents(web_contents())->
199 DocumentOnLoadCompletedInMainFrame();
202 scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
204 // The action that FakeCreate() should take.
205 TestingAction testing_action_;
207 // Number of times ContinueDownload was invoked.
208 int continue_count_;
210 // Number of times CancelDownload was invoked.
211 int cancel_count_;
213 // Number of times ShouldAllowDownload was invoked.
214 int ask_allow_count_;
216 scoped_refptr<HostContentSettingsMap> content_settings_;
218 private:
219 DownloadRequestInfoBarDelegate::FakeCreateCallback fake_create_callback_;
220 scoped_ptr<TestingProfile> profile_;
223 void FakePermissionBubbleView::Show(
224 const std::vector<PermissionBubbleRequest*>& requests,
225 const std::vector<bool>& accept_state) {
226 test_->AskAllow();
227 int action = test_->GetAction();
228 if (action == DownloadRequestLimiterTest::ACCEPT) {
229 delegate_->Accept();
230 } else if (action == DownloadRequestLimiterTest::CANCEL) {
231 delegate_->Deny();
232 } else if (action == DownloadRequestLimiterTest::WAIT) {
233 // do nothing.
234 } else {
235 delegate_->Closing();
239 class DownloadRequestLimiterParamTests
240 : public DownloadRequestLimiterTest,
241 public ::testing::WithParamInterface<bool> {
242 protected:
243 DownloadRequestLimiterParamTests() {}
244 ~DownloadRequestLimiterParamTests() override {}
246 void SetUp() override {
247 DownloadRequestLimiterTest::SetUp();
248 #if !defined(OS_ANDROID)
249 if (GetParam()) {
250 base::CommandLine::ForCurrentProcess()->AppendSwitch(
251 switches::kEnablePermissionsBubbles);
252 EXPECT_TRUE(PermissionBubbleManager::Enabled());
253 } else {
254 base::CommandLine::ForCurrentProcess()->AppendSwitch(
255 switches::kDisablePermissionsBubbles);
257 #endif
260 void BubbleManagerDocumentLoadCompleted() {
261 #if defined(OS_ANDROID)
262 DownloadRequestLimiterTest::BubbleManagerDocumentLoadCompleted(false);
263 #else
264 DownloadRequestLimiterTest::BubbleManagerDocumentLoadCompleted(GetParam());
265 #endif
267 private:
268 DISALLOW_COPY_AND_ASSIGN(DownloadRequestLimiterParamTests);
271 TEST_P(DownloadRequestLimiterParamTests,
272 DownloadRequestLimiter_Allow) {
273 BubbleManagerDocumentLoadCompleted();
275 // All tabs should initially start at ALLOW_ONE_DOWNLOAD.
276 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
277 download_request_limiter_->GetDownloadStatus(web_contents()));
279 // Ask if the tab can do a download. This moves to PROMPT_BEFORE_DOWNLOAD.
280 CanDownload();
281 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
282 download_request_limiter_->GetDownloadStatus(web_contents()));
283 // We should have been told we can download.
284 ExpectAndResetCounts(1, 0, 0, __LINE__);
286 // Ask again. This triggers asking the delegate for allow/disallow.
287 testing_action_ = ACCEPT;
288 CanDownload();
289 // This should ask us if the download is allowed.
290 // We should have been told we can download.
291 ExpectAndResetCounts(1, 0, 1, __LINE__);
292 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
293 download_request_limiter_->GetDownloadStatus(web_contents()));
295 // Ask again and make sure continue is invoked.
296 CanDownload();
297 // The state is at allow_all, which means the delegate shouldn't be asked.
298 // We should have been told we can download.
299 ExpectAndResetCounts(1, 0, 0, __LINE__);
300 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
301 download_request_limiter_->GetDownloadStatus(web_contents()));
304 TEST_P(DownloadRequestLimiterParamTests,
305 DownloadRequestLimiter_ResetOnNavigation) {
306 NavigateAndCommit(GURL("http://foo.com/bar"));
307 BubbleManagerDocumentLoadCompleted();
309 // Do two downloads, allowing the second so that we end up with allow all.
310 CanDownload();
311 ExpectAndResetCounts(1, 0, 0, __LINE__);
312 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
313 download_request_limiter_->GetDownloadStatus(web_contents()));
315 testing_action_ = ACCEPT;
316 CanDownload();
317 ExpectAndResetCounts(1, 0, 1, __LINE__);
318 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
319 download_request_limiter_->GetDownloadStatus(web_contents()));
321 // Navigate to a new URL with the same host, which shouldn't reset the allow
322 // all state.
323 NavigateAndCommit(GURL("http://foo.com/bar2"));
324 BubbleManagerDocumentLoadCompleted();
325 CanDownload();
326 ExpectAndResetCounts(1, 0, 0, __LINE__);
327 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
328 download_request_limiter_->GetDownloadStatus(web_contents()));
330 // Do a user gesture, because we're at allow all, this shouldn't change the
331 // state.
332 OnUserGesture();
333 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
334 download_request_limiter_->GetDownloadStatus(web_contents()));
336 // Navigate to a completely different host, which should reset the state.
337 NavigateAndCommit(GURL("http://fooey.com"));
338 BubbleManagerDocumentLoadCompleted();
339 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
340 download_request_limiter_->GetDownloadStatus(web_contents()));
342 // Do two downloads, allowing the second so that we end up with allow all.
343 CanDownload();
344 ExpectAndResetCounts(1, 0, 0, __LINE__);
345 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
346 download_request_limiter_->GetDownloadStatus(web_contents()));
348 testing_action_ = CANCEL;
349 CanDownload();
350 ExpectAndResetCounts(0, 1, 1, __LINE__);
351 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
352 download_request_limiter_->GetDownloadStatus(web_contents()));
354 // Navigate to a new URL with the same host, which shouldn't reset the allow
355 // all state.
356 NavigateAndCommit(GURL("http://fooey.com/bar2"));
357 BubbleManagerDocumentLoadCompleted();
358 CanDownload();
359 ExpectAndResetCounts(0, 1, 0, __LINE__);
360 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
361 download_request_limiter_->GetDownloadStatus(web_contents()));
364 TEST_P(DownloadRequestLimiterParamTests,
365 DownloadRequestLimiter_ResetOnUserGesture) {
366 NavigateAndCommit(GURL("http://foo.com/bar"));
367 BubbleManagerDocumentLoadCompleted();
369 // Do one download, which should change to prompt before download.
370 CanDownload();
371 ExpectAndResetCounts(1, 0, 0, __LINE__);
372 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
373 download_request_limiter_->GetDownloadStatus(web_contents()));
375 // Do a user gesture, which should reset back to allow one.
376 OnUserGesture();
377 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
378 download_request_limiter_->GetDownloadStatus(web_contents()));
380 // Ask twice, which triggers calling the delegate. Don't allow the download
381 // so that we end up with not allowed.
382 CanDownload();
383 ExpectAndResetCounts(1, 0, 0, __LINE__);
384 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
385 download_request_limiter_->GetDownloadStatus(web_contents()));
387 testing_action_ = CANCEL;
388 CanDownload();
389 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
390 download_request_limiter_->GetDownloadStatus(web_contents()));
391 ExpectAndResetCounts(0, 1, 1, __LINE__);
393 // A user gesture now should NOT change the state.
394 OnUserGesture();
395 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
396 download_request_limiter_->GetDownloadStatus(web_contents()));
397 // And make sure we really can't download.
398 CanDownload();
399 ExpectAndResetCounts(0, 1, 0, __LINE__);
400 // And the state shouldn't have changed.
401 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
402 download_request_limiter_->GetDownloadStatus(web_contents()));
405 TEST_P(DownloadRequestLimiterParamTests,
406 DownloadRequestLimiter_ResetOnReload) {
407 NavigateAndCommit(GURL("http://foo.com/bar"));
408 BubbleManagerDocumentLoadCompleted();
409 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
410 download_request_limiter_->GetDownloadStatus(web_contents()));
412 // If the user refreshes the page without responding to the infobar, pretend
413 // like the refresh is the initial load: they get 1 free download (probably
414 // the same as the actual initial load), then an infobar.
415 testing_action_ = WAIT;
417 CanDownload();
418 ExpectAndResetCounts(1, 0, 0, __LINE__);
419 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
420 download_request_limiter_->GetDownloadStatus(web_contents()));
422 CanDownload();
423 ExpectAndResetCounts(0, 0, 1, __LINE__);
424 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
425 download_request_limiter_->GetDownloadStatus(web_contents()));
427 Reload();
428 BubbleManagerDocumentLoadCompleted();
429 base::RunLoop().RunUntilIdle();
430 ExpectAndResetCounts(0, 1, 0, __LINE__);
431 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
432 download_request_limiter_->GetDownloadStatus(web_contents()));
434 CanDownload();
435 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
436 download_request_limiter_->GetDownloadStatus(web_contents()));
437 ExpectAndResetCounts(1, 0, 0, __LINE__);
439 testing_action_ = CANCEL;
440 CanDownload();
441 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
442 download_request_limiter_->GetDownloadStatus(web_contents()));
443 ExpectAndResetCounts(0, 1, 1, __LINE__);
445 Reload();
446 BubbleManagerDocumentLoadCompleted();
447 base::RunLoop().RunUntilIdle();
448 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
449 download_request_limiter_->GetDownloadStatus(web_contents()));
450 CanDownload();
451 ExpectAndResetCounts(0, 1, 0, __LINE__);
452 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
453 download_request_limiter_->GetDownloadStatus(web_contents()));
456 TEST_P(DownloadRequestLimiterParamTests,
457 DownloadRequestLimiter_RawWebContents) {
458 scoped_ptr<WebContents> web_contents(CreateTestWebContents());
460 // DownloadRequestLimiter won't try to make a permission bubble if there's
461 // no permission bubble manager, so don't put one on the test WebContents.
463 // DownloadRequestLimiter won't try to make an infobar if it doesn't have an
464 // InfoBarService, and we want to test that it will Cancel() instead of
465 // prompting when it doesn't have a InfoBarService, so unset the delegate.
466 UnsetDelegate();
467 ExpectAndResetCounts(0, 0, 0, __LINE__);
468 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
469 download_request_limiter_->GetDownloadStatus(web_contents.get()));
470 // You get one freebie.
471 CanDownloadFor(web_contents.get());
472 ExpectAndResetCounts(1, 0, 0, __LINE__);
473 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
474 download_request_limiter_->GetDownloadStatus(web_contents.get()));
475 OnUserGestureFor(web_contents.get());
476 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
477 download_request_limiter_->GetDownloadStatus(web_contents.get()));
478 CanDownloadFor(web_contents.get());
479 ExpectAndResetCounts(1, 0, 0, __LINE__);
480 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
481 download_request_limiter_->GetDownloadStatus(web_contents.get()));
482 CanDownloadFor(web_contents.get());
483 ExpectAndResetCounts(0, 1, 0, __LINE__);
484 EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
485 download_request_limiter_->GetDownloadStatus(web_contents.get()));
486 OnUserGestureFor(web_contents.get());
487 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
488 download_request_limiter_->GetDownloadStatus(web_contents.get()));
489 CanDownloadFor(web_contents.get());
490 ExpectAndResetCounts(1, 0, 0, __LINE__);
491 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
492 download_request_limiter_->GetDownloadStatus(web_contents.get()));
495 TEST_P(DownloadRequestLimiterParamTests,
496 DownloadRequestLimiter_SetHostContentSetting) {
497 NavigateAndCommit(GURL("http://foo.com/bar"));
498 BubbleManagerDocumentLoadCompleted();
499 SetHostContentSetting(web_contents(), CONTENT_SETTING_ALLOW);
501 CanDownload();
502 ExpectAndResetCounts(1, 0, 0, __LINE__);
503 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
504 download_request_limiter_->GetDownloadStatus(web_contents()));
506 CanDownload();
507 ExpectAndResetCounts(1, 0, 0, __LINE__);
508 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
509 download_request_limiter_->GetDownloadStatus(web_contents()));
511 SetHostContentSetting(web_contents(), CONTENT_SETTING_BLOCK);
513 CanDownload();
514 ExpectAndResetCounts(0, 1, 0, __LINE__);
515 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
516 download_request_limiter_->GetDownloadStatus(web_contents()));
518 CanDownload();
519 ExpectAndResetCounts(0, 1, 0, __LINE__);
520 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
521 download_request_limiter_->GetDownloadStatus(web_contents()));
524 INSTANTIATE_TEST_CASE_P(DownloadRequestLimiterTestsWithAndWithoutBubbles,
525 DownloadRequestLimiterParamTests,
526 ::testing::Values(false, true));