Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / renderer / safe_browsing / phishing_classifier_delegate_browsertest.cc
blob8f7f298846a74f3e7a427efc62919226ac107975
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.
5 #include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
7 #include "base/command_line.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/run_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/ui/browser.h"
13 #include "chrome/browser/ui/browser_commands.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "chrome/common/safe_browsing/csd.pb.h"
17 #include "chrome/common/safe_browsing/safebrowsing_messages.h"
18 #include "chrome/renderer/safe_browsing/features.h"
19 #include "chrome/renderer/safe_browsing/phishing_classifier.h"
20 #include "chrome/renderer/safe_browsing/scorer.h"
21 #include "chrome/test/base/in_process_browser_test.h"
22 #include "chrome/test/base/ui_test_utils.h"
23 #include "content/public/browser/browser_message_filter.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/render_process_host.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/renderer/render_view.h"
28 #include "content/public/test/browser_test_utils.h"
29 #include "content/public/test/test_navigation_observer.h"
30 #include "content/public/test/test_utils.h"
31 #include "net/dns/mock_host_resolver.h"
32 #include "net/test/embedded_test_server/embedded_test_server.h"
33 #include "net/test/embedded_test_server/http_request.h"
34 #include "net/test/embedded_test_server/http_response.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "third_party/WebKit/public/platform/WebURL.h"
37 #include "third_party/WebKit/public/platform/WebURLRequest.h"
38 #include "third_party/WebKit/public/web/WebFrame.h"
39 #include "third_party/WebKit/public/web/WebView.h"
40 #include "url/gurl.h"
42 using base::ASCIIToUTF16;
43 using ::testing::_;
44 using ::testing::InSequence;
45 using ::testing::Mock;
46 using ::testing::Pointee;
47 using ::testing::StrictMock;
49 namespace safe_browsing {
51 namespace {
53 // The RenderFrame is routing ID 1, and the RenderView is 2.
54 const int kRenderViewRoutingId = 2;
56 class MockPhishingClassifier : public PhishingClassifier {
57 public:
58 explicit MockPhishingClassifier(content::RenderView* render_view)
59 : PhishingClassifier(render_view, NULL /* clock */) {}
61 virtual ~MockPhishingClassifier() {}
63 MOCK_METHOD2(BeginClassification,
64 void(const base::string16*, const DoneCallback&));
65 MOCK_METHOD0(CancelPendingClassification, void());
67 private:
68 DISALLOW_COPY_AND_ASSIGN(MockPhishingClassifier);
71 class MockScorer : public Scorer {
72 public:
73 MockScorer() : Scorer() {}
74 virtual ~MockScorer() {}
76 MOCK_CONST_METHOD1(ComputeScore, double(const FeatureMap&));
78 private:
79 DISALLOW_COPY_AND_ASSIGN(MockScorer);
82 class InterceptingMessageFilter : public content::BrowserMessageFilter {
83 public:
84 InterceptingMessageFilter()
85 : BrowserMessageFilter(SafeBrowsingMsgStart),
86 waiting_message_loop_(NULL) {
89 const ClientPhishingRequest* verdict() const { return verdict_.get(); }
90 bool OnMessageReceived(const IPC::Message& message) override {
91 bool handled = true;
92 IPC_BEGIN_MESSAGE_MAP(InterceptingMessageFilter, message)
93 IPC_MESSAGE_HANDLER(SafeBrowsingHostMsg_PhishingDetectionDone,
94 OnPhishingDetectionDone)
95 IPC_MESSAGE_UNHANDLED(handled = false);
96 IPC_END_MESSAGE_MAP()
97 return handled;
100 void Reset() {
101 run_loop_.reset(new base::RunLoop());
102 waiting_message_loop_ = base::MessageLoop::current();
103 quit_closure_ = run_loop_->QuitClosure();
106 void RunUntilVerdictReceived() {
107 content::RunThisRunLoop(run_loop_.get());
109 // Clear out the synchronization state just in case.
110 waiting_message_loop_ = NULL;
111 quit_closure_.Reset();
112 run_loop_.reset();
115 void OnPhishingDetectionDone(const std::string& verdict_str) {
116 scoped_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest);
117 if (verdict->ParseFromString(verdict_str) &&
118 verdict->IsInitialized()) {
119 verdict_.swap(verdict);
121 waiting_message_loop_->PostTask(FROM_HERE, quit_closure_);
124 private:
125 ~InterceptingMessageFilter() override {}
127 scoped_ptr<ClientPhishingRequest> verdict_;
128 base::MessageLoop* waiting_message_loop_;
129 base::Closure quit_closure_;
130 scoped_ptr<base::RunLoop> run_loop_;
132 } // namespace
134 class PhishingClassifierDelegateTest : public InProcessBrowserTest {
135 public:
136 void CancelCalled() {
137 if (runner_.get()) {
138 content::BrowserThread::PostTask(
139 content::BrowserThread::UI, FROM_HERE, runner_->QuitClosure());
143 protected:
144 void SetUpCommandLine(base::CommandLine* command_line) override {
145 command_line->AppendSwitch(switches::kSingleProcess);
146 #if defined(OS_WIN)
147 // Don't want to try to create a GPU process.
148 command_line->AppendSwitch(switches::kDisableGpu);
149 #endif
152 void SetUpOnMainThread() override {
153 intercepting_filter_ = new InterceptingMessageFilter();
154 content::RenderView* render_view =
155 content::RenderView::FromRoutingID(kRenderViewRoutingId);
157 GetWebContents()->GetRenderProcessHost()->AddFilter(
158 intercepting_filter_.get());
159 classifier_ = new StrictMock<MockPhishingClassifier>(render_view);
160 delegate_ = PhishingClassifierDelegate::Create(render_view, classifier_);
162 ASSERT_TRUE(StartTestServer());
163 host_resolver()->AddRule("*", "127.0.0.1");
166 // Runs the ClassificationDone callback, then waits for the
167 // PhishingDetectionDone IPC to arrive.
168 void RunClassificationDone(const ClientPhishingRequest& verdict) {
169 // Clear out any previous state.
170 intercepting_filter_->Reset();
171 PostTaskToInProcessRendererAndWait(
172 base::Bind(&PhishingClassifierDelegate::ClassificationDone,
173 base::Unretained(delegate_),
174 verdict));
175 intercepting_filter_->RunUntilVerdictReceived();
178 void OnStartPhishingDetection(const GURL& url) {
179 PostTaskToInProcessRendererAndWait(
180 base::Bind(&PhishingClassifierDelegate::OnStartPhishingDetection,
181 base::Unretained(delegate_), url));
184 void PageCaptured(base::string16* page_text, bool preliminary_capture) {
185 PostTaskToInProcessRendererAndWait(
186 base::Bind(&PhishingClassifierDelegate::PageCaptured,
187 base::Unretained(delegate_), page_text,
188 preliminary_capture));
191 bool StartTestServer() {
192 CHECK(!embedded_test_server_);
193 embedded_test_server_.reset(new net::test_server::EmbeddedTestServer());
194 embedded_test_server_->RegisterRequestHandler(
195 base::Bind(&PhishingClassifierDelegateTest::HandleRequest,
196 base::Unretained(this)));
197 return embedded_test_server_->InitializeAndWaitUntilReady();
200 scoped_ptr<net::test_server::HttpResponse> HandleRequest(
201 const net::test_server::HttpRequest& request) {
202 std::map<std::string, std::string>::const_iterator host_it =
203 request.headers.find("Host");
204 if (host_it == request.headers.end())
205 return scoped_ptr<net::test_server::HttpResponse>();
207 std::string url =
208 std::string("http://") + host_it->second + request.relative_url;
209 if (response_url_.spec() != url)
210 return scoped_ptr<net::test_server::HttpResponse>();
212 scoped_ptr<net::test_server::BasicHttpResponse> http_response(
213 new net::test_server::BasicHttpResponse());
214 http_response->set_code(net::HTTP_OK);
215 http_response->set_content_type("text/html");
216 http_response->set_content(response_content_);
217 return http_response.Pass();
220 content::WebContents* GetWebContents() {
221 return browser()->tab_strip_model()->GetActiveWebContents();
224 // Returns the URL that was loaded.
225 GURL LoadHtml(const std::string& host, const std::string& content) {
226 GURL::Replacements replace_host;
227 replace_host.SetHostStr(host);
228 response_content_ = content;
229 response_url_ =
230 embedded_test_server_->base_url().ReplaceComponents(replace_host);
231 ui_test_utils::NavigateToURL(browser(), response_url_);
232 return response_url_;
235 void NavigateMainFrame(const GURL& url) {
236 PostTaskToInProcessRendererAndWait(
237 base::Bind(&PhishingClassifierDelegateTest::NavigateMainFrameInternal,
238 base::Unretained(this), url));
241 void NavigateMainFrameInternal(const GURL& url) {
242 content::RenderView* render_view =
243 content::RenderView::FromRoutingID(kRenderViewRoutingId);
244 render_view->GetWebView()->mainFrame()->firstChild()->loadRequest(
245 blink::WebURLRequest(url));
248 void GoBack() {
249 GetWebContents()->GetController().GoBack();
250 content::WaitForLoadStop(GetWebContents());
253 void GoForward() {
254 GetWebContents()->GetController().GoForward();
255 content::WaitForLoadStop(GetWebContents());
258 scoped_refptr<InterceptingMessageFilter> intercepting_filter_;
259 GURL response_url_;
260 std::string response_content_;
261 scoped_ptr<net::test_server::EmbeddedTestServer> embedded_test_server_;
262 scoped_ptr<ClientPhishingRequest> verdict_;
263 StrictMock<MockPhishingClassifier>* classifier_; // Owned by |delegate_|.
264 PhishingClassifierDelegate* delegate_; // Owned by the RenderView.
265 scoped_refptr<content::MessageLoopRunner> runner_;
268 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, Navigation) {
269 MockScorer scorer;
270 delegate_->SetPhishingScorer(&scorer);
271 ASSERT_TRUE(classifier_->is_ready());
273 // Test an initial load. We expect classification to happen normally.
274 EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
275 std::string port = base::IntToString(embedded_test_server_->port());
276 std::string html = "<html><body><iframe src=\"http://sub1.com:";
277 html += port;
278 html += "/\"></iframe></body></html>";
279 GURL url = LoadHtml("host.com", html);
280 Mock::VerifyAndClearExpectations(classifier_);
281 OnStartPhishingDetection(url);
282 base::string16 page_text = ASCIIToUTF16("dummy");
284 InSequence s;
285 EXPECT_CALL(*classifier_, CancelPendingClassification());
286 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
287 PageCaptured(&page_text, false);
288 Mock::VerifyAndClearExpectations(classifier_);
291 // Reloading the same page should not trigger a reclassification.
292 // However, it will cancel any pending classification since the
293 // content is being replaced.
294 EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
296 content::TestNavigationObserver observer(GetWebContents());
297 chrome::Reload(browser(), CURRENT_TAB);
298 observer.Wait();
300 Mock::VerifyAndClearExpectations(classifier_);
301 OnStartPhishingDetection(url);
302 page_text = ASCIIToUTF16("dummy");
303 EXPECT_CALL(*classifier_, CancelPendingClassification());
304 PageCaptured(&page_text, false);
305 Mock::VerifyAndClearExpectations(classifier_);
307 // Navigating in a subframe will not change the toplevel URL. However, this
308 // should cancel pending classification since the page content is changing.
309 // Currently, we do not start a new classification after subframe loads.
310 EXPECT_CALL(*classifier_, CancelPendingClassification())
311 .WillOnce(Invoke(this, &PhishingClassifierDelegateTest::CancelCalled));
313 runner_ = new content::MessageLoopRunner;
314 NavigateMainFrame(GURL(std::string("http://sub2.com:") + port + "/"));
316 runner_->Run();
317 runner_ = NULL;
319 Mock::VerifyAndClearExpectations(classifier_);
321 OnStartPhishingDetection(url);
322 page_text = ASCIIToUTF16("dummy");
323 EXPECT_CALL(*classifier_, CancelPendingClassification());
324 PageCaptured(&page_text, false);
325 Mock::VerifyAndClearExpectations(classifier_);
327 // Scrolling to an anchor works similarly to a subframe navigation, but
328 // see the TODO in PhishingClassifierDelegate::DidCommitProvisionalLoad.
329 EXPECT_CALL(*classifier_, CancelPendingClassification());
330 GURL foo_url = GURL(url.spec() + "#foo");
331 ui_test_utils::NavigateToURL(browser(), foo_url);
332 Mock::VerifyAndClearExpectations(classifier_);
333 OnStartPhishingDetection(url);
334 page_text = ASCIIToUTF16("dummy");
335 EXPECT_CALL(*classifier_, CancelPendingClassification());
336 PageCaptured(&page_text, false);
337 Mock::VerifyAndClearExpectations(classifier_);
339 // Now load a new toplevel page, which should trigger another classification.
340 EXPECT_CALL(*classifier_, CancelPendingClassification())
341 .WillOnce(Invoke(this, &PhishingClassifierDelegateTest::CancelCalled));
343 runner_ = new content::MessageLoopRunner;
344 url = LoadHtml("host2.com", "dummy2");
345 runner_->Run();
346 runner_ = NULL;
348 Mock::VerifyAndClearExpectations(classifier_);
349 page_text = ASCIIToUTF16("dummy2");
350 OnStartPhishingDetection(url);
352 InSequence s;
353 EXPECT_CALL(*classifier_, CancelPendingClassification());
354 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
355 PageCaptured(&page_text, false);
356 Mock::VerifyAndClearExpectations(classifier_);
359 // No classification should happen on back/forward navigation.
360 // Note: in practice, the browser will not send a StartPhishingDetection IPC
361 // in this case. However, we want to make sure that the delegate behaves
362 // correctly regardless.
363 EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
364 GoBack();
365 Mock::VerifyAndClearExpectations(classifier_);
367 page_text = ASCIIToUTF16("dummy");
368 OnStartPhishingDetection(url);
369 EXPECT_CALL(*classifier_, CancelPendingClassification());
370 PageCaptured(&page_text, false);
371 Mock::VerifyAndClearExpectations(classifier_);
373 EXPECT_CALL(*classifier_, CancelPendingClassification());
374 GoForward();
375 Mock::VerifyAndClearExpectations(classifier_);
377 page_text = ASCIIToUTF16("dummy2");
378 OnStartPhishingDetection(url);
379 EXPECT_CALL(*classifier_, CancelPendingClassification());
380 PageCaptured(&page_text, false);
381 Mock::VerifyAndClearExpectations(classifier_);
383 // Now go back again and scroll to a different anchor.
384 // No classification should happen.
385 EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
386 GoBack();
387 Mock::VerifyAndClearExpectations(classifier_);
388 page_text = ASCIIToUTF16("dummy");
390 OnStartPhishingDetection(url);
391 EXPECT_CALL(*classifier_, CancelPendingClassification());
392 PageCaptured(&page_text, false);
393 Mock::VerifyAndClearExpectations(classifier_);
395 EXPECT_CALL(*classifier_, CancelPendingClassification());
396 GURL foo2_url = GURL(foo_url.spec() + "2");
397 ui_test_utils::NavigateToURL(browser(), foo2_url);
398 Mock::VerifyAndClearExpectations(classifier_);
400 OnStartPhishingDetection(url);
401 page_text = ASCIIToUTF16("dummy");
402 EXPECT_CALL(*classifier_, CancelPendingClassification());
403 PageCaptured(&page_text, false);
404 Mock::VerifyAndClearExpectations(classifier_);
406 // The delegate will cancel pending classification on destruction.
407 EXPECT_CALL(*classifier_, CancelPendingClassification());
410 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer) {
411 // For this test, we'll create the delegate with no scorer available yet.
412 ASSERT_FALSE(classifier_->is_ready());
414 // Queue up a pending classification, cancel it, then queue up another one.
415 GURL url = LoadHtml("host.com", "dummy");
416 base::string16 page_text = ASCIIToUTF16("dummy");
417 OnStartPhishingDetection(url);
418 PageCaptured(&page_text, false);
420 url = LoadHtml("host2.com", "dummy2");
421 page_text = ASCIIToUTF16("dummy2");
422 OnStartPhishingDetection(url);
423 PageCaptured(&page_text, false);
425 // Now set a scorer, which should cause a classifier to be created and
426 // the classification to proceed.
427 page_text = ASCIIToUTF16("dummy2");
428 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
429 MockScorer scorer;
430 delegate_->SetPhishingScorer(&scorer);
431 Mock::VerifyAndClearExpectations(classifier_);
433 // If we set a new scorer while a classification is going on the
434 // classification should be cancelled.
435 EXPECT_CALL(*classifier_, CancelPendingClassification());
436 delegate_->SetPhishingScorer(&scorer);
437 Mock::VerifyAndClearExpectations(classifier_);
439 // The delegate will cancel pending classification on destruction.
440 EXPECT_CALL(*classifier_, CancelPendingClassification());
443 // Flaky: crbug.com/435719
444 #if defined(LEAK_SANITIZER)
445 #define MAYBE_NoScorer_Ref DISABLED_NoScorer_Ref
446 #else
447 #define MAYBE_NoScorer_Ref NoScorer_Ref
448 #endif
450 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, MAYBE_NoScorer_Ref) {
451 // Similar to the last test, but navigates within the page before
452 // setting the scorer.
453 ASSERT_FALSE(classifier_->is_ready());
455 // Queue up a pending classification, cancel it, then queue up another one.
456 GURL url = LoadHtml("host.com", "dummy");
457 base::string16 page_text = ASCIIToUTF16("dummy");
458 OnStartPhishingDetection(url);
459 PageCaptured(&page_text, false);
461 OnStartPhishingDetection(url);
462 page_text = ASCIIToUTF16("dummy");
463 PageCaptured(&page_text, false);
465 // Now set a scorer, which should cause a classifier to be created and
466 // the classification to proceed.
467 page_text = ASCIIToUTF16("dummy");
468 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
469 MockScorer scorer;
470 delegate_->SetPhishingScorer(&scorer);
471 Mock::VerifyAndClearExpectations(classifier_);
473 // The delegate will cancel pending classification on destruction.
474 EXPECT_CALL(*classifier_, CancelPendingClassification());
477 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
478 NoStartPhishingDetection) {
479 // Tests the behavior when OnStartPhishingDetection has not yet been called
480 // when the page load finishes.
481 MockScorer scorer;
482 delegate_->SetPhishingScorer(&scorer);
483 ASSERT_TRUE(classifier_->is_ready());
485 EXPECT_CALL(*classifier_, CancelPendingClassification());
486 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
487 Mock::VerifyAndClearExpectations(classifier_);
488 base::string16 page_text = ASCIIToUTF16("phish");
489 EXPECT_CALL(*classifier_, CancelPendingClassification());
490 PageCaptured(&page_text, false);
491 Mock::VerifyAndClearExpectations(classifier_);
492 // Now simulate the StartPhishingDetection IPC. We expect classification
493 // to begin.
494 page_text = ASCIIToUTF16("phish");
495 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
496 OnStartPhishingDetection(url);
497 Mock::VerifyAndClearExpectations(classifier_);
499 // Now try again, but this time we will navigate the page away before
500 // the IPC is sent.
501 EXPECT_CALL(*classifier_, CancelPendingClassification());
502 LoadHtml("host2.com", "<html><body>phish</body></html>");
503 Mock::VerifyAndClearExpectations(classifier_);
504 page_text = ASCIIToUTF16("phish");
505 EXPECT_CALL(*classifier_, CancelPendingClassification());
506 PageCaptured(&page_text, false);
507 Mock::VerifyAndClearExpectations(classifier_);
509 EXPECT_CALL(*classifier_, CancelPendingClassification());
510 LoadHtml("host3.com", "<html><body>phish</body></html>");
511 Mock::VerifyAndClearExpectations(classifier_);
512 OnStartPhishingDetection(url);
514 // In this test, the original page is a redirect, which we do not get a
515 // StartPhishingDetection IPC for. We use location.replace() to load a
516 // new page while reusing the original session history entry, and check that
517 // classification begins correctly for the landing page.
518 EXPECT_CALL(*classifier_, CancelPendingClassification());
519 LoadHtml("host4.com", "<html><body>abc</body></html>");
520 Mock::VerifyAndClearExpectations(classifier_);
521 page_text = ASCIIToUTF16("abc");
522 EXPECT_CALL(*classifier_, CancelPendingClassification());
523 PageCaptured(&page_text, false);
524 Mock::VerifyAndClearExpectations(classifier_);
525 EXPECT_CALL(*classifier_, CancelPendingClassification());
527 ui_test_utils::NavigateToURL(
528 browser(), GURL("javascript:location.replace(\'redir\');"));
530 Mock::VerifyAndClearExpectations(classifier_);
532 std::string url_str = "http://host4.com:";
533 url_str += base::IntToString(embedded_test_server_->port());
534 url_str += "/redir";
535 OnStartPhishingDetection(GURL(url_str));
536 page_text = ASCIIToUTF16("123");
538 InSequence s;
539 EXPECT_CALL(*classifier_, CancelPendingClassification());
540 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
541 PageCaptured(&page_text, false);
542 Mock::VerifyAndClearExpectations(classifier_);
545 // The delegate will cancel pending classification on destruction.
546 EXPECT_CALL(*classifier_, CancelPendingClassification());
549 // Test flakes with LSAN enabled. See http://crbug.com/373155.
550 #if defined(LEAK_SANITIZER)
551 #define MAYBE_IgnorePreliminaryCapture DISABLED_IgnorePreliminaryCapture
552 #else
553 #define MAYBE_IgnorePreliminaryCapture IgnorePreliminaryCapture
554 #endif
555 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
556 MAYBE_IgnorePreliminaryCapture) {
557 // Tests that preliminary PageCaptured notifications are ignored.
558 MockScorer scorer;
559 delegate_->SetPhishingScorer(&scorer);
560 ASSERT_TRUE(classifier_->is_ready());
562 EXPECT_CALL(*classifier_, CancelPendingClassification());
563 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
564 Mock::VerifyAndClearExpectations(classifier_);
565 OnStartPhishingDetection(url);
566 base::string16 page_text = ASCIIToUTF16("phish");
567 PageCaptured(&page_text, true);
569 // Once the non-preliminary capture happens, classification should begin.
570 page_text = ASCIIToUTF16("phish");
572 InSequence s;
573 EXPECT_CALL(*classifier_, CancelPendingClassification());
574 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
575 PageCaptured(&page_text, false);
576 Mock::VerifyAndClearExpectations(classifier_);
579 // The delegate will cancel pending classification on destruction.
580 EXPECT_CALL(*classifier_, CancelPendingClassification());
583 #if defined(ADDRESS_SANITIZER)
584 #define Maybe_DuplicatePageCapture DISABLED_DuplicatePageCapture
585 #else
586 #define Maybe_DuplicatePageCapture DuplicatePageCapture
587 #endif
588 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
589 Maybe_DuplicatePageCapture) {
590 // Tests that a second PageCaptured notification causes classification to
591 // be cancelled.
592 MockScorer scorer;
593 delegate_->SetPhishingScorer(&scorer);
594 ASSERT_TRUE(classifier_->is_ready());
596 EXPECT_CALL(*classifier_, CancelPendingClassification());
597 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
598 Mock::VerifyAndClearExpectations(classifier_);
599 OnStartPhishingDetection(url);
600 base::string16 page_text = ASCIIToUTF16("phish");
602 InSequence s;
603 EXPECT_CALL(*classifier_, CancelPendingClassification());
604 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
605 PageCaptured(&page_text, false);
606 Mock::VerifyAndClearExpectations(classifier_);
609 page_text = ASCIIToUTF16("phish");
610 EXPECT_CALL(*classifier_, CancelPendingClassification());
611 PageCaptured(&page_text, false);
612 Mock::VerifyAndClearExpectations(classifier_);
614 // The delegate will cancel pending classification on destruction.
615 EXPECT_CALL(*classifier_, CancelPendingClassification());
618 // Test flakes with LSAN enabled. See http://crbug.com/373155.
619 #if defined(LEAK_SANITIZER)
620 #define MAYBE_PhishingDetectionDone DISABLED_PhishingDetectionDone
621 #else
622 #define MAYBE_PhishingDetectionDone PhishingDetectionDone
623 #endif
624 IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
625 MAYBE_PhishingDetectionDone) {
626 // Tests that a PhishingDetectionDone IPC is sent to the browser
627 // whenever we finish classification.
628 MockScorer scorer;
629 delegate_->SetPhishingScorer(&scorer);
630 ASSERT_TRUE(classifier_->is_ready());
632 // Start by loading a page to populate the delegate's state.
633 EXPECT_CALL(*classifier_, CancelPendingClassification());
634 GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
635 Mock::VerifyAndClearExpectations(classifier_);
636 base::string16 page_text = ASCIIToUTF16("phish");
637 OnStartPhishingDetection(url);
639 InSequence s;
640 EXPECT_CALL(*classifier_, CancelPendingClassification());
641 EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
642 PageCaptured(&page_text, false);
643 Mock::VerifyAndClearExpectations(classifier_);
646 // Now run the callback to simulate the classifier finishing.
647 ClientPhishingRequest verdict;
648 verdict.set_url(url.spec());
649 verdict.set_client_score(0.8f);
650 verdict.set_is_phishing(false); // Send IPC even if site is not phishing.
651 RunClassificationDone(verdict);
652 ASSERT_TRUE(intercepting_filter_->verdict());
653 EXPECT_EQ(verdict.SerializeAsString(),
654 intercepting_filter_->verdict()->SerializeAsString());
656 // The delegate will cancel pending classification on destruction.
657 EXPECT_CALL(*classifier_, CancelPendingClassification());
660 } // namespace safe_browsing