phishing_classifier_browsertest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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)// Note that although this is not a "browser" test, it runs as part of
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// browser_tests.  This is because WebKit does not work properly if it is
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shutdown and re-initialized.  Since browser_tests runs each test in a
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// new process, this avoids the problem.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/phishing_classifier.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string16.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/safe_browsing/client_model.pb.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/safe_browsing/csd.pb.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/features.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/mock_feature_extractor_clock.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/murmurhash3_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/renderer/safe_browsing/scorer.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/render_view_fake_resources_test.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/sha2.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::AllOf;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Contains;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Not;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::testing::Pair;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace safe_browsing {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PhishingClassifierTest : public content::RenderViewFakeResourcesTest {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PhishingClassifierTest()
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : url_tld_token_net_(features::kUrlTldToken + std::string("net")),
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        page_link_domain_phishing_(features::kPageLinkDomain +
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   std::string("phishing.com")),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        page_term_login_(features::kPageTerm + std::string("login")) {}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Set up WebKit and the RenderView.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RenderViewFakeResourcesTest::SetUp();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Construct a model to test with.  We include one feature from each of
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the feature extractors, which allows us to verify that they all ran.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSideModel model;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(url_tld_token_net_));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(page_link_domain_phishing_));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(page_term_login_));
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString("login"));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(features::kUrlTldToken +
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              std::string("net")));
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(features::kPageLinkDomain +
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              std::string("phishing.com")));
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString(features::kPageTerm +
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              std::string("login")));
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_hashes(crypto::SHA256HashString("login"));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Add a default rule with a non-phishy weight.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClientSideModel::Rule* rule = model.add_rule();
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rule->set_weight(-1.0);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // To give a phishy score, the total weight needs to be >= 0
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // (0.5 when converted to a probability).  This will only happen
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if all of the listed features are present.
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rule = model.add_rule();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rule->add_feature(0);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rule->add_feature(1);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rule->add_feature(2);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rule->set_weight(1.0);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_page_term(3);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.set_murmur_hash_seed(2777808611U);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.add_page_word(MurmurHash3String("login", model.murmur_hash_seed()));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    model.set_max_words_per_term(1);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    clock_ = new MockFeatureExtractorClock;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scorer_.reset(Scorer::Create(model.SerializeAsString()));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ASSERT_TRUE(scorer_.get());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    classifier_.reset(new PhishingClassifier(view(), clock_));
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RenderViewFakeResourcesTest::TearDown();
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper method to start phishing classification and wait for it to
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // complete.  Returns the true if the page is classified as phishy and
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // false otherwise.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool RunPhishingClassifier(const string16* page_text,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             float* phishy_score,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             FeatureMap* features) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    verdict_.Clear();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *phishy_score = PhishingClassifier::kInvalidScore;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    features->Clear();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    classifier_->BeginClassification(
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        page_text,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&PhishingClassifierTest::ClassificationFinished,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this)));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Run();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *phishy_score = verdict_.client_score();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < verdict_.feature_map_size(); ++i) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      features->AddRealFeature(verdict_.feature_map(i).name(),
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               verdict_.feature_map(i).value());
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return verdict_.is_phishing();
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Completion callback for classification.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClassificationFinished(const ClientPhishingRequest& verdict) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    verdict_ = verdict;  // copy the verdict.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_.Quit();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Scorer> scorer_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<PhishingClassifier> classifier_;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockFeatureExtractorClock* clock_;  // owned by classifier_
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Features that are in the model.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string url_tld_token_net_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string page_link_domain_phishing_;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string page_term_login_;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This member holds the status from the most recent call to the
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClassificationFinished callback.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClientPhishingRequest verdict_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PhishingClassifierTest, TestClassification) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No scorer yet, so the classifier is not ready.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(classifier_->is_ready());
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now set the scorer.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  classifier_->set_phishing_scorer(scorer_.get());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(classifier_->is_ready());
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This test doesn't exercise the extraction timing.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_CALL(*clock_, Now())
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .WillRepeatedly(::testing::Return(base::TimeTicks::Now()));
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  responses_["http://host.net/"] =
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "<html><body><a href=\"http://phishing.com/\">login</a></body></html>";
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadURL("http://host.net/");
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 page_text = ASCIIToUTF16("login");
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  float phishy_score;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FeatureMap features;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: features.features() might contain other features that simply aren't
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the model.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_THAT(features.features(),
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              AllOf(Contains(Pair(url_tld_token_net_, 1.0)),
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Contains(Pair(page_link_domain_phishing_, 1.0)),
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Contains(Pair(page_term_login_, 1.0))));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FLOAT_EQ(0.5, phishy_score);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Change the link domain to something non-phishy.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  responses_["http://host.net/"] =
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "<html><body><a href=\"http://safe.com/\">login</a></body></html>";
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadURL("http://host.net/");
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_THAT(features.features(),
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              AllOf(Contains(Pair(url_tld_token_net_, 1.0)),
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    Contains(Pair(page_term_login_, 1.0))));
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_THAT(features.features(),
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              Not(Contains(Pair(page_link_domain_phishing_, 1.0))));
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(phishy_score, 0.0);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LT(phishy_score, 0.5);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extraction should fail for this case, since there is no TLD.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  responses_["http://localhost/"] = "<html><body>content</body></html>";
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadURL("http://localhost/");
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, features.features().size());
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PhishingClassifier::kInvalidScore, phishy_score);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extraction should also fail for this case, because the URL is not http.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  responses_["https://host.net/"] = "<html><body>secure</body></html>";
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadURL("https://host.net/");
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, features.features().size());
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PhishingClassifier::kInvalidScore, phishy_score);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Extraction should fail for this case because the URL is a POST request.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LoadURLWithPost("http://host.net/");
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(RunPhishingClassifier(&page_text, &phishy_score, &features));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0U, features.features().size());
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PhishingClassifier::kInvalidScore, phishy_score);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PhishingClassifierTest, DisableDetection) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No scorer yet, so the classifier is not ready.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(classifier_->is_ready());
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Now set the scorer.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  classifier_->set_phishing_scorer(scorer_.get());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(classifier_->is_ready());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set a NULL scorer, which turns detection back off.
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  classifier_->set_phishing_scorer(NULL);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(classifier_->is_ready());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace safe_browsing
212