• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <list>
6 
7 #include "base/prefs/pref_service.h"
8 #include "base/run_loop.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/safe_browsing/malware_details.h"
11 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
12 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
13 #include "chrome/browser/safe_browsing/ui_manager.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
16 #include "content/public/browser/interstitial_page.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/web_contents_tester.h"
21 
22 using content::InterstitialPage;
23 using content::NavigationEntry;
24 using content::WebContents;
25 using content::WebContentsTester;
26 
27 static const char* kGoogleURL = "http://www.google.com/";
28 static const char* kGoodURL = "http://www.goodguys.com/";
29 static const char* kBadURL = "http://www.badguys.com/";
30 static const char* kBadURL2 = "http://www.badguys2.com/";
31 static const char* kBadURL3 = "http://www.badguys3.com/";
32 
33 namespace {
34 
35 // A SafeBrowingBlockingPage class that does not create windows.
36 class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage {
37  public:
TestSafeBrowsingBlockingPage(SafeBrowsingUIManager * manager,WebContents * web_contents,const UnsafeResourceList & unsafe_resources)38   TestSafeBrowsingBlockingPage(SafeBrowsingUIManager* manager,
39                                  WebContents* web_contents,
40                                  const UnsafeResourceList& unsafe_resources)
41       : SafeBrowsingBlockingPage(manager, web_contents, unsafe_resources) {
42     // Don't delay details at all for the unittest.
43     malware_details_proceed_delay_ms_ = 0;
44     DontCreateViewForTesting();
45   }
46 };
47 
48 class TestSafeBrowsingUIManager: public SafeBrowsingUIManager {
49  public:
TestSafeBrowsingUIManager(SafeBrowsingService * service)50   explicit TestSafeBrowsingUIManager(SafeBrowsingService* service)
51       : SafeBrowsingUIManager(service) {
52   }
53 
SendSerializedMalwareDetails(const std::string & serialized)54   virtual void SendSerializedMalwareDetails(
55       const std::string& serialized) OVERRIDE {
56     details_.push_back(serialized);
57   }
58 
GetDetails()59   std::list<std::string>* GetDetails() {
60     return &details_;
61   }
62 
63  private:
~TestSafeBrowsingUIManager()64   virtual ~TestSafeBrowsingUIManager() {}
65 
66   std::list<std::string> details_;
67 };
68 
69 class TestSafeBrowsingBlockingPageFactory
70     : public SafeBrowsingBlockingPageFactory {
71  public:
TestSafeBrowsingBlockingPageFactory()72   TestSafeBrowsingBlockingPageFactory() { }
~TestSafeBrowsingBlockingPageFactory()73   virtual ~TestSafeBrowsingBlockingPageFactory() { }
74 
CreateSafeBrowsingPage(SafeBrowsingUIManager * manager,WebContents * web_contents,const SafeBrowsingBlockingPage::UnsafeResourceList & unsafe_resources)75   virtual SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
76       SafeBrowsingUIManager* manager,
77       WebContents* web_contents,
78       const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
79       OVERRIDE {
80     return new TestSafeBrowsingBlockingPage(manager, web_contents,
81                                               unsafe_resources);
82   }
83 };
84 
85 }  // namespace
86 
87 class SafeBrowsingBlockingPageTest : public ChromeRenderViewHostTestHarness {
88  public:
89   // The decision the user made.
90   enum UserResponse {
91     PENDING,
92     OK,
93     CANCEL
94   };
95 
SafeBrowsingBlockingPageTest()96   SafeBrowsingBlockingPageTest() {
97     ResetUserResponse();
98     // The safe browsing UI manager does not need a service for this test.
99     ui_manager_ = new TestSafeBrowsingUIManager(NULL);
100   }
101 
SetUp()102   virtual void SetUp() OVERRIDE {
103     ChromeRenderViewHostTestHarness::SetUp();
104     SafeBrowsingBlockingPage::RegisterFactory(&factory_);
105     ResetUserResponse();
106   }
107 
TearDown()108   virtual void TearDown() OVERRIDE {
109     // Release the UI manager before the BrowserThreads are destroyed.
110     ui_manager_ = NULL;
111     SafeBrowsingBlockingPage::RegisterFactory(NULL);
112     // Clean up singleton reference (crbug.com/110594).
113     MalwareDetails::RegisterFactory(NULL);
114     ChromeRenderViewHostTestHarness::TearDown();
115   }
116 
OnBlockingPageComplete(bool proceed)117   void OnBlockingPageComplete(bool proceed) {
118     if (proceed)
119       user_response_ = OK;
120     else
121       user_response_ = CANCEL;
122   }
123 
Navigate(const char * url,int page_id)124   void Navigate(const char* url, int page_id) {
125     WebContentsTester::For(web_contents())->TestDidNavigate(
126         web_contents()->GetMainFrame(), page_id, GURL(url),
127         ui::PAGE_TRANSITION_TYPED);
128   }
129 
GoBack(bool is_cross_site)130   void GoBack(bool is_cross_site) {
131     NavigationEntry* entry =
132         web_contents()->GetController().GetEntryAtOffset(-1);
133     ASSERT_TRUE(entry);
134     web_contents()->GetController().GoBack();
135 
136     // The pending RVH should commit for cross-site navigations.
137     content::RenderFrameHost* rfh = is_cross_site ?
138         WebContentsTester::For(web_contents())->GetPendingMainFrame() :
139         web_contents()->GetMainFrame();
140     WebContentsTester::For(web_contents())->TestDidNavigate(
141         rfh,
142         entry->GetPageID(),
143         GURL(entry->GetURL()),
144         ui::PAGE_TRANSITION_TYPED);
145   }
146 
ShowInterstitial(bool is_subresource,const char * url)147   void ShowInterstitial(bool is_subresource, const char* url) {
148     SafeBrowsingUIManager::UnsafeResource resource;
149     InitResource(&resource, is_subresource, GURL(url));
150     SafeBrowsingBlockingPage::ShowBlockingPage(ui_manager_.get(), resource);
151   }
152 
153   // Returns the SafeBrowsingBlockingPage currently showing or NULL if none is
154   // showing.
GetSafeBrowsingBlockingPage()155   SafeBrowsingBlockingPage* GetSafeBrowsingBlockingPage() {
156     InterstitialPage* interstitial =
157         InterstitialPage::GetInterstitialPage(web_contents());
158     if (!interstitial)
159       return NULL;
160     return  static_cast<SafeBrowsingBlockingPage*>(
161         interstitial->GetDelegateForTesting());
162   }
163 
user_response() const164   UserResponse user_response() const { return user_response_; }
ResetUserResponse()165   void ResetUserResponse() { user_response_ = PENDING; }
166 
ProceedThroughInterstitial(SafeBrowsingBlockingPage * sb_interstitial)167   static void ProceedThroughInterstitial(
168       SafeBrowsingBlockingPage* sb_interstitial) {
169     sb_interstitial->interstitial_page_->Proceed();
170     // Proceed() posts a task to update the SafeBrowsingService::Client.
171     base::RunLoop().RunUntilIdle();
172   }
173 
DontProceedThroughInterstitial(SafeBrowsingBlockingPage * sb_interstitial)174   static void DontProceedThroughInterstitial(
175       SafeBrowsingBlockingPage* sb_interstitial) {
176     sb_interstitial->interstitial_page_->DontProceed();
177     // DontProceed() posts a task to update the SafeBrowsingService::Client.
178     base::RunLoop().RunUntilIdle();
179   }
180 
DontProceedThroughSubresourceInterstitial(SafeBrowsingBlockingPage * sb_interstitial)181   void DontProceedThroughSubresourceInterstitial(
182       SafeBrowsingBlockingPage* sb_interstitial) {
183     // CommandReceived(kTakeMeBackCommand) does a back navigation for
184     // subresource interstitials.
185     GoBack(false);
186     // DontProceed() posts a task to update the SafeBrowsingService::Client.
187     base::RunLoop().RunUntilIdle();
188   }
189 
190   scoped_refptr<TestSafeBrowsingUIManager> ui_manager_;
191 
192  private:
InitResource(SafeBrowsingUIManager::UnsafeResource * resource,bool is_subresource,const GURL & url)193   void InitResource(SafeBrowsingUIManager::UnsafeResource* resource,
194                     bool is_subresource,
195                     const GURL& url) {
196     resource->callback =
197         base::Bind(&SafeBrowsingBlockingPageTest::OnBlockingPageComplete,
198                    base::Unretained(this));
199     resource->url = url;
200     resource->is_subresource = is_subresource;
201     resource->threat_type = SB_THREAT_TYPE_URL_MALWARE;
202     resource->render_process_host_id =
203         web_contents()->GetRenderProcessHost()->GetID();
204     resource->render_view_id =
205         web_contents()->GetRenderViewHost()->GetRoutingID();
206   }
207 
208   UserResponse user_response_;
209   TestSafeBrowsingBlockingPageFactory factory_;
210 };
211 
212 
213 // Tests showing a blocking page for a malware page and not proceeding.
TEST_F(SafeBrowsingBlockingPageTest,MalwarePageDontProceed)214 TEST_F(SafeBrowsingBlockingPageTest, MalwarePageDontProceed) {
215   // Enable malware details.
216   Profile* profile = Profile::FromBrowserContext(
217       web_contents()->GetBrowserContext());
218   profile->GetPrefs()->SetBoolean(
219       prefs::kSafeBrowsingExtendedReportingEnabled, true);
220 
221   // Start a load.
222   controller().LoadURL(GURL(kBadURL), content::Referrer(),
223                        ui::PAGE_TRANSITION_TYPED, std::string());
224 
225 
226   // Simulate the load causing a safe browsing interstitial to be shown.
227   ShowInterstitial(false, kBadURL);
228   SafeBrowsingBlockingPage* sb_interstitial =
229       GetSafeBrowsingBlockingPage();
230   ASSERT_TRUE(sb_interstitial);
231 
232   base::RunLoop().RunUntilIdle();
233 
234   // Simulate the user clicking "don't proceed".
235   DontProceedThroughInterstitial(sb_interstitial);
236 
237   // The interstitial should be gone.
238   EXPECT_EQ(CANCEL, user_response());
239   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
240 
241   // We did not proceed, the pending entry should be gone.
242   EXPECT_FALSE(controller().GetPendingEntry());
243 
244   // A report should have been sent.
245   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
246   ui_manager_->GetDetails()->clear();
247 }
248 
249 // Tests showing a blocking page for a malware page and then proceeding.
TEST_F(SafeBrowsingBlockingPageTest,MalwarePageProceed)250 TEST_F(SafeBrowsingBlockingPageTest, MalwarePageProceed) {
251   // Enable malware reports.
252   Profile* profile = Profile::FromBrowserContext(
253       web_contents()->GetBrowserContext());
254   profile->GetPrefs()->SetBoolean(
255       prefs::kSafeBrowsingExtendedReportingEnabled, true);
256 
257   // Start a load.
258   controller().LoadURL(GURL(kBadURL), content::Referrer(),
259                        ui::PAGE_TRANSITION_TYPED, std::string());
260 
261   // Simulate the load causing a safe browsing interstitial to be shown.
262   ShowInterstitial(false, kBadURL);
263   SafeBrowsingBlockingPage* sb_interstitial =
264       GetSafeBrowsingBlockingPage();
265   ASSERT_TRUE(sb_interstitial);
266 
267   // Simulate the user clicking "proceed".
268   ProceedThroughInterstitial(sb_interstitial);
269 
270   // The interstitial is shown until the navigation commits.
271   ASSERT_TRUE(InterstitialPage::GetInterstitialPage(web_contents()));
272   // Commit the navigation.
273   Navigate(kBadURL, 1);
274   // The interstitial should be gone now.
275   ASSERT_FALSE(InterstitialPage::GetInterstitialPage(web_contents()));
276 
277   // A report should have been sent.
278   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
279   ui_manager_->GetDetails()->clear();
280 }
281 
282 // Tests showing a blocking page for a page that contains malware subresources
283 // and not proceeding.
TEST_F(SafeBrowsingBlockingPageTest,PageWithMalwareResourceDontProceed)284 TEST_F(SafeBrowsingBlockingPageTest, PageWithMalwareResourceDontProceed) {
285   // Enable malware reports.
286   Profile* profile = Profile::FromBrowserContext(
287       web_contents()->GetBrowserContext());
288   profile->GetPrefs()->SetBoolean(
289       prefs::kSafeBrowsingExtendedReportingEnabled, true);
290 
291   // Navigate somewhere.
292   Navigate(kGoogleURL, 1);
293 
294   // Navigate somewhere else.
295   Navigate(kGoodURL, 2);
296 
297   // Simulate that page loading a bad-resource triggering an interstitial.
298   ShowInterstitial(true, kBadURL);
299 
300   SafeBrowsingBlockingPage* sb_interstitial =
301       GetSafeBrowsingBlockingPage();
302   ASSERT_TRUE(sb_interstitial);
303 
304   // Simulate the user clicking "don't proceed".
305   DontProceedThroughSubresourceInterstitial(sb_interstitial);
306   EXPECT_EQ(CANCEL, user_response());
307   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
308 
309   // We did not proceed, we should be back to the first page, the 2nd one should
310   // have been removed from the navigation controller.
311   ASSERT_EQ(1, controller().GetEntryCount());
312   EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec());
313 
314   // A report should have been sent.
315   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
316   ui_manager_->GetDetails()->clear();
317 }
318 
319 // Tests showing a blocking page for a page that contains malware subresources
320 // and proceeding.
TEST_F(SafeBrowsingBlockingPageTest,PageWithMalwareResourceProceed)321 TEST_F(SafeBrowsingBlockingPageTest, PageWithMalwareResourceProceed) {
322   // Enable malware reports.
323   Profile* profile = Profile::FromBrowserContext(
324       web_contents()->GetBrowserContext());
325   profile->GetPrefs()->SetBoolean(
326       prefs::kSafeBrowsingExtendedReportingEnabled, true);
327 
328   // Navigate somewhere.
329   Navigate(kGoodURL, 1);
330 
331   // Simulate that page loading a bad-resource triggering an interstitial.
332   ShowInterstitial(true, kBadURL);
333 
334   SafeBrowsingBlockingPage* sb_interstitial =
335       GetSafeBrowsingBlockingPage();
336   ASSERT_TRUE(sb_interstitial);
337 
338   // Simulate the user clicking "proceed".
339   ProceedThroughInterstitial(sb_interstitial);
340   EXPECT_EQ(OK, user_response());
341   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
342 
343   // We did proceed, we should be back to showing the page.
344   ASSERT_EQ(1, controller().GetEntryCount());
345   EXPECT_EQ(kGoodURL, controller().GetActiveEntry()->GetURL().spec());
346 
347   // A report should have been sent.
348   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
349   ui_manager_->GetDetails()->clear();
350 }
351 
352 // Tests showing a blocking page for a page that contains multiple malware
353 // subresources and not proceeding.  This just tests that the extra malware
354 // subresources (which trigger queued interstitial pages) do not break anything.
TEST_F(SafeBrowsingBlockingPageTest,PageWithMultipleMalwareResourceDontProceed)355 TEST_F(SafeBrowsingBlockingPageTest,
356        PageWithMultipleMalwareResourceDontProceed) {
357   // Enable malware reports.
358   Profile* profile = Profile::FromBrowserContext(
359       web_contents()->GetBrowserContext());
360   profile->GetPrefs()->SetBoolean(
361       prefs::kSafeBrowsingExtendedReportingEnabled, true);
362 
363   // Navigate somewhere.
364   Navigate(kGoogleURL, 1);
365 
366   // Navigate somewhere else.
367   Navigate(kGoodURL, 2);
368 
369   // Simulate that page loading a bad-resource triggering an interstitial.
370   ShowInterstitial(true, kBadURL);
371 
372   // More bad resources loading causing more interstitials. The new
373   // interstitials should be queued.
374   ShowInterstitial(true, kBadURL2);
375   ShowInterstitial(true, kBadURL3);
376 
377   SafeBrowsingBlockingPage* sb_interstitial =
378       GetSafeBrowsingBlockingPage();
379   ASSERT_TRUE(sb_interstitial);
380 
381   // Simulate the user clicking "don't proceed".
382   DontProceedThroughSubresourceInterstitial(sb_interstitial);
383   EXPECT_EQ(CANCEL, user_response());
384   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
385 
386   // We did not proceed, we should be back to the first page, the 2nd one should
387   // have been removed from the navigation controller.
388   ASSERT_EQ(1, controller().GetEntryCount());
389   EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec());
390 
391   // A report should have been sent.
392   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
393   ui_manager_->GetDetails()->clear();
394 }
395 
396 // Tests showing a blocking page for a page that contains multiple malware
397 // subresources and proceeding through the first interstitial, but not the next.
TEST_F(SafeBrowsingBlockingPageTest,PageWithMultipleMalwareResourceProceedThenDontProceed)398 TEST_F(SafeBrowsingBlockingPageTest,
399        PageWithMultipleMalwareResourceProceedThenDontProceed) {
400   // Enable malware reports.
401   Profile* profile = Profile::FromBrowserContext(
402       web_contents()->GetBrowserContext());
403   profile->GetPrefs()->SetBoolean(
404       prefs::kSafeBrowsingExtendedReportingEnabled, true);
405 
406   // Navigate somewhere.
407   Navigate(kGoogleURL, 1);
408 
409   // Navigate somewhere else.
410   Navigate(kGoodURL, 2);
411 
412   // Simulate that page loading a bad-resource triggering an interstitial.
413   ShowInterstitial(true, kBadURL);
414 
415   // More bad resources loading causing more interstitials. The new
416   // interstitials should be queued.
417   ShowInterstitial(true, kBadURL2);
418   ShowInterstitial(true, kBadURL3);
419 
420   SafeBrowsingBlockingPage* sb_interstitial =
421       GetSafeBrowsingBlockingPage();
422   ASSERT_TRUE(sb_interstitial);
423 
424   // Proceed through the 1st interstitial.
425   ProceedThroughInterstitial(sb_interstitial);
426   EXPECT_EQ(OK, user_response());
427 
428   // A report should have been sent.
429   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
430   ui_manager_->GetDetails()->clear();
431 
432   ResetUserResponse();
433 
434   // We should land to a 2nd interstitial (aggregating all the malware resources
435   // loaded while the 1st interstitial was showing).
436   sb_interstitial = GetSafeBrowsingBlockingPage();
437   ASSERT_TRUE(sb_interstitial);
438 
439   // Don't proceed through the 2nd interstitial.
440   DontProceedThroughSubresourceInterstitial(sb_interstitial);
441   EXPECT_EQ(CANCEL, user_response());
442   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
443 
444   // We did not proceed, we should be back to the first page, the 2nd one should
445   // have been removed from the navigation controller.
446   ASSERT_EQ(1, controller().GetEntryCount());
447   EXPECT_EQ(kGoogleURL, controller().GetActiveEntry()->GetURL().spec());
448 
449   // No report should have been sent -- we don't create a report the
450   // second time.
451   EXPECT_EQ(0u, ui_manager_->GetDetails()->size());
452   ui_manager_->GetDetails()->clear();
453 }
454 
455 // Tests showing a blocking page for a page that contains multiple malware
456 // subresources and proceeding through the multiple interstitials.
TEST_F(SafeBrowsingBlockingPageTest,PageWithMultipleMalwareResourceProceed)457 TEST_F(SafeBrowsingBlockingPageTest,
458     PageWithMultipleMalwareResourceProceed) {
459   // Enable malware reports.
460   Profile* profile = Profile::FromBrowserContext(
461       web_contents()->GetBrowserContext());
462   profile->GetPrefs()->SetBoolean(
463       prefs::kSafeBrowsingExtendedReportingEnabled, true);
464 
465   // Navigate somewhere else.
466   Navigate(kGoodURL, 1);
467 
468   // Simulate that page loading a bad-resource triggering an interstitial.
469   ShowInterstitial(true, kBadURL);
470 
471   // More bad resources loading causing more interstitials. The new
472   // interstitials should be queued.
473   ShowInterstitial(true, kBadURL2);
474   ShowInterstitial(true, kBadURL3);
475 
476   SafeBrowsingBlockingPage* sb_interstitial =
477       GetSafeBrowsingBlockingPage();
478   ASSERT_TRUE(sb_interstitial);
479 
480   // Proceed through the 1st interstitial.
481   ProceedThroughInterstitial(sb_interstitial);
482   EXPECT_EQ(OK, user_response());
483 
484   // A report should have been sent.
485   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
486   ui_manager_->GetDetails()->clear();
487 
488   ResetUserResponse();
489 
490   // We should land to a 2nd interstitial (aggregating all the malware resources
491   // loaded while the 1st interstitial was showing).
492   sb_interstitial = GetSafeBrowsingBlockingPage();
493   ASSERT_TRUE(sb_interstitial);
494 
495   // Proceed through the 2nd interstitial.
496   ProceedThroughInterstitial(sb_interstitial);
497   EXPECT_EQ(OK, user_response());
498 
499   // We did proceed, we should be back to the initial page.
500   ASSERT_EQ(1, controller().GetEntryCount());
501   EXPECT_EQ(kGoodURL, controller().GetActiveEntry()->GetURL().spec());
502 
503   // No report should have been sent -- we don't create a report the
504   // second time.
505   EXPECT_EQ(0u, ui_manager_->GetDetails()->size());
506   ui_manager_->GetDetails()->clear();
507 }
508 
509 // Tests showing a blocking page then navigating back and forth to make sure the
510 // controller entries are OK.  http://crbug.com/17627
TEST_F(SafeBrowsingBlockingPageTest,NavigatingBackAndForth)511 TEST_F(SafeBrowsingBlockingPageTest, NavigatingBackAndForth) {
512   // Enable malware reports.
513   Profile* profile = Profile::FromBrowserContext(
514       web_contents()->GetBrowserContext());
515   profile->GetPrefs()->SetBoolean(
516       prefs::kSafeBrowsingExtendedReportingEnabled, true);
517 
518   // Navigate somewhere.
519   Navigate(kGoodURL, 1);
520 
521   // Now navigate to a bad page triggerring an interstitial.
522   controller().LoadURL(GURL(kBadURL), content::Referrer(),
523                        ui::PAGE_TRANSITION_TYPED, std::string());
524   ShowInterstitial(false, kBadURL);
525   SafeBrowsingBlockingPage* sb_interstitial =
526       GetSafeBrowsingBlockingPage();
527   ASSERT_TRUE(sb_interstitial);
528 
529   // Proceed, then navigate back.
530   ProceedThroughInterstitial(sb_interstitial);
531   Navigate(kBadURL, 2);  // Commit the navigation.
532   GoBack(true);
533 
534   // We are back on the good page.
535   sb_interstitial = GetSafeBrowsingBlockingPage();
536   ASSERT_FALSE(sb_interstitial);
537   ASSERT_EQ(2, controller().GetEntryCount());
538   EXPECT_EQ(kGoodURL, controller().GetActiveEntry()->GetURL().spec());
539 
540   // Navigate forward to the malware URL.
541   web_contents()->GetController().GoForward();
542   ShowInterstitial(false, kBadURL);
543   sb_interstitial = GetSafeBrowsingBlockingPage();
544   ASSERT_TRUE(sb_interstitial);
545 
546   // Let's proceed and make sure everything is OK (bug 17627).
547   ProceedThroughInterstitial(sb_interstitial);
548   Navigate(kBadURL, 2);  // Commit the navigation.
549   sb_interstitial = GetSafeBrowsingBlockingPage();
550   ASSERT_FALSE(sb_interstitial);
551   ASSERT_EQ(2, controller().GetEntryCount());
552   EXPECT_EQ(kBadURL, controller().GetActiveEntry()->GetURL().spec());
553 
554   // Two reports should have been sent.
555   EXPECT_EQ(2u, ui_manager_->GetDetails()->size());
556   ui_manager_->GetDetails()->clear();
557 }
558 
559 // Tests that calling "don't proceed" after "proceed" has been called doesn't
560 // cause problems. http://crbug.com/30079
TEST_F(SafeBrowsingBlockingPageTest,ProceedThenDontProceed)561 TEST_F(SafeBrowsingBlockingPageTest, ProceedThenDontProceed) {
562   // Enable malware reports.
563   Profile* profile = Profile::FromBrowserContext(
564       web_contents()->GetBrowserContext());
565   profile->GetPrefs()->SetBoolean(
566       prefs::kSafeBrowsingExtendedReportingEnabled, true);
567 
568   // Start a load.
569   controller().LoadURL(GURL(kBadURL), content::Referrer(),
570                        ui::PAGE_TRANSITION_TYPED, std::string());
571 
572   // Simulate the load causing a safe browsing interstitial to be shown.
573   ShowInterstitial(false, kBadURL);
574   SafeBrowsingBlockingPage* sb_interstitial =
575       GetSafeBrowsingBlockingPage();
576   ASSERT_TRUE(sb_interstitial);
577 
578   base::RunLoop().RunUntilIdle();
579 
580   // Simulate the user clicking "proceed" then "don't proceed" (before the
581   // interstitial is shown).
582   sb_interstitial->interstitial_page_->Proceed();
583   sb_interstitial->interstitial_page_->DontProceed();
584   // Proceed() and DontProceed() post a task to update the
585   // SafeBrowsingService::Client.
586   base::RunLoop().RunUntilIdle();
587 
588   // The interstitial should be gone.
589   EXPECT_EQ(OK, user_response());
590   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
591 
592   // Only one report should have been sent.
593   EXPECT_EQ(1u, ui_manager_->GetDetails()->size());
594   ui_manager_->GetDetails()->clear();
595 }
596 
597 // Tests showing a blocking page for a malware page with reports disabled.
TEST_F(SafeBrowsingBlockingPageTest,MalwareReportsDisabled)598 TEST_F(SafeBrowsingBlockingPageTest, MalwareReportsDisabled) {
599   // Disable malware reports.
600   Profile* profile = Profile::FromBrowserContext(
601       web_contents()->GetBrowserContext());
602   profile->GetPrefs()->SetBoolean(
603       prefs::kSafeBrowsingExtendedReportingEnabled, false);
604 
605   // Start a load.
606   controller().LoadURL(GURL(kBadURL), content::Referrer(),
607                        ui::PAGE_TRANSITION_TYPED, std::string());
608 
609   // Simulate the load causing a safe browsing interstitial to be shown.
610   ShowInterstitial(false, kBadURL);
611   SafeBrowsingBlockingPage* sb_interstitial =
612       GetSafeBrowsingBlockingPage();
613   ASSERT_TRUE(sb_interstitial);
614 
615   base::RunLoop().RunUntilIdle();
616 
617   // Simulate the user clicking "don't proceed".
618   DontProceedThroughInterstitial(sb_interstitial);
619 
620   // The interstitial should be gone.
621   EXPECT_EQ(CANCEL, user_response());
622   EXPECT_FALSE(GetSafeBrowsingBlockingPage());
623 
624   // We did not proceed, the pending entry should be gone.
625   EXPECT_FALSE(controller().GetPendingEntry());
626 
627   // No report should have been sent.
628   EXPECT_EQ(0u, ui_manager_->GetDetails()->size());
629   ui_manager_->GetDetails()->clear();
630 }
631 
632 // Test that toggling the checkbox has the anticipated effects.
TEST_F(SafeBrowsingBlockingPageTest,MalwareReportsToggling)633 TEST_F(SafeBrowsingBlockingPageTest, MalwareReportsToggling) {
634   // Disable malware reports.
635   Profile* profile = Profile::FromBrowserContext(
636       web_contents()->GetBrowserContext());
637   profile->GetPrefs()->SetBoolean(
638       prefs::kSafeBrowsingExtendedReportingEnabled, false);
639 
640   // Start a load.
641   controller().LoadURL(GURL(kBadURL), content::Referrer(),
642                        ui::PAGE_TRANSITION_TYPED, std::string());
643 
644   // Simulate the load causing a safe browsing interstitial to be shown.
645   ShowInterstitial(false, kBadURL);
646   SafeBrowsingBlockingPage* sb_interstitial =
647       GetSafeBrowsingBlockingPage();
648   ASSERT_TRUE(sb_interstitial);
649 
650   base::RunLoop().RunUntilIdle();
651 
652   EXPECT_FALSE(profile->GetPrefs()->GetBoolean(
653       prefs::kSafeBrowsingExtendedReportingEnabled));
654 
655   // Simulate the user check the report agreement checkbox.
656   sb_interstitial->SetReportingPreference(true);
657 
658   EXPECT_TRUE(profile->GetPrefs()->GetBoolean(
659       prefs::kSafeBrowsingExtendedReportingEnabled));
660 
661   // Simulate the user uncheck the report agreement checkbox.
662   sb_interstitial->SetReportingPreference(false);
663 
664   EXPECT_FALSE(profile->GetPrefs()->GetBoolean(
665       prefs::kSafeBrowsingExtendedReportingEnabled));
666 }
667