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