Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / download / download_request_limiter_unittest.cc
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.
4
5 #include "chrome/browser/download/download_request_limiter.h"
6
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"
18
19 using content::WebContents;
20
21 class DownloadRequestLimiterTest;
22
23 class FakePermissionBubbleView : public PermissionBubbleView {
24  public:
25   explicit FakePermissionBubbleView(DownloadRequestLimiterTest *test)
26       : test_(test), delegate_(NULL) {}
27
28   virtual ~FakePermissionBubbleView() {
29     if (delegate_)
30       delegate_->SetView(NULL);
31   }
32
33   void Close() {
34     if (delegate_)
35       delegate_->Closing();
36   }
37
38   // PermissionBubbleView:
39   virtual void SetDelegate(Delegate* delegate) OVERRIDE {
40     delegate_ = delegate;
41   }
42
43   virtual void Show(
44       const std::vector<PermissionBubbleRequest*>& requests,
45       const std::vector<bool>& accept_state,
46       bool customization_mode) OVERRIDE;
47
48   virtual bool CanAcceptRequestUpdate() OVERRIDE { return false; }
49
50   virtual void Hide() OVERRIDE {}
51   virtual bool IsVisible() OVERRIDE { return false; }
52
53  private:
54   DownloadRequestLimiterTest* test_;
55   Delegate* delegate_;
56 };
57
58 class DownloadRequestLimiterTest : public ChromeRenderViewHostTestHarness {
59  public:
60   enum TestingAction {
61     ACCEPT,
62     CANCEL,
63     WAIT
64   };
65
66   virtual void SetUp() {
67     ChromeRenderViewHostTestHarness::SetUp();
68     InfoBarService::CreateForWebContents(web_contents());
69
70     PermissionBubbleManager::CreateForWebContents(web_contents());
71     view_.reset(new FakePermissionBubbleView(this));
72     PermissionBubbleManager* manager =
73       PermissionBubbleManager::FromWebContents(web_contents());
74     manager->SetView(view_.get());
75
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());
86   }
87
88   int GetAction() {
89     return testing_action_;
90   }
91
92   void AskAllow() {
93     ask_allow_count_++;
94   }
95
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;
109     }
110   }
111
112   virtual void TearDown() {
113     content_settings_->ShutdownOnUIThread();
114     content_settings_ = NULL;
115     UnsetDelegate();
116     ChromeRenderViewHostTestHarness::TearDown();
117   }
118
119   virtual void UnsetDelegate() {
120     DownloadRequestInfoBarDelegate::SetCallbackForTesting(NULL);
121   }
122
123   void CanDownload() {
124     CanDownloadFor(web_contents());
125   }
126
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();
134   }
135
136   void OnUserGesture() {
137     OnUserGestureFor(web_contents());
138   }
139
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();
145   }
146
147   void AboutToNavigateRenderView() {
148     view_->Close();
149     DownloadRequestLimiter::TabDownloadState* state =
150         download_request_limiter_->GetDownloadState(
151             web_contents(), NULL, false);
152     state->AboutToNavigateRenderView(NULL);
153   }
154
155   void ExpectAndResetCounts(
156       int expect_continues,
157       int expect_cancels,
158       int expect_asks,
159       int line) {
160     EXPECT_EQ(expect_continues, continue_count_) << "line " << line;
161     EXPECT_EQ(expect_cancels, cancel_count_) << "line " << line;
162     EXPECT_EQ(expect_asks, ask_allow_count_) << "line " << line;
163     continue_count_ = cancel_count_ = ask_allow_count_ = 0;
164   }
165
166  protected:
167   void ContinueDownload(bool allow) {
168     if (allow) {
169       continue_count_++;
170     } else {
171       cancel_count_++;
172     }
173   }
174
175   void SetHostContentSetting(WebContents* contents, ContentSetting setting) {
176     content_settings_->SetContentSetting(
177         ContentSettingsPattern::FromURL(contents->GetURL()),
178         ContentSettingsPattern::Wildcard(),
179         CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS,
180         std::string(),
181         setting);
182   }
183
184   scoped_refptr<DownloadRequestLimiter> download_request_limiter_;
185
186   // The action that FakeCreate() should take.
187   TestingAction testing_action_;
188
189   // Number of times ContinueDownload was invoked.
190   int continue_count_;
191
192   // Number of times CancelDownload was invoked.
193   int cancel_count_;
194
195   // Number of times ShouldAllowDownload was invoked.
196   int ask_allow_count_;
197
198   scoped_refptr<HostContentSettingsMap> content_settings_;
199
200  private:
201   DownloadRequestInfoBarDelegate::FakeCreateCallback fake_create_callback_;
202   TestingProfile profile_;
203   scoped_ptr<FakePermissionBubbleView> view_;
204 };
205
206 void FakePermissionBubbleView::Show(
207     const std::vector<PermissionBubbleRequest*>& requests,
208     const std::vector<bool>& accept_state,
209     bool customization_mode) {
210   test_->AskAllow();
211   int action = test_->GetAction();
212   if (action == DownloadRequestLimiterTest::ACCEPT) {
213     delegate_->Accept();
214   } else if (action == DownloadRequestLimiterTest::CANCEL) {
215     delegate_->Deny();
216   } else if (action == DownloadRequestLimiterTest::WAIT) {
217     // do nothing.
218   } else {
219     delegate_->Closing();
220   }
221 }
222
223 TEST_F(DownloadRequestLimiterTest,
224        DownloadRequestLimiter_Allow) {
225   // All tabs should initially start at ALLOW_ONE_DOWNLOAD.
226   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
227             download_request_limiter_->GetDownloadStatus(web_contents()));
228
229   // Ask if the tab can do a download. This moves to PROMPT_BEFORE_DOWNLOAD.
230   CanDownload();
231   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
232             download_request_limiter_->GetDownloadStatus(web_contents()));
233   // We should have been told we can download.
234   ExpectAndResetCounts(1, 0, 0, __LINE__);
235
236   // Ask again. This triggers asking the delegate for allow/disallow.
237   testing_action_ = ACCEPT;
238   CanDownload();
239   // This should ask us if the download is allowed.
240   // We should have been told we can download.
241   ExpectAndResetCounts(1, 0, 1, __LINE__);
242   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
243             download_request_limiter_->GetDownloadStatus(web_contents()));
244
245   // Ask again and make sure continue is invoked.
246   CanDownload();
247   // The state is at allow_all, which means the delegate shouldn't be asked.
248   // We should have been told we can download.
249   ExpectAndResetCounts(1, 0, 0, __LINE__);
250   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
251             download_request_limiter_->GetDownloadStatus(web_contents()));
252 }
253
254 TEST_F(DownloadRequestLimiterTest,
255        DownloadRequestLimiter_ResetOnNavigation) {
256   NavigateAndCommit(GURL("http://foo.com/bar"));
257
258   // Do two downloads, allowing the second so that we end up with allow all.
259   CanDownload();
260   ExpectAndResetCounts(1, 0, 0, __LINE__);
261   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
262             download_request_limiter_->GetDownloadStatus(web_contents()));
263
264   testing_action_ = ACCEPT;
265   CanDownload();
266   ExpectAndResetCounts(1, 0, 1, __LINE__);
267   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
268             download_request_limiter_->GetDownloadStatus(web_contents()));
269
270   // Navigate to a new URL with the same host, which shouldn't reset the allow
271   // all state.
272   NavigateAndCommit(GURL("http://foo.com/bar2"));
273   CanDownload();
274   ExpectAndResetCounts(1, 0, 0, __LINE__);
275   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
276             download_request_limiter_->GetDownloadStatus(web_contents()));
277
278   // Do a user gesture, because we're at allow all, this shouldn't change the
279   // state.
280   OnUserGesture();
281   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ALL_DOWNLOADS,
282             download_request_limiter_->GetDownloadStatus(web_contents()));
283
284   // Navigate to a completely different host, which should reset the state.
285   NavigateAndCommit(GURL("http://fooey.com"));
286   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
287             download_request_limiter_->GetDownloadStatus(web_contents()));
288
289   // Do two downloads, allowing the second so that we end up with allow all.
290   CanDownload();
291   ExpectAndResetCounts(1, 0, 0, __LINE__);
292   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
293             download_request_limiter_->GetDownloadStatus(web_contents()));
294
295   testing_action_ = CANCEL;
296   CanDownload();
297   ExpectAndResetCounts(0, 1, 1, __LINE__);
298   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
299             download_request_limiter_->GetDownloadStatus(web_contents()));
300
301   // Navigate to a new URL with the same host, which shouldn't reset the allow
302   // all state.
303   NavigateAndCommit(GURL("http://fooey.com/bar2"));
304   CanDownload();
305   ExpectAndResetCounts(0, 1, 0, __LINE__);
306   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
307             download_request_limiter_->GetDownloadStatus(web_contents()));
308 }
309
310 TEST_F(DownloadRequestLimiterTest,
311        DownloadRequestLimiter_ResetOnUserGesture) {
312   NavigateAndCommit(GURL("http://foo.com/bar"));
313
314   // Do one download, which should change to prompt before download.
315   CanDownload();
316   ExpectAndResetCounts(1, 0, 0, __LINE__);
317   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
318             download_request_limiter_->GetDownloadStatus(web_contents()));
319
320   // Do a user gesture, which should reset back to allow one.
321   OnUserGesture();
322   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
323             download_request_limiter_->GetDownloadStatus(web_contents()));
324
325   // Ask twice, which triggers calling the delegate. Don't allow the download
326   // so that we end up with not allowed.
327   CanDownload();
328   ExpectAndResetCounts(1, 0, 0, __LINE__);
329   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
330             download_request_limiter_->GetDownloadStatus(web_contents()));
331
332   testing_action_ = CANCEL;
333   CanDownload();
334   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
335             download_request_limiter_->GetDownloadStatus(web_contents()));
336   ExpectAndResetCounts(0, 1, 1, __LINE__);
337
338   // A user gesture now should NOT change the state.
339   OnUserGesture();
340   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
341             download_request_limiter_->GetDownloadStatus(web_contents()));
342   // And make sure we really can't download.
343   CanDownload();
344   ExpectAndResetCounts(0, 1, 0, __LINE__);
345   // And the state shouldn't have changed.
346   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
347             download_request_limiter_->GetDownloadStatus(web_contents()));
348 }
349
350 TEST_F(DownloadRequestLimiterTest,
351        DownloadRequestLimiter_ResetOnReload) {
352   NavigateAndCommit(GURL("http://foo.com/bar"));
353   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
354             download_request_limiter_->GetDownloadStatus(web_contents()));
355
356   // If the user refreshes the page without responding to the infobar, pretend
357   // like the refresh is the initial load: they get 1 free download (probably
358   // the same as the actual initial load), then an infobar.
359   testing_action_ = WAIT;
360
361   CanDownload();
362   ExpectAndResetCounts(1, 0, 0, __LINE__);
363   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
364             download_request_limiter_->GetDownloadStatus(web_contents()));
365
366   CanDownload();
367   ExpectAndResetCounts(0, 0, 1, __LINE__);
368   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
369             download_request_limiter_->GetDownloadStatus(web_contents()));
370
371   AboutToNavigateRenderView();
372   base::RunLoop().RunUntilIdle();
373   ExpectAndResetCounts(0, 1, 0, __LINE__);
374   ASSERT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
375             download_request_limiter_->GetDownloadStatus(web_contents()));
376
377   CanDownload();
378   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
379             download_request_limiter_->GetDownloadStatus(web_contents()));
380   ExpectAndResetCounts(1, 0, 0, __LINE__);
381
382   testing_action_ = CANCEL;
383   CanDownload();
384   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
385             download_request_limiter_->GetDownloadStatus(web_contents()));
386   ExpectAndResetCounts(0, 1, 1, __LINE__);
387
388   AboutToNavigateRenderView();
389   base::RunLoop().RunUntilIdle();
390   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
391             download_request_limiter_->GetDownloadStatus(web_contents()));
392   CanDownload();
393   ExpectAndResetCounts(0, 1, 0, __LINE__);
394   ASSERT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
395             download_request_limiter_->GetDownloadStatus(web_contents()));
396 }
397
398 TEST_F(DownloadRequestLimiterTest,
399        DownloadRequestLimiter_RawWebContents) {
400   scoped_ptr<WebContents> web_contents(CreateTestWebContents());
401
402   // DownloadRequestLimiter won't try to make a permission bubble if there's
403   // no permission bubble manager, so don't put one on the test WebContents.
404
405   // DownloadRequestLimiter won't try to make an infobar if it doesn't have an
406   // InfoBarService, and we want to test that it will Cancel() instead of
407   // prompting when it doesn't have a InfoBarService, so unset the delegate.
408   UnsetDelegate();
409   ExpectAndResetCounts(0, 0, 0, __LINE__);
410   EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
411             download_request_limiter_->GetDownloadStatus(web_contents.get()));
412   // You get one freebie.
413   CanDownloadFor(web_contents.get());
414   ExpectAndResetCounts(1, 0, 0, __LINE__);
415   EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
416             download_request_limiter_->GetDownloadStatus(web_contents.get()));
417   OnUserGestureFor(web_contents.get());
418   EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
419             download_request_limiter_->GetDownloadStatus(web_contents.get()));
420   CanDownloadFor(web_contents.get());
421   ExpectAndResetCounts(1, 0, 0, __LINE__);
422   EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
423             download_request_limiter_->GetDownloadStatus(web_contents.get()));
424   CanDownloadFor(web_contents.get());
425   ExpectAndResetCounts(0, 1, 0, __LINE__);
426   EXPECT_EQ(DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED,
427             download_request_limiter_->GetDownloadStatus(web_contents.get()));
428   OnUserGestureFor(web_contents.get());
429   EXPECT_EQ(DownloadRequestLimiter::ALLOW_ONE_DOWNLOAD,
430             download_request_limiter_->GetDownloadStatus(web_contents.get()));
431   CanDownloadFor(web_contents.get());
432   ExpectAndResetCounts(1, 0, 0, __LINE__);
433   EXPECT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
434             download_request_limiter_->GetDownloadStatus(web_contents.get()));
435 }
436
437 TEST_F(DownloadRequestLimiterTest,
438        DownloadRequestLimiter_SetHostContentSetting) {
439   NavigateAndCommit(GURL("http://foo.com/bar"));
440   SetHostContentSetting(web_contents(), CONTENT_SETTING_ALLOW);
441
442   CanDownload();
443   ExpectAndResetCounts(1, 0, 0, __LINE__);
444   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
445             download_request_limiter_->GetDownloadStatus(web_contents()));
446
447   CanDownload();
448   ExpectAndResetCounts(1, 0, 0, __LINE__);
449   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
450             download_request_limiter_->GetDownloadStatus(web_contents()));
451
452   SetHostContentSetting(web_contents(), CONTENT_SETTING_BLOCK);
453
454   CanDownload();
455   ExpectAndResetCounts(0, 1, 0, __LINE__);
456   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
457             download_request_limiter_->GetDownloadStatus(web_contents()));
458
459   CanDownload();
460   ExpectAndResetCounts(0, 1, 0, __LINE__);
461   ASSERT_EQ(DownloadRequestLimiter::PROMPT_BEFORE_DOWNLOAD,
462             download_request_limiter_->GetDownloadStatus(web_contents()));
463 }