phishing_classifier_browsertest.cc revision 7d4cd473f85ac64c3747c96c277f9e506a0d2246
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Note that although this is not a "browser" test, it runs as part of
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// browser_tests.  This is because WebKit does not work properly if it is
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// shutdown and re-initialized.  Since browser_tests runs each test in a
890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// new process, this avoids the problem.
990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/renderer/safe_browsing/phishing_classifier.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/bind.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string16.h"
1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/common/safe_browsing/client_model.pb.h"
19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/common/safe_browsing/csd.pb.h"
20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/renderer/safe_browsing/features.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/renderer/safe_browsing/mock_feature_extractor_clock.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/renderer/safe_browsing/murmurhash3_util.h"
23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "chrome/renderer/safe_browsing/scorer.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/render_view_fake_resources_test.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "crypto/sha2.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing ::testing::AllOf;
29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing ::testing::Contains;
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing ::testing::Not;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing ::testing::Pair;
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace safe_browsing {
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass PhishingClassifierTest : public content::RenderViewFakeResourcesTest {
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch protected:
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PhishingClassifierTest()
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      : url_tld_token_net_(features::kUrlTldToken + std::string("net")),
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        page_link_domain_phishing_(features::kPageLinkDomain +
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                   std::string("phishing.com")),
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        page_term_login_(features::kPageTerm + std::string("login")) {}
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void SetUp() {
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Set up WebKit and the RenderView.
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    content::RenderViewFakeResourcesTest::SetUp();
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // Construct a model to test with.  We include one feature from each of
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    // the feature extractors, which allows us to verify that they all ran.
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    ClientSideModel model;
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(url_tld_token_net_));
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(page_link_domain_phishing_));
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(page_term_login_));
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString("login"));
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(features::kUrlTldToken +
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                              std::string("net")));
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(features::kPageLinkDomain +
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                              std::string("phishing.com")));
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(features::kPageTerm +
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                              std::string("login")));
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_hashes(crypto::SHA256HashString("login"));
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Add a default rule with a non-phishy weight.
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    ClientSideModel::Rule* rule = model.add_rule();
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rule->set_weight(-1.0);
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // To give a phishy score, the total weight needs to be >= 0
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    // (0.5 when converted to a probability).  This will only happen
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // if all of the listed features are present.
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rule = model.add_rule();
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rule->add_feature(0);
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rule->add_feature(1);
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rule->add_feature(2);
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    rule->set_weight(1.0);
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_page_term(3);
7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.set_murmur_hash_seed(2777808611U);
7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    model.add_page_word(MurmurHash3String("login", model.murmur_hash_seed()));
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    model.set_max_words_per_term(1);
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    clock_ = new MockFeatureExtractorClock;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scorer_.reset(Scorer::Create(model.SerializeAsString()));
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ASSERT_TRUE(scorer_.get());
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    classifier_.reset(new PhishingClassifier(view(), clock_));
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
87b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  virtual void TearDown() {
88b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    content::RenderViewFakeResourcesTest::TearDown();
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper method to start phishing classification and wait for it to
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // complete.  Returns the true if the page is classified as phishy and
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // false otherwise.
94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  bool RunPhishingClassifier(const string16* page_text,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             float* phishy_score,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             FeatureMap* features) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    verdict_.Clear();
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *phishy_score = PhishingClassifier::kInvalidScore;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    features->Clear();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
101b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    classifier_->BeginClassification(
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        page_text,
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        base::Bind(&PhishingClassifierTest::ClassificationFinished,
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                   base::Unretained(this)));
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    message_loop_.Run();
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    *phishy_score = verdict_.client_score();
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (int i = 0; i < verdict_.feature_map_size(); ++i) {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      features->AddRealFeature(verdict_.feature_map(i).name(),
110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                               verdict_.feature_map(i).value());
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return verdict_.is_phishing();
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Completion callback for classification.
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void ClassificationFinished(const ClientPhishingRequest& verdict) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    verdict_ = verdict;  // copy the verdict.
118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    message_loop_.Quit();
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<Scorer> scorer_;
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<PhishingClassifier> classifier_;
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  MockFeatureExtractorClock* clock_;  // owned by classifier_
124b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
125b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Features that are in the model.
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string url_tld_token_net_;
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string page_link_domain_phishing_;
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string page_term_login_;
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This member holds the status from the most recent call to the
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // ClassificationFinished callback.
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ClientPhishingRequest verdict_;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
134b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(PhishingClassifierTest, TestClassification) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // No scorer yet, so the classifier is not ready.
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(classifier_->is_ready());
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Now set the scorer.
140b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  classifier_->set_phishing_scorer(scorer_.get());
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_TRUE(classifier_->is_ready());
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This test doesn't exercise the extraction timing.
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_CALL(*clock_, Now())
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      .WillRepeatedly(::testing::Return(base::TimeTicks::Now()));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  responses_["http://host.net/"] =
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "<html><body><a href=\"http://phishing.com/\">login</a></body></html>";
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadURL("http://host.net/");
150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  string16 page_text = ASCIIToUTF16("login");
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  float phishy_score;
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FeatureMap features;
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_TRUE(RunPhishingClassifier(&page_text, &phishy_score, &features));
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Note: features.features() might contain other features that simply aren't
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // in the model.
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_THAT(features.features(),
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              AllOf(Contains(Pair(url_tld_token_net_, 1.0)),
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    Contains(Pair(page_link_domain_phishing_, 1.0)),
16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                    Contains(Pair(page_term_login_, 1.0))));
16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  EXPECT_FLOAT_EQ(0.5, phishy_score);
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Change the link domain to something non-phishy.
16490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  responses_["http://host.net/"] =
16590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      "<html><body><a href=\"http://safe.com/\">login</a></body></html>";
16690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LoadURL("http://host.net/");
16790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_THAT(features.features(),
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              AllOf(Contains(Pair(url_tld_token_net_, 1.0)),
171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)                    Contains(Pair(page_term_login_, 1.0))));
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_THAT(features.features(),
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              Not(Contains(Pair(page_link_domain_phishing_, 1.0))));
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_GE(phishy_score, 0.0);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_LT(phishy_score, 0.5);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Extraction should fail for this case, since there is no TLD.
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  responses_["http://localhost/"] = "<html><body>content</body></html>";
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadURL("http://localhost/");
180b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, features.features().size());
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(PhishingClassifier::kInvalidScore, phishy_score);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Extraction should also fail for this case, because the URL is not http.
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  responses_["https://host.net/"] = "<html><body>secure</body></html>";
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LoadURL("https://host.net/");
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, features.features().size());
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(PhishingClassifier::kInvalidScore, phishy_score);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Extraction should fail for this case because the URL is a POST request.
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  LoadURLWithPost("http://host.net/");
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(0U, features.features().size());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(PhishingClassifier::kInvalidScore, phishy_score);
19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)TEST_F(PhishingClassifierTest, DisableDetection) {
19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // No scorer yet, so the classifier is not ready.
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  EXPECT_FALSE(classifier_->is_ready());
20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Now set the scorer.
20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  classifier_->set_phishing_scorer(scorer_.get());
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(classifier_->is_ready());
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set a NULL scorer, which turns detection back off.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  classifier_->set_phishing_scorer(NULL);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_FALSE(classifier_->is_ready());
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
211b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)}  // namespace safe_browsing
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)