Remove 'RemoveTrailingSeparators' function from SimpleMenuModel
[chromium-blink-merge.git] / chrome / browser / safe_browsing / safe_browsing_blocking_page_test.cc
blob280196647a4b252ee2c1be5d85eedc6ba8cc026e
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 // This test creates a fake safebrowsing service, where we can inject known-
6 // threat urls. It then uses a real browser to go to these urls, and sends
7 // "goback" or "proceed" commands and verifies they work.
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/interstitials/security_interstitial_page_test_utils.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/safe_browsing/database_manager.h"
19 #include "chrome/browser/safe_browsing/malware_details.h"
20 #include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h"
21 #include "chrome/browser/safe_browsing/safe_browsing_service.h"
22 #include "chrome/browser/safe_browsing/safe_browsing_util.h"
23 #include "chrome/browser/safe_browsing/ui_manager.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_tabstrip.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/common/url_constants.h"
30 #include "chrome/test/base/in_process_browser_test.h"
31 #include "chrome/test/base/test_switches.h"
32 #include "chrome/test/base/ui_test_utils.h"
33 #include "content/public/browser/interstitial_page.h"
34 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/notification_types.h"
36 #include "content/public/browser/render_frame_host.h"
37 #include "content/public/browser/render_process_host.h"
38 #include "content/public/browser/render_view_host.h"
39 #include "content/public/browser/web_contents.h"
40 #include "content/public/test/browser_test_utils.h"
41 #include "content/public/test/test_browser_thread.h"
42 #include "content/public/test/test_utils.h"
44 using chrome_browser_interstitials::SecurityInterstitialIDNTest;
45 using content::BrowserThread;
46 using content::InterstitialPage;
47 using content::NavigationController;
48 using content::WebContents;
50 namespace {
52 const char kEmptyPage[] = "files/empty.html";
53 const char kMalwarePage[] = "files/safe_browsing/malware.html";
54 const char kMalwareIframe[] = "files/safe_browsing/malware_iframe.html";
56 // A SafeBrowsingDatabaseManager class that allows us to inject the malicious
57 // URLs.
58 class FakeSafeBrowsingDatabaseManager : public SafeBrowsingDatabaseManager {
59 public:
60 explicit FakeSafeBrowsingDatabaseManager(SafeBrowsingService* service)
61 : SafeBrowsingDatabaseManager(service) { }
63 // Called on the IO thread to check if the given url is safe or not. If we
64 // can synchronously determine that the url is safe, CheckUrl returns true.
65 // Otherwise it returns false, and "client" is called asynchronously with the
66 // result when it is ready.
67 // Overrides SafeBrowsingDatabaseManager::CheckBrowseUrl.
68 bool CheckBrowseUrl(const GURL& gurl, Client* client) override {
69 if (badurls[gurl.spec()] == SB_THREAT_TYPE_SAFE)
70 return true;
72 BrowserThread::PostTask(
73 BrowserThread::IO, FROM_HERE,
74 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone,
75 this, gurl, client));
76 return false;
79 void OnCheckBrowseURLDone(const GURL& gurl, Client* client) {
80 std::vector<SBThreatType> expected_threats;
81 expected_threats.push_back(SB_THREAT_TYPE_URL_MALWARE);
82 expected_threats.push_back(SB_THREAT_TYPE_URL_PHISHING);
83 expected_threats.push_back(SB_THREAT_TYPE_URL_UNWANTED);
84 SafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
85 std::vector<GURL>(1, gurl),
86 std::vector<SBFullHash>(),
87 client,
88 safe_browsing_util::MALWARE,
89 expected_threats);
90 sb_check.url_results[0] = badurls[gurl.spec()];
91 client->OnSafeBrowsingResult(sb_check);
94 void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
95 badurls[url.spec()] = threat_type;
98 private:
99 ~FakeSafeBrowsingDatabaseManager() override {}
101 base::hash_map<std::string, SBThreatType> badurls;
102 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingDatabaseManager);
105 // A SafeBrowingUIManager class that allows intercepting malware details.
106 class FakeSafeBrowsingUIManager : public SafeBrowsingUIManager {
107 public:
108 explicit FakeSafeBrowsingUIManager(SafeBrowsingService* service) :
109 SafeBrowsingUIManager(service) { }
111 // Overrides SafeBrowsingUIManager
112 void SendSerializedMalwareDetails(const std::string& serialized) override {
113 // Notify the UI thread that we got a report.
114 BrowserThread::PostTask(
115 BrowserThread::UI,
116 FROM_HERE,
117 base::Bind(&FakeSafeBrowsingUIManager::OnMalwareDetailsDone,
118 this,
119 serialized));
122 void OnMalwareDetailsDone(const std::string& serialized) {
123 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 report_ = serialized;
126 EXPECT_FALSE(malware_details_done_callback_.is_null());
127 if (!malware_details_done_callback_.is_null()) {
128 malware_details_done_callback_.Run();
129 malware_details_done_callback_ = base::Closure();
133 void set_malware_details_done_callback(const base::Closure& callback) {
134 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
135 EXPECT_TRUE(malware_details_done_callback_.is_null());
136 malware_details_done_callback_ = callback;
139 std::string GetReport() {
140 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::UI));
141 return report_;
144 protected:
145 ~FakeSafeBrowsingUIManager() override {}
147 private:
148 std::string report_;
149 base::Closure malware_details_done_callback_;
151 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingUIManager);
154 class FakeSafeBrowsingService : public SafeBrowsingService {
155 public:
156 FakeSafeBrowsingService()
157 : fake_database_manager_(),
158 fake_ui_manager_() { }
160 // Returned pointer has the same lifespan as the database_manager_ refcounted
161 // object.
162 FakeSafeBrowsingDatabaseManager* fake_database_manager() {
163 return fake_database_manager_;
165 // Returned pointer has the same lifespan as the ui_manager_ refcounted
166 // object.
167 FakeSafeBrowsingUIManager* fake_ui_manager() {
168 return fake_ui_manager_;
171 protected:
172 ~FakeSafeBrowsingService() override {}
174 SafeBrowsingDatabaseManager* CreateDatabaseManager() override {
175 fake_database_manager_ = new FakeSafeBrowsingDatabaseManager(this);
176 return fake_database_manager_;
179 SafeBrowsingUIManager* CreateUIManager() override {
180 fake_ui_manager_ = new FakeSafeBrowsingUIManager(this);
181 return fake_ui_manager_;
184 private:
185 FakeSafeBrowsingDatabaseManager* fake_database_manager_;
186 FakeSafeBrowsingUIManager* fake_ui_manager_;
188 DISALLOW_COPY_AND_ASSIGN(FakeSafeBrowsingService);
191 // Factory that creates FakeSafeBrowsingService instances.
192 class TestSafeBrowsingServiceFactory : public SafeBrowsingServiceFactory {
193 public:
194 TestSafeBrowsingServiceFactory() :
195 most_recent_service_(NULL) { }
196 ~TestSafeBrowsingServiceFactory() override {}
198 SafeBrowsingService* CreateSafeBrowsingService() override {
199 most_recent_service_ = new FakeSafeBrowsingService();
200 return most_recent_service_;
203 FakeSafeBrowsingService* most_recent_service() const {
204 return most_recent_service_;
207 private:
208 FakeSafeBrowsingService* most_recent_service_;
211 // A MalwareDetails class lets us intercept calls from the renderer.
212 class FakeMalwareDetails : public MalwareDetails {
213 public:
214 FakeMalwareDetails(
215 SafeBrowsingUIManager* delegate,
216 WebContents* web_contents,
217 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource)
218 : MalwareDetails(delegate, web_contents, unsafe_resource),
219 got_dom_(false),
220 waiting_(false) { }
222 void AddDOMDetails(
223 const std::vector<SafeBrowsingHostMsg_MalwareDOMDetails_Node>& params)
224 override {
225 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
226 MalwareDetails::AddDOMDetails(params);
228 // Notify the UI thread that we got the dom details.
229 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
230 base::Bind(&FakeMalwareDetails::OnDOMDetailsDone,
231 this));
234 void WaitForDOM() {
235 if (got_dom_) {
236 return;
238 // This condition might not trigger normally, but if you add a
239 // sleep(1) in malware_dom_details it triggers :).
240 waiting_ = true;
241 content::RunMessageLoop();
242 EXPECT_TRUE(got_dom_);
245 private:
246 ~FakeMalwareDetails() override {}
248 void OnDOMDetailsDone() {
249 got_dom_ = true;
250 if (waiting_) {
251 base::MessageLoopForUI::current()->Quit();
255 // Some logic to figure out if we should wait for the dom details or not.
256 // These variables should only be accessed in the UI thread.
257 bool got_dom_;
258 bool waiting_;
261 class TestMalwareDetailsFactory : public MalwareDetailsFactory {
262 public:
263 TestMalwareDetailsFactory() : details_() { }
264 ~TestMalwareDetailsFactory() override {}
266 MalwareDetails* CreateMalwareDetails(
267 SafeBrowsingUIManager* delegate,
268 WebContents* web_contents,
269 const SafeBrowsingUIManager::UnsafeResource& unsafe_resource) override {
270 details_ = new FakeMalwareDetails(delegate, web_contents,
271 unsafe_resource);
272 return details_;
275 FakeMalwareDetails* get_details() {
276 return details_;
279 private:
280 FakeMalwareDetails* details_;
283 // A SafeBrowingBlockingPage class that lets us wait until it's hidden.
284 class TestSafeBrowsingBlockingPage : public SafeBrowsingBlockingPage {
285 public:
286 TestSafeBrowsingBlockingPage(SafeBrowsingUIManager* manager,
287 WebContents* web_contents,
288 const UnsafeResourceList& unsafe_resources)
289 : SafeBrowsingBlockingPage(manager, web_contents, unsafe_resources),
290 wait_for_delete_(false) {
291 // Don't wait the whole 3 seconds for the browser test.
292 malware_details_proceed_delay_ms_ = 100;
295 ~TestSafeBrowsingBlockingPage() override {
296 if (!wait_for_delete_)
297 return;
299 // Notify that we are gone
300 base::MessageLoopForUI::current()->Quit();
301 wait_for_delete_ = false;
304 void WaitForDelete() {
305 wait_for_delete_ = true;
306 content::RunMessageLoop();
309 // InterstitialPageDelegate methods:
310 void CommandReceived(const std::string& command) override {
311 SafeBrowsingBlockingPage::CommandReceived(command);
313 void OnProceed() override { SafeBrowsingBlockingPage::OnProceed(); }
314 void OnDontProceed() override { SafeBrowsingBlockingPage::OnDontProceed(); }
316 private:
317 bool wait_for_delete_;
320 class TestSafeBrowsingBlockingPageFactory
321 : public SafeBrowsingBlockingPageFactory {
322 public:
323 TestSafeBrowsingBlockingPageFactory() { }
324 ~TestSafeBrowsingBlockingPageFactory() override {}
326 SafeBrowsingBlockingPage* CreateSafeBrowsingPage(
327 SafeBrowsingUIManager* delegate,
328 WebContents* web_contents,
329 const SafeBrowsingBlockingPage::UnsafeResourceList& unsafe_resources)
330 override {
331 return new TestSafeBrowsingBlockingPage(delegate, web_contents,
332 unsafe_resources);
336 } // namespace
338 // Tests the safe browsing blocking page in a browser.
339 class SafeBrowsingBlockingPageBrowserTest
340 : public InProcessBrowserTest,
341 public testing::WithParamInterface<SBThreatType> {
342 public:
343 enum Visibility {
344 VISIBILITY_ERROR = -1,
345 HIDDEN = 0,
346 VISIBLE = 1
349 SafeBrowsingBlockingPageBrowserTest() {}
351 void SetUp() override {
352 SafeBrowsingService::RegisterFactory(&factory_);
353 SafeBrowsingBlockingPage::RegisterFactory(&blocking_page_factory_);
354 MalwareDetails::RegisterFactory(&details_factory_);
355 InProcessBrowserTest::SetUp();
358 void SetUpCommandLine(base::CommandLine* command_line) override {
359 command_line->AppendSwitchASCII(
360 switches::kForceFieldTrials, "UwSInterstitialStatus/On/");
363 void TearDown() override {
364 InProcessBrowserTest::TearDown();
365 SafeBrowsingBlockingPage::RegisterFactory(NULL);
366 SafeBrowsingService::RegisterFactory(NULL);
367 MalwareDetails::RegisterFactory(NULL);
370 void SetUpInProcessBrowserTestFixture() override {
371 ASSERT_TRUE(test_server()->Start());
374 void SetURLThreatType(const GURL& url, SBThreatType threat_type) {
375 FakeSafeBrowsingService* service =
376 static_cast<FakeSafeBrowsingService*>(
377 g_browser_process->safe_browsing_service());
379 ASSERT_TRUE(service);
380 service->fake_database_manager()->SetURLThreatType(url, threat_type);
383 // Adds a safebrowsing result of the current test threat to the fake
384 // safebrowsing service, navigates to that page, and returns the url.
385 GURL SetupWarningAndNavigate() {
386 GURL url = test_server()->GetURL(kEmptyPage);
387 SetURLThreatType(url, GetParam());
389 ui_test_utils::NavigateToURL(browser(), url);
390 EXPECT_TRUE(WaitForReady());
391 return url;
394 // Adds a safebrowsing threat result to the fake safebrowsing service,
395 // navigates to a page with an iframe containing the threat site, and returns
396 // the url of the parent page.
397 GURL SetupThreatIframeWarningAndNavigate() {
398 GURL url = test_server()->GetURL(kMalwarePage);
399 GURL iframe_url = test_server()->GetURL(kMalwareIframe);
400 SetURLThreatType(iframe_url, GetParam());
402 ui_test_utils::NavigateToURL(browser(), url);
403 EXPECT_TRUE(WaitForReady());
404 return url;
407 void SendCommand(
408 SecurityInterstitialPage::SecurityInterstitialCommands command) {
409 WebContents* contents =
410 browser()->tab_strip_model()->GetActiveWebContents();
411 // We use InterstitialPage::GetInterstitialPage(tab) instead of
412 // tab->GetInterstitialPage() because the tab doesn't have a pointer
413 // to its interstital page until it gets a command from the renderer
414 // that it has indeed displayed it -- and this sometimes happens after
415 // NavigateToURL returns.
416 SafeBrowsingBlockingPage* interstitial_page =
417 static_cast<SafeBrowsingBlockingPage*>(
418 InterstitialPage::GetInterstitialPage(contents)->
419 GetDelegateForTesting());
420 ASSERT_TRUE(interstitial_page);
421 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting,
422 interstitial_page->GetTypeForTesting());
423 interstitial_page->CommandReceived(base::IntToString(command));
426 void DontProceedThroughInterstitial() {
427 WebContents* contents =
428 browser()->tab_strip_model()->GetActiveWebContents();
429 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
430 contents);
431 ASSERT_TRUE(interstitial_page);
432 interstitial_page->DontProceed();
435 void ProceedThroughInterstitial() {
436 WebContents* contents =
437 browser()->tab_strip_model()->GetActiveWebContents();
438 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
439 contents);
440 ASSERT_TRUE(interstitial_page);
441 interstitial_page->Proceed();
444 void AssertNoInterstitial(bool wait_for_delete) {
445 WebContents* contents =
446 browser()->tab_strip_model()->GetActiveWebContents();
448 if (contents->ShowingInterstitialPage() && wait_for_delete) {
449 // We'll get notified when the interstitial is deleted.
450 TestSafeBrowsingBlockingPage* page =
451 static_cast<TestSafeBrowsingBlockingPage*>(
452 contents->GetInterstitialPage()->GetDelegateForTesting());
453 ASSERT_EQ(SafeBrowsingBlockingPage::kTypeForTesting,
454 page->GetTypeForTesting());
455 page->WaitForDelete();
458 // Can't use InterstitialPage::GetInterstitialPage() because that
459 // gets updated after the TestSafeBrowsingBlockingPage destructor
460 ASSERT_FALSE(contents->ShowingInterstitialPage());
463 bool YesInterstitial() {
464 WebContents* contents =
465 browser()->tab_strip_model()->GetActiveWebContents();
466 InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage(
467 contents);
468 return interstitial_page != NULL;
471 void SetReportSentCallback(const base::Closure& callback) {
472 factory_.most_recent_service()
473 ->fake_ui_manager()
474 ->set_malware_details_done_callback(callback);
477 std::string GetReportSent() {
478 return factory_.most_recent_service()->fake_ui_manager()->GetReport();
481 void MalwareRedirectCancelAndProceed(const std::string& open_function) {
482 GURL load_url = test_server()->GetURL(
483 "files/safe_browsing/interstitial_cancel.html");
484 GURL malware_url("http://localhost/files/safe_browsing/malware.html");
485 SetURLThreatType(malware_url, GetParam());
487 // Load the test page.
488 ui_test_utils::NavigateToURL(browser(), load_url);
489 // Trigger the safe browsing interstitial page via a redirect in
490 // "openWin()".
491 ui_test_utils::NavigateToURLWithDisposition(
492 browser(),
493 GURL("javascript:" + open_function + "()"),
494 CURRENT_TAB,
495 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
496 WebContents* contents =
497 browser()->tab_strip_model()->GetActiveWebContents();
498 content::WaitForInterstitialAttach(contents);
499 // Cancel the redirect request while interstitial page is open.
500 browser()->tab_strip_model()->ActivateTabAt(0, true);
501 ui_test_utils::NavigateToURL(browser(), GURL("javascript:stopWin()"));
502 browser()->tab_strip_model()->ActivateTabAt(1, true);
503 // Simulate the user clicking "proceed", there should be no crash. Since
504 // clicking proceed may do nothing (see comment in RedirectCanceled
505 // below, and crbug.com/76460), we use SendCommand to trigger the callback
506 // directly rather than using ClickAndWaitForDetach since there might not
507 // be a notification to wait for.
508 SendCommand(SecurityInterstitialPage::CMD_PROCEED);
511 content::RenderViewHost* GetRenderViewHost() {
512 InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage(
513 browser()->tab_strip_model()->GetActiveWebContents());
514 if (!interstitial)
515 return NULL;
516 return interstitial->GetMainFrame()->GetRenderViewHost();
519 bool WaitForReady() {
520 InterstitialPage* interstitial = InterstitialPage::GetInterstitialPage(
521 browser()->tab_strip_model()->GetActiveWebContents());
522 if (!interstitial)
523 return false;
524 return content::WaitForRenderFrameReady(interstitial->GetMainFrame());
527 Visibility GetVisibility(const std::string& node_id) {
528 content::RenderViewHost* rvh = GetRenderViewHost();
529 if (!rvh)
530 return VISIBILITY_ERROR;
531 scoped_ptr<base::Value> value = content::ExecuteScriptAndGetValue(
532 rvh->GetMainFrame(),
533 "var node = document.getElementById('" + node_id + "');\n"
534 "if (node)\n"
535 " node.offsetWidth > 0 && node.offsetHeight > 0;"
536 "else\n"
537 " 'node not found';\n");
538 if (!value.get())
539 return VISIBILITY_ERROR;
540 bool result = false;
541 if (!value->GetAsBoolean(&result))
542 return VISIBILITY_ERROR;
543 return result ? VISIBLE : HIDDEN;
546 bool Click(const std::string& node_id) {
547 content::RenderViewHost* rvh = GetRenderViewHost();
548 if (!rvh)
549 return false;
550 // We don't use ExecuteScriptAndGetValue for this one, since clicking
551 // the button/link may navigate away before the injected javascript can
552 // reply, hanging the test.
553 rvh->GetMainFrame()->ExecuteJavaScript(
554 base::ASCIIToUTF16(
555 "document.getElementById('" + node_id + "').click();\n"));
556 return true;
559 bool ClickAndWaitForDetach(const std::string& node_id) {
560 // We wait for interstitial_detached rather than nav_entry_committed, as
561 // going back from a main-frame malware interstitial page will not cause a
562 // nav entry committed event.
563 if (!Click(node_id))
564 return false;
565 content::WaitForInterstitialDetach(
566 browser()->tab_strip_model()->GetActiveWebContents());
567 return true;
570 void TestReportingDisabledAndDontProceed(const GURL& url) {
571 SetURLThreatType(url, GetParam());
572 ui_test_utils::NavigateToURL(browser(), url);
573 ASSERT_TRUE(WaitForReady());
575 EXPECT_EQ(HIDDEN, GetVisibility("extended-reporting-opt-in"));
576 EXPECT_EQ(HIDDEN, GetVisibility("opt-in-checkbox"));
577 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
578 EXPECT_TRUE(Click("details-button"));
579 EXPECT_EQ(VISIBLE, GetVisibility("help-link"));
580 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
582 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
583 AssertNoInterstitial(false); // Assert the interstitial is gone
584 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
585 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
588 protected:
589 TestMalwareDetailsFactory details_factory_;
591 private:
592 TestSafeBrowsingServiceFactory factory_;
593 TestSafeBrowsingBlockingPageFactory blocking_page_factory_;
595 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingBlockingPageBrowserTest);
598 // TODO(linux_aura) http://crbug.com/163931
599 // TODO(win_aura) http://crbug.com/154081
600 #if defined(USE_AURA) && !defined(OS_CHROMEOS)
601 #define MAYBE_RedirectInIFrameCanceled DISABLED_RedirectInIFrameCanceled
602 #else
603 #define MAYBE_RedirectInIFrameCanceled RedirectInIFrameCanceled
604 #endif
605 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
606 MAYBE_RedirectInIFrameCanceled) {
607 // 1. Test the case that redirect is a subresource.
608 MalwareRedirectCancelAndProceed("openWinIFrame");
609 // If the redirect was from subresource but canceled, "proceed" will continue
610 // with the rest of resources.
611 AssertNoInterstitial(true);
614 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, RedirectCanceled) {
615 // 2. Test the case that redirect is the only resource.
616 MalwareRedirectCancelAndProceed("openWin");
617 // Clicking proceed won't do anything if the main request is cancelled
618 // already. See crbug.com/76460.
619 EXPECT_TRUE(YesInterstitial());
622 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, DontProceed) {
623 #if defined(OS_WIN) && defined(USE_ASH)
624 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
625 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
626 switches::kAshBrowserTests))
627 return;
628 #endif
630 SetupWarningAndNavigate();
632 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
633 EXPECT_EQ(HIDDEN, GetVisibility("details"));
634 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
635 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
636 EXPECT_TRUE(Click("details-button"));
637 EXPECT_EQ(VISIBLE, GetVisibility("details"));
638 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
639 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
640 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
642 AssertNoInterstitial(false); // Assert the interstitial is gone
643 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
644 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
647 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, Proceed) {
648 GURL url = SetupWarningAndNavigate();
650 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
651 AssertNoInterstitial(true); // Assert the interstitial is gone.
652 EXPECT_EQ(url,
653 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
656 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, IframeDontProceed) {
657 #if defined(OS_WIN) && defined(USE_ASH)
658 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
659 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
660 switches::kAshBrowserTests))
661 return;
662 #endif
664 SetupThreatIframeWarningAndNavigate();
666 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
667 EXPECT_EQ(HIDDEN, GetVisibility("details"));
668 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
669 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
670 EXPECT_TRUE(Click("details-button"));
671 EXPECT_EQ(VISIBLE, GetVisibility("details"));
672 EXPECT_EQ(VISIBLE, GetVisibility("proceed-link"));
673 EXPECT_EQ(HIDDEN, GetVisibility("error-code"));
674 EXPECT_TRUE(ClickAndWaitForDetach("primary-button"));
676 AssertNoInterstitial(false); // Assert the interstitial is gone
678 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
679 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
682 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, IframeProceed) {
683 GURL url = SetupThreatIframeWarningAndNavigate();
685 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
686 AssertNoInterstitial(true); // Assert the interstitial is gone
688 EXPECT_EQ(url,
689 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
692 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
693 IframeOptInAndReportMalwareDetails) {
694 // The extended reporting opt-in is presented in the interstitial for malware,
695 // phishing, and UwS threats. It however only results in uploading further
696 // details about the immediate threat when facing malware threats.
697 const bool expect_malware_details = GetParam() == SB_THREAT_TYPE_URL_MALWARE;
699 scoped_refptr<content::MessageLoopRunner> malware_report_sent_runner(
700 new content::MessageLoopRunner);
701 if (expect_malware_details)
702 SetReportSentCallback(malware_report_sent_runner->QuitClosure());
704 GURL url = SetupThreatIframeWarningAndNavigate();
706 FakeMalwareDetails* fake_malware_details = details_factory_.get_details();
707 EXPECT_EQ(expect_malware_details, fake_malware_details != nullptr);
709 // If the DOM details from renderer did not already return when they are
710 // expected, wait for them.
711 if (expect_malware_details)
712 fake_malware_details->WaitForDOM();
714 EXPECT_EQ(VISIBLE, GetVisibility("extended-reporting-opt-in"));
715 EXPECT_TRUE(Click("opt-in-checkbox"));
716 EXPECT_TRUE(ClickAndWaitForDetach("proceed-link"));
717 AssertNoInterstitial(true); // Assert the interstitial is gone
719 EXPECT_TRUE(browser()->profile()->GetPrefs()->GetBoolean(
720 prefs::kSafeBrowsingExtendedReportingEnabled));
721 EXPECT_EQ(url,
722 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
724 if (expect_malware_details) {
725 malware_report_sent_runner->Run();
726 std::string serialized = GetReportSent();
727 safe_browsing::ClientMalwareReportRequest report;
728 ASSERT_TRUE(report.ParseFromString(serialized));
729 // Verify the report is complete.
730 EXPECT_TRUE(report.complete());
734 // Verifies that the "proceed anyway" link isn't available when it is disabled
735 // by the corresponding policy. Also verifies that sending the "proceed"
736 // command anyway doesn't advance to the malware site.
737 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ProceedDisabled) {
738 #if defined(OS_WIN) && defined(USE_ASH)
739 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
740 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
741 switches::kAshBrowserTests))
742 return;
743 #endif
745 // Simulate a policy disabling the "proceed anyway" link.
746 browser()->profile()->GetPrefs()->SetBoolean(
747 prefs::kSafeBrowsingProceedAnywayDisabled, true);
749 SetupWarningAndNavigate();
751 EXPECT_EQ(VISIBLE, GetVisibility("primary-button"));
752 EXPECT_EQ(HIDDEN, GetVisibility("details"));
753 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
754 EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
755 EXPECT_TRUE(Click("details-button"));
756 EXPECT_EQ(HIDDEN, GetVisibility("proceed-link"));
757 EXPECT_EQ(HIDDEN, GetVisibility("final-paragraph"));
758 SendCommand(SecurityInterstitialPage::CMD_PROCEED);
760 // The "proceed" command should go back instead, if proceeding is disabled.
761 AssertNoInterstitial(true);
762 EXPECT_EQ(GURL(url::kAboutBlankURL), // Back to "about:blank"
763 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
766 // Verifies that the reporting checkbox is hidden on non-HTTP pages.
767 // TODO(mattm): Should also verify that no report is sent, but there isn't a
768 // good way to do that in the current design.
769 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, ReportingDisabled) {
770 #if defined(OS_WIN) && defined(USE_ASH)
771 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
772 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
773 switches::kAshBrowserTests))
774 return;
775 #endif
777 browser()->profile()->GetPrefs()->SetBoolean(
778 prefs::kSafeBrowsingExtendedReportingEnabled, true);
780 net::SpawnedTestServer https_server(
781 net::SpawnedTestServer::TYPE_HTTPS, net::SpawnedTestServer::kLocalhost,
782 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
783 ASSERT_TRUE(https_server.Start());
784 GURL url = https_server.GetURL(kEmptyPage);
786 TestReportingDisabledAndDontProceed(url);
789 // Verifies that the reporting checkbox is hidden when opt-in is
790 // disabled by policy.
791 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest,
792 ReportingDisabledByPolicy) {
793 #if defined(OS_WIN) && defined(USE_ASH)
794 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
795 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
796 switches::kAshBrowserTests))
797 return;
798 #endif
800 browser()->profile()->GetPrefs()->SetBoolean(
801 prefs::kSafeBrowsingExtendedReportingEnabled, true);
802 browser()->profile()->GetPrefs()->SetBoolean(
803 prefs::kSafeBrowsingExtendedReportingOptInAllowed, false);
805 TestReportingDisabledAndDontProceed(test_server()->GetURL(kEmptyPage));
808 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, LearnMore) {
809 SetupWarningAndNavigate();
810 EXPECT_TRUE(ClickAndWaitForDetach("help-link"));
811 AssertNoInterstitial(false); // Assert the interstitial is gone
813 // We are in the help page.
814 EXPECT_EQ(
815 GetParam() == SB_THREAT_TYPE_URL_PHISHING
816 ? "/transparencyreport/safebrowsing/"
817 : "/safebrowsing/diagnostic",
818 browser()->tab_strip_model()->GetActiveWebContents()->GetURL().path());
821 INSTANTIATE_TEST_CASE_P(SafeBrowsingBlockingPageBrowserTestWithThreatType,
822 SafeBrowsingBlockingPageBrowserTest,
823 testing::Values(SB_THREAT_TYPE_URL_MALWARE,
824 SB_THREAT_TYPE_URL_PHISHING,
825 SB_THREAT_TYPE_URL_UNWANTED));
827 // Test that SafeBrowsingBlockingPage properly decodes IDN URLs that are
828 // displayed.
829 class SafeBrowsingBlockingPageIDNTest
830 : public SecurityInterstitialIDNTest,
831 public testing::WithParamInterface<SBThreatType> {
832 protected:
833 // SecurityInterstitialIDNTest implementation
834 SecurityInterstitialPage* CreateInterstitial(
835 content::WebContents* contents,
836 const GURL& request_url) const override {
837 SafeBrowsingService* sb_service =
838 g_browser_process->safe_browsing_service();
839 SafeBrowsingBlockingPage::UnsafeResource resource;
841 resource.url = request_url;
842 resource.is_subresource = false;
843 resource.threat_type = GetParam();
844 resource.render_process_host_id = contents->GetRenderProcessHost()->GetID();
845 resource.render_view_id = contents->GetRenderViewHost()->GetRoutingID();
847 return SafeBrowsingBlockingPage::CreateBlockingPage(
848 sb_service->ui_manager().get(), contents, resource);
852 IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageIDNTest,
853 SafeBrowsingBlockingPageDecodesIDN) {
854 EXPECT_TRUE(VerifyIDNDecoded());
857 INSTANTIATE_TEST_CASE_P(SafeBrowsingBlockingPageIDNTestWithThreatType,
858 SafeBrowsingBlockingPageIDNTest,
859 testing::Values(SB_THREAT_TYPE_URL_MALWARE,
860 SB_THREAT_TYPE_URL_PHISHING,
861 SB_THREAT_TYPE_URL_UNWANTED));