[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / download / download_request_limiter_unittest.cc
blob299906fee3af35d5cf81ad2269dca95c8cd24275
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/browser/ui/website_settings/permission_bubble_manager.h"
13 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
14 #include "chrome/test/base/testing_profile.h"
15 #include "content/public/browser/navigation_controller.h"
16 #include "content/public/browser/web_contents.h"
17 #include "testing/gtest/include/gtest/gtest.h"
19 using content::WebContents;
21 class DownloadRequestLimiterTest;
23 class FakePermissionBubbleView : public PermissionBubbleView {
24 public:
25 explicit FakePermissionBubbleView(DownloadRequestLimiterTest *test)
26 : test_(test), delegate_(NULL) {}
28 virtual ~FakePermissionBubbleView() {
29 if (delegate_)
30 delegate_->SetView(NULL);
33 void Close() {
34 if (delegate_)
35 delegate_->Closing();
38 // PermissionBubbleView:
39 virtual void SetDelegate(Delegate* delegate) OVERRIDE {
40 delegate_ = delegate;
43 virtual void Show(
44 const std::vector<PermissionBubbleRequest*>& requests,
45 const std::vector<bool>& accept_state,
46 bool customization_mode) OVERRIDE;
48 virtual bool CanAcceptRequestUpdate() OVERRIDE { return false; }
50 virtual void Hide() OVERRIDE {}
52 private:
53 DownloadRequestLimiterTest* test_;
54 Delegate* delegate_;
57 class DownloadRequestLimiterTest : public ChromeRenderViewHostTestHarness {
58 public:
59 enum TestingAction {
60 ACCEPT,
61 CANCEL,
62 WAIT
65 virtual void SetUp() {
66 ChromeRenderViewHostTestHarness::SetUp();
67 InfoBarService::CreateForWebContents(web_contents());
69 PermissionBubbleManager::CreateForWebContents(web_contents());
70 view_.reset(new FakePermissionBubbleView(this));
71 PermissionBubbleManager* manager =
72 PermissionBubbleManager::FromWebContents(web_contents());
73 manager->SetView(view_.get());
75 testing_action_ = ACCEPT;
76 ask_allow_count_ = cancel_count_ = continue_count_ = 0;
77 download_request_limiter_ = new DownloadRequestLimiter();
78 fake_create_callback_ = base::Bind(
79 &DownloadRequestLimiterTest::FakeCreate, base::Unretained(this));
80 DownloadRequestInfoBarDelegate::SetCallbackForTesting(
81 &fake_create_callback_);
82 content_settings_ = new HostContentSettingsMap(profile_.GetPrefs(), false);
83 DownloadRequestLimiter::SetContentSettingsForTesting(
84 content_settings_.get());
87 int GetAction() {
88 return testing_action_;
91 void AskAllow() {
92 ask_allow_count_++;
95 void FakeCreate(
96 InfoBarService* infobar_service,
97 base::WeakPtr<DownloadRequestLimiter::TabDownloadState> host) {
98 AskAllow();
99 switch (testing_action_) {
100 case ACCEPT:
101 host->Accept();
102 break;
103 case CANCEL:
104 host->Cancel();
105 break;
106 case WAIT:
107 break;
111 virtual void TearDown() {
112 content_settings_->ShutdownOnUIThread();
113 content_settings_ = NULL;
114 UnsetDelegate();
115 ChromeRenderViewHostTestHarness::TearDown();
118 virtual void UnsetDelegate() {
119 DownloadRequestInfoBarDelegate::SetCallbackForTesting(NULL);
122 void CanDownload() {
123 CanDownloadFor(web_contents());
126 void CanDownloadFor(WebContents* web_contents) {
127 download_request_limiter_->CanDownloadImpl(
128 web_contents,
129 "GET", // request method
130 base::Bind(&DownloadRequestLimiterTest::ContinueDownload,
131 base::Unretained(this)));
132 base::RunLoop().RunUntilIdle();
135 void OnUserGesture() {
136 OnUserGestureFor(web_contents());
139 void OnUserGestureFor(WebContents* web_contents) {
140 DownloadRequestLimiter::TabDownloadState* state =
141 download_request_limiter_->GetDownloadState(web_contents, NULL, false);
142 if (state)
143 state->DidGetUserGesture();
146 void AboutToNavigateRenderView() {
147 view_->Close();
148 DownloadRequestLimiter::TabDownloadState* state =
149 download_request_limiter_->GetDownloadState(
150 web_contents(), NULL, false);
151 state->AboutToNavigateRenderView(NULL);
154 void ExpectAndResetCounts(
155 int expect_continues,
156 int expect_cancels,
157 int expect_asks,
158 int line) {
159 EXPECT_EQ(expect_continues, continue_count_) << "line " << line;
160 EXPECT_EQ(expect_cancels, cancel_count_) << "line " << line;
161 EXPECT_EQ(expect_asks, ask_allow_count_) << "line " << line;
162 continue_count_ = cancel_count_ = ask_allow_count_ = 0;
165 protected:
166 void ContinueDownload(bool allow) {
167 if (allow) {
168 continue_count_++;
169 } else {
170 cancel_count_++;
174 void SetHostContentSetting(WebContents* contents, ContentSetting setting) {
175 content_settings_->SetContentSetting(
176 ContentSettingsPattern::FromURL(contents->GetURL()),
177 ContentSettingsPattern::Wildcard(),
178 CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
179 std::string(),
180 setting);
183 scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
185 // The action that FakeCreate() should take.
186 TestingAction testing_action_;
188 // Number of times ContinueDownload was invoked.
189 int continue_count_;
191 // Number of times CancelDownload was invoked.
192 int cancel_count_;
194 // Number of times ShouldAllowDownload was invoked.
195 int ask_allow_count_;
197 scoped_refptr<HostContentSettingsMap> content_settings_;
199 private:
200 DownloadRequestInfoBarDelegate::FakeCreateCallback fake_create_callback_;
201 TestingProfile profile_;
202 scoped_ptr<FakePermissionBubbleView> view_;
205 void FakePermissionBubbleView::Show(
206 const std::vector<PermissionBubbleRequest*>& requests,
207 const std::vector<bool>& accept_state,
208 bool customization_mode) {
209 test_->AskAllow();
210 int action = test_->GetAction();
211 if (action == DownloadRequestLimiterTest::ACCEPT) {
212 delegate_->Accept();
213 } else if (action == DownloadRequestLimiterTest::CANCEL) {
214 delegate_->Deny();
215 } else if (action == DownloadRequestLimiterTest::WAIT) {
216 // do nothing.
217 } else {
218 delegate_->Closing();
222 TEST_F(DownloadRequestLimiterTest,
223 DownloadRequestLimiter_Allow) {
224 // All tabs should initially start at ALLOW_ONE_DOWNLOAD.
225 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
226 download_request_limiter_->GetDownloadStatus(web_contents()));
228 // Ask if the tab can do a download. This moves to PROMPT_BEFORE_DOWNLOAD.
229 CanDownload();
230 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
231 download_request_limiter_->GetDownloadStatus(web_contents()));
232 // We should have been told we can download.
233 ExpectAndResetCounts(1, 0, 0, __LINE__);
235 // Ask again. This triggers asking the delegate for allow/disallow.
236 testing_action_ = ACCEPT;
237 CanDownload();
238 // This should ask us if the download is allowed.
239 // We should have been told we can download.
240 ExpectAndResetCounts(1, 0, 1, __LINE__);
241 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
242 download_request_limiter_->GetDownloadStatus(web_contents()));
244 // Ask again and make sure continue is invoked.
245 CanDownload();
246 // The state is at allow_all, which means the delegate shouldn't be asked.
247 // We should have been told we can download.
248 ExpectAndResetCounts(1, 0, 0, __LINE__);
249 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
250 download_request_limiter_->GetDownloadStatus(web_contents()));
253 TEST_F(DownloadRequestLimiterTest,
254 DownloadRequestLimiter_ResetOnNavigation) {
255 NavigateAndCommit(GURL("http://foo.com/bar"));
257 // Do two downloads, allowing the second so that we end up with allow all.
258 CanDownload();
259 ExpectAndResetCounts(1, 0, 0, __LINE__);
260 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
261 download_request_limiter_->GetDownloadStatus(web_contents()));
263 testing_action_ = ACCEPT;
264 CanDownload();
265 ExpectAndResetCounts(1, 0, 1, __LINE__);
266 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
267 download_request_limiter_->GetDownloadStatus(web_contents()));
269 // Navigate to a new URL with the same host, which shouldn't reset the allow
270 // all state.
271 NavigateAndCommit(GURL("http://foo.com/bar2"));
272 CanDownload();
273 ExpectAndResetCounts(1, 0, 0, __LINE__);
274 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
275 download_request_limiter_->GetDownloadStatus(web_contents()));
277 // Do a user gesture, because we're at allow all, this shouldn't change the
278 // state.
279 OnUserGesture();
280 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
281 download_request_limiter_->GetDownloadStatus(web_contents()));
283 // Navigate to a completely different host, which should reset the state.
284 NavigateAndCommit(GURL("http://fooey.com"));
285 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
286 download_request_limiter_->GetDownloadStatus(web_contents()));
288 // Do two downloads, allowing the second so that we end up with allow all.
289 CanDownload();
290 ExpectAndResetCounts(1, 0, 0, __LINE__);
291 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
292 download_request_limiter_->GetDownloadStatus(web_contents()));
294 testing_action_ = CANCEL;
295 CanDownload();
296 ExpectAndResetCounts(0, 1, 1, __LINE__);
297 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
298 download_request_limiter_->GetDownloadStatus(web_contents()));
300 // Navigate to a new URL with the same host, which shouldn't reset the allow
301 // all state.
302 NavigateAndCommit(GURL("http://fooey.com/bar2"));
303 CanDownload();
304 ExpectAndResetCounts(0, 1, 0, __LINE__);
305 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
306 download_request_limiter_->GetDownloadStatus(web_contents()));
309 TEST_F(DownloadRequestLimiterTest,
310 DownloadRequestLimiter_ResetOnUserGesture) {
311 NavigateAndCommit(GURL("http://foo.com/bar"));
313 // Do one download, which should change to prompt before download.
314 CanDownload();
315 ExpectAndResetCounts(1, 0, 0, __LINE__);
316 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
317 download_request_limiter_->GetDownloadStatus(web_contents()));
319 // Do a user gesture, which should reset back to allow one.
320 OnUserGesture();
321 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
322 download_request_limiter_->GetDownloadStatus(web_contents()));
324 // Ask twice, which triggers calling the delegate. Don't allow the download
325 // so that we end up with not allowed.
326 CanDownload();
327 ExpectAndResetCounts(1, 0, 0, __LINE__);
328 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
329 download_request_limiter_->GetDownloadStatus(web_contents()));
331 testing_action_ = CANCEL;
332 CanDownload();
333 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
334 download_request_limiter_->GetDownloadStatus(web_contents()));
335 ExpectAndResetCounts(0, 1, 1, __LINE__);
337 // A user gesture now should NOT change the state.
338 OnUserGesture();
339 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
340 download_request_limiter_->GetDownloadStatus(web_contents()));
341 // And make sure we really can't download.
342 CanDownload();
343 ExpectAndResetCounts(0, 1, 0, __LINE__);
344 // And the state shouldn't have changed.
345 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
346 download_request_limiter_->GetDownloadStatus(web_contents()));
349 TEST_F(DownloadRequestLimiterTest,
350 DownloadRequestLimiter_ResetOnReload) {
351 NavigateAndCommit(GURL("http://foo.com/bar"));
352 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
353 download_request_limiter_->GetDownloadStatus(web_contents()));
355 // If the user refreshes the page without responding to the infobar, pretend
356 // like the refresh is the initial load: they get 1 free download (probably
357 // the same as the actual initial load), then an infobar.
358 testing_action_ = WAIT;
360 CanDownload();
361 ExpectAndResetCounts(1, 0, 0, __LINE__);
362 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
363 download_request_limiter_->GetDownloadStatus(web_contents()));
365 CanDownload();
366 ExpectAndResetCounts(0, 0, 1, __LINE__);
367 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
368 download_request_limiter_->GetDownloadStatus(web_contents()));
370 AboutToNavigateRenderView();
371 base::RunLoop().RunUntilIdle();
372 ExpectAndResetCounts(0, 1, 0, __LINE__);
373 ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
374 download_request_limiter_->GetDownloadStatus(web_contents()));
376 CanDownload();
377 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
378 download_request_limiter_->GetDownloadStatus(web_contents()));
379 ExpectAndResetCounts(1, 0, 0, __LINE__);
381 testing_action_ = CANCEL;
382 CanDownload();
383 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
384 download_request_limiter_->GetDownloadStatus(web_contents()));
385 ExpectAndResetCounts(0, 1, 1, __LINE__);
387 AboutToNavigateRenderView();
388 base::RunLoop().RunUntilIdle();
389 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
390 download_request_limiter_->GetDownloadStatus(web_contents()));
391 CanDownload();
392 ExpectAndResetCounts(0, 1, 0, __LINE__);
393 ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
394 download_request_limiter_->GetDownloadStatus(web_contents()));
397 TEST_F(DownloadRequestLimiterTest,
398 DownloadRequestLimiter_RawWebContents) {
399 scoped_ptr<WebContents> web_contents(CreateTestWebContents());
401 // DownloadRequestLimiter won't try to make a permission bubble if there's
402 // no permission bubble manager, so don't put one on the test WebContents.
404 // DownloadRequestLimiter won't try to make an infobar if it doesn't have an
405 // InfoBarService, and we want to test that it will Cancel() instead of
406 // prompting when it doesn't have a InfoBarService, so unset the delegate.
407 UnsetDelegate();
408 ExpectAndResetCounts(0, 0, 0, __LINE__);
409 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
410 download_request_limiter_->GetDownloadStatus(web_contents.get()));
411 // You get one freebie.
412 CanDownloadFor(web_contents.get());
413 ExpectAndResetCounts(1, 0, 0, __LINE__);
414 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
415 download_request_limiter_->GetDownloadStatus(web_contents.get()));
416 OnUserGestureFor(web_contents.get());
417 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
418 download_request_limiter_->GetDownloadStatus(web_contents.get()));
419 CanDownloadFor(web_contents.get());
420 ExpectAndResetCounts(1, 0, 0, __LINE__);
421 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
422 download_request_limiter_->GetDownloadStatus(web_contents.get()));
423 CanDownloadFor(web_contents.get());
424 ExpectAndResetCounts(0, 1, 0, __LINE__);
425 EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
426 download_request_limiter_->GetDownloadStatus(web_contents.get()));
427 OnUserGestureFor(web_contents.get());
428 EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
429 download_request_limiter_->GetDownloadStatus(web_contents.get()));
430 CanDownloadFor(web_contents.get());
431 ExpectAndResetCounts(1, 0, 0, __LINE__);
432 EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
433 download_request_limiter_->GetDownloadStatus(web_contents.get()));
436 TEST_F(DownloadRequestLimiterTest,
437 DownloadRequestLimiter_SetHostContentSetting) {
438 NavigateAndCommit(GURL("http://foo.com/bar"));
439 SetHostContentSetting(web_contents(), CONTENT_SETTING_ALLOW);
441 CanDownload();
442 ExpectAndResetCounts(1, 0, 0, __LINE__);
443 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
444 download_request_limiter_->GetDownloadStatus(web_contents()));
446 CanDownload();
447 ExpectAndResetCounts(1, 0, 0, __LINE__);
448 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
449 download_request_limiter_->GetDownloadStatus(web_contents()));
451 SetHostContentSetting(web_contents(), CONTENT_SETTING_BLOCK);
453 CanDownload();
454 ExpectAndResetCounts(0, 1, 0, __LINE__);
455 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
456 download_request_limiter_->GetDownloadStatus(web_contents()));
458 CanDownload();
459 ExpectAndResetCounts(0, 1, 0, __LINE__);
460 ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
461 download_request_limiter_->GetDownloadStatus(web_contents()));