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