15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/command_line.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/run_loop.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/safe_browsing/csd.pb.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/safe_browsing/safebrowsing_messages.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/features.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/phishing_classifier.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/scorer.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/browser_message_filter.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/render_process_host.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/browser/web_contents.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_view.h"
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/test/browser_test_utils.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/test/test_navigation_observer.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "content/public/test/test_utils.h"
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/dns/mock_host_resolver.h"
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/test/embedded_test_server/embedded_test_server.h"
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/test/embedded_test_server/http_request.h"
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "net/test/embedded_test_server/http_response.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h"
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURLRequest.h"
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h"
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "third_party/WebKit/public/web/WebView.h"
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::InSequence;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Mock;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Pointee;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::StrictMock;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace safe_browsing {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// The RenderFrame is routing ID 1, and the RenderView is 2.
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kRenderViewRoutingId = 2;
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockPhishingClassifier : public PhishingClassifier {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit MockPhishingClassifier(content::RenderView* render_view)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : PhishingClassifier(render_view, NULL /* clock */) {}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MockPhishingClassifier() {}
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MOCK_METHOD2(BeginClassification,
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               void(const base::string16*, const DoneCallback&));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_METHOD0(CancelPendingClassification, void());
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockPhishingClassifier);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockScorer : public Scorer {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer() : Scorer() {}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MockScorer() {}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MOCK_CONST_METHOD1(ComputeScore, double(const FeatureMap&));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MockScorer);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class InterceptingMessageFilter : public content::BrowserMessageFilter {
83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  InterceptingMessageFilter()
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : BrowserMessageFilter(SafeBrowsingMsgStart),
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        waiting_message_loop_(NULL) {
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const ClientPhishingRequest* verdict() const { return verdict_.get(); }
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool handled = true;
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC_BEGIN_MESSAGE_MAP(InterceptingMessageFilter, message)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IPC_MESSAGE_HANDLER(SafeBrowsingHostMsg_PhishingDetectionDone,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            OnPhishingDetectionDone)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        IPC_MESSAGE_UNHANDLED(handled = false);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC_END_MESSAGE_MAP()
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return handled;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void Reset() {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    run_loop_.reset(new base::RunLoop());
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    waiting_message_loop_ = base::MessageLoop::current();
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    quit_closure_ = run_loop_->QuitClosure();
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RunUntilVerdictReceived() {
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::RunThisRunLoop(run_loop_.get());
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Clear out the synchronization state just in case.
110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    waiting_message_loop_ = NULL;
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    quit_closure_.Reset();
112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    run_loop_.reset();
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnPhishingDetectionDone(const std::string& verdict_str) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<ClientPhishingRequest> verdict(new ClientPhishingRequest);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (verdict->ParseFromString(verdict_str) &&
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        verdict->IsInitialized()) {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      verdict_.swap(verdict);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    waiting_message_loop_->PostTask(FROM_HERE, quit_closure_);
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private:
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~InterceptingMessageFilter() {}
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<ClientPhishingRequest> verdict_;
128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop* waiting_message_loop_;
129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::Closure quit_closure_;
130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<base::RunLoop> run_loop_;
131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class PhishingClassifierDelegateTest : public InProcessBrowserTest {
135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void CancelCalled() {
137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (runner_.get()) {
138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      content::BrowserThread::PostTask(
139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          content::BrowserThread::UI, FROM_HERE, runner_->QuitClosure());
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) protected:
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    command_line->AppendSwitch(switches::kSingleProcess);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_WIN)
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Don't want to try to create a GPU process.
1480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    command_line->AppendSwitch(switches::kDisableGpu);
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual void SetUpOnMainThread() OVERRIDE {
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    intercepting_filter_ = new InterceptingMessageFilter();
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::RenderView* render_view =
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::RenderView::FromRoutingID(kRenderViewRoutingId);
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GetWebContents()->GetRenderProcessHost()->AddFilter(
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        intercepting_filter_.get());
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    classifier_ = new StrictMock<MockPhishingClassifier>(render_view);
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    delegate_ = PhishingClassifierDelegate::Create(render_view, classifier_);
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(StartTestServer());
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host_resolver()->AddRule("*", "127.0.0.1");
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs the ClassificationDone callback, then waits for the
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PhishingDetectionDone IPC to arrive.
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void RunClassificationDone(const ClientPhishingRequest& verdict) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Clear out any previous state.
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    intercepting_filter_->Reset();
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PostTaskToInProcessRendererAndWait(
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&PhishingClassifierDelegate::ClassificationDone,
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Unretained(delegate_),
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        verdict));
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    intercepting_filter_->RunUntilVerdictReceived();
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnStartPhishingDetection(const GURL& url) {
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PostTaskToInProcessRendererAndWait(
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&PhishingClassifierDelegate::OnStartPhishingDetection,
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   base::Unretained(delegate_), url));
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void PageCaptured(base::string16* page_text, bool preliminary_capture) {
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PostTaskToInProcessRendererAndWait(
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&PhishingClassifierDelegate::PageCaptured,
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   base::Unretained(delegate_), page_text,
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   preliminary_capture));
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  bool StartTestServer() {
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    CHECK(!embedded_test_server_);
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    embedded_test_server_.reset(new net::test_server::EmbeddedTestServer());
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    embedded_test_server_->RegisterRequestHandler(
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&PhishingClassifierDelegateTest::HandleRequest,
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   base::Unretained(this)));
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return embedded_test_server_->InitializeAndWaitUntilReady();
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<net::test_server::HttpResponse> HandleRequest(
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      const net::test_server::HttpRequest& request) {
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::map<std::string, std::string>::const_iterator host_it =
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        request.headers.find("Host");
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (host_it == request.headers.end())
205f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<net::test_server::HttpResponse>();
206f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
207f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    std::string url =
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        std::string("http://") + host_it->second + request.relative_url;
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (response_url_.spec() != url)
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return scoped_ptr<net::test_server::HttpResponse>();
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_ptr<net::test_server::BasicHttpResponse> http_response(
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new net::test_server::BasicHttpResponse());
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    http_response->set_code(net::HTTP_OK);
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    http_response->set_content_type("text/html");
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    http_response->set_content(response_content_);
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return http_response.PassAs<net::test_server::HttpResponse>();
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::WebContents* GetWebContents() {
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return browser()->tab_strip_model()->GetActiveWebContents();
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Returns the URL that was loaded.
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL LoadHtml(const std::string& host, const std::string& content) {
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GURL::Replacements replace_host;
227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    replace_host.SetHostStr(host);
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    response_content_ = content;
229f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    response_url_ =
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        embedded_test_server_->base_url().ReplaceComponents(replace_host);
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ui_test_utils::NavigateToURL(browser(), response_url_);
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return response_url_;
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
235f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void NavigateMainFrame(const GURL& url) {
236f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PostTaskToInProcessRendererAndWait(
237f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        base::Bind(&PhishingClassifierDelegateTest::NavigateMainFrameInternal,
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   base::Unretained(this), url));
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void NavigateMainFrameInternal(const GURL& url) {
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::RenderView* render_view =
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::RenderView::FromRoutingID(kRenderViewRoutingId);
244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    render_view->GetWebView()->mainFrame()->firstChild()->loadRequest(
245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        blink::WebURLRequest(url));
246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void GoBack() {
249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GetWebContents()->GetController().GoBack();
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::WaitForLoadStop(GetWebContents());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void GoForward() {
254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    GetWebContents()->GetController().GoForward();
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    content::WaitForLoadStop(GetWebContents());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<InterceptingMessageFilter> intercepting_filter_;
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL response_url_;
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string response_content_;
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<net::test_server::EmbeddedTestServer> embedded_test_server_;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ClientPhishingRequest> verdict_;
263f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  StrictMock<MockPhishingClassifier>* classifier_;  // Owned by |delegate_|.
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PhishingClassifierDelegate* delegate_;  // Owned by the RenderView.
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner_;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
268f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, Navigation) {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
270f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(classifier_->is_ready());
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test an initial load.  We expect classification to happen normally.
274f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
275f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string port = base::IntToString(embedded_test_server_->port());
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string html = "<html><body><iframe src=\"http://sub1.com:";
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  html += port;
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  html += "/\"></iframe></body></html>";
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", html);
280f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("dummy");
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, CancelPendingClassification());
286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PageCaptured(&page_text, false);
288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(classifier_);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reloading the same page should not trigger a reclassification.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // However, it will cancel any pending classification since the
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content is being replaced.
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  content::TestNavigationObserver observer(GetWebContents());
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  chrome::Reload(browser(), CURRENT_TAB);
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  observer.Wait();
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Navigating in a subframe will not change the toplevel URL.  However, this
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should cancel pending classification since the page content is changing.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Currently, we do not start a new classification after subframe loads.
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification())
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(Invoke(this, &PhishingClassifierDelegateTest::CancelCalled));
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
313f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  runner_ = new content::MessageLoopRunner;
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NavigateMainFrame(GURL(std::string("http://sub2.com:") + port + "/"));
315f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  runner_->Run();
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  runner_ = NULL;
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scrolling to an anchor works similarly to a subframe navigation, but
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // see the TODO in PhishingClassifierDelegate::DidCommitProvisionalLoad.
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL foo_url = GURL(url.spec() + "#foo");
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), foo_url);
332f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
336f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now load a new toplevel page, which should trigger another classification.
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification())
341f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      .WillOnce(Invoke(this, &PhishingClassifierDelegateTest::CancelCalled));
342f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  runner_ = new content::MessageLoopRunner;
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  url = LoadHtml("host2.com", "dummy2");
345f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  runner_->Run();
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  runner_ = NULL;
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
348f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy2");
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, CancelPendingClassification());
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PageCaptured(&page_text, false);
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(classifier_);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No classification should happen on back/forward navigation.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: in practice, the browser will not send a StartPhishingDetection IPC
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in this case.  However, we want to make sure that the delegate behaves
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // correctly regardless.
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GoBack();
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
372f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
374f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GoForward();
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy2");
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now go back again and scroll to a different anchor.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No classification should happen.
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification()).Times(2);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GoBack();
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
394f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
395f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL foo2_url = GURL(foo_url.spec() + "2");
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), foo2_url);
398f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
402f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
403f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
404f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
407f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer) {
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For this test, we'll create the delegate with no scorer available yet.
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(classifier_->is_ready());
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Queue up a pending classification, cancel it, then queue up another one.
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", "dummy");
416a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("dummy");
417f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  url = LoadHtml("host2.com", "dummy2");
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy2");
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now set a scorer, which should cause a classifier to be created and
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the classification to proceed.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy2");
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we set a new scorer while a classification is going on the
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // classification should be cancelled.
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, NoScorer_Ref) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Similar to the last test, but navigates within the page before
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // setting the scorer.
446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_FALSE(classifier_->is_ready());
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Queue up a pending classification, cancel it, then queue up another one.
449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", "dummy");
450a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("dummy");
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
454f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now set a scorer, which should cause a classifier to be created and
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the classification to proceed.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("dummy");
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       NoStartPhishingDetection) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests the behavior when OnStartPhishingDetection has not yet been called
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when the page load finishes.
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(classifier_->is_ready());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
481a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("phish");
482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now simulate the StartPhishingDetection IPC.  We expect classification
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to begin.
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("phish");
488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now try again, but this time we will navigate the page away before
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the IPC is sent.
494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoadHtml("host2.com", "<html><body>phish</body></html>");
496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("phish");
498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
502f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoadHtml("host3.com", "<html><body>phish</body></html>");
504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In this test, the original page is a redirect, which we do not get a
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StartPhishingDetection IPC for.  We use location.replace() to load a
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // new page while reusing the original session history entry, and check that
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // classification begins correctly for the landing page.
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  LoadHtml("host4.com", "<html><body>abc</body></html>");
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("abc");
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ui_test_utils::NavigateToURL(
521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      browser(), GURL("javascript:location.replace(\'redir\');"));
522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  std::string url_str = "http://host4.com:";
526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  url_str += base::IntToString(embedded_test_server_->port());
527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  url_str += "/redir";
528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(GURL(url_str));
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("123");
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, CancelPendingClassification());
533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PageCaptured(&page_text, false);
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(classifier_);
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                       IgnorePreliminaryCapture) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests that preliminary PageCaptured notifications are ignored.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(classifier_->is_ready());
548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
553a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("phish");
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, true);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once the non-preliminary capture happens, classification should begin.
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("phish");
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
560f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, CancelPendingClassification());
561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
562f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PageCaptured(&page_text, false);
563f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(classifier_);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
567f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
570f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(ADDRESS_SANITIZER)
571f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define Maybe_DuplicatePageCapture DISABLED_DuplicatePageCapture
572f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#else
573f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#define Maybe_DuplicatePageCapture DuplicatePageCapture
574f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif
575f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest,
576f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                       Maybe_DuplicatePageCapture) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests that a second PageCaptured notification causes classification to
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // be cancelled.
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(classifier_->is_ready());
582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
584f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
586f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("phish");
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
590f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, CancelPendingClassification());
591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PageCaptured(&page_text, false);
593f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(classifier_);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_text = ASCIIToUTF16("phish");
597f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
598f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  PageCaptured(&page_text, false);
599f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(PhishingClassifierDelegateTest, PhishingDetectionDone) {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests that a PhishingDetectionDone IPC is sent to the browser
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whenever we finish classification.
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockScorer scorer;
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  delegate_->SetPhishingScorer(&scorer);
610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(classifier_->is_ready());
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start by loading a page to populate the delegate's state.
613f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
614f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  GURL url = LoadHtml("host.com", "<html><body>phish</body></html>");
615f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  Mock::VerifyAndClearExpectations(classifier_);
616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 page_text = ASCIIToUTF16("phish");
617f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  OnStartPhishingDetection(url);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InSequence s;
620f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, CancelPendingClassification());
621f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_CALL(*classifier_, BeginClassification(Pointee(page_text), _));
622f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PageCaptured(&page_text, false);
623f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Mock::VerifyAndClearExpectations(classifier_);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now run the callback to simulate the classifier finishing.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientPhishingRequest verdict;
628f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  verdict.set_url(url.spec());
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  verdict.set_client_score(0.8f);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  verdict.set_is_phishing(false);  // Send IPC even if site is not phishing.
631f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  RunClassificationDone(verdict);
632f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ASSERT_TRUE(intercepting_filter_->verdict());
633f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_EQ(verdict.SerializeAsString(),
634f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            intercepting_filter_->verdict()->SerializeAsString());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The delegate will cancel pending classification on destruction.
637f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_CALL(*classifier_, CancelPendingClassification());
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace safe_browsing
641