This source file includes following definitions.
- Schedule
- Disable
- ACTION
- SetUp
- TearDown
- SendClientReportPhishingRequest
- SendClientReportMalwareRequest
- SetModelFetchResponse
- SetClientReportPhishingResponse
- SetClientReportMalwareResponse
- GetNumReports
- GetPhishingReportTimes
- GetMalwareReportTimes
- SetCache
- TestCache
- AddFeature
- AddNonModelFeature
- CheckConfirmedMalwareUrl
- SendRequestDone
- SendMalwareRequestDone
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include <map>
#include <queue>
#include <string>
#include "base/bind.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
#include "chrome/browser/safe_browsing/client_side_detection_service.h"
#include "chrome/common/safe_browsing/client_model.pb.h"
#include "chrome/common/safe_browsing/csd.pb.h"
#include "content/public/test/test_browser_thread.h"
#include "crypto/sha2.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::StrictMock;
using ::testing::_;
using content::BrowserThread;
namespace safe_browsing {
namespace {
class MockClientSideDetectionService : public ClientSideDetectionService {
public:
MockClientSideDetectionService() : ClientSideDetectionService(NULL) {}
virtual ~MockClientSideDetectionService() {}
MOCK_METHOD1(EndFetchModel, void(ClientModelStatus));
MOCK_METHOD1(ScheduleFetchModel, void(int64));
void Schedule(int64) {
StartFetchModel();
}
void Disable(int) {
SetEnabledAndRefreshState(false);
}
private:
DISALLOW_COPY_AND_ASSIGN(MockClientSideDetectionService);
};
ACTION(QuitCurrentMessageLoop) {
base::MessageLoop::current()->Quit();
}
}
class ClientSideDetectionServiceTest : public testing::Test {
protected:
virtual void SetUp() {
file_thread_.reset(new content::TestBrowserThread(BrowserThread::FILE,
&msg_loop_));
factory_.reset(new net::FakeURLFetcherFactory(NULL));
browser_thread_.reset(new content::TestBrowserThread(BrowserThread::UI,
&msg_loop_));
}
virtual void TearDown() {
msg_loop_.RunUntilIdle();
csd_service_.reset();
file_thread_.reset();
browser_thread_.reset();
}
bool SendClientReportPhishingRequest(const GURL& phishing_url,
float score) {
ClientPhishingRequest* request = new ClientPhishingRequest();
request->set_url(phishing_url.spec());
request->set_client_score(score);
request->set_is_phishing(true);
csd_service_->SendClientReportPhishingRequest(
request,
base::Bind(&ClientSideDetectionServiceTest::SendRequestDone,
base::Unretained(this)));
phishing_url_ = phishing_url;
msg_loop_.Run();
return is_phishing_;
}
bool SendClientReportMalwareRequest(const GURL& url) {
scoped_ptr<ClientMalwareRequest> request(new ClientMalwareRequest());
request->set_url(url.spec());
csd_service_->SendClientReportMalwareRequest(
request.release(),
base::Bind(&ClientSideDetectionServiceTest::SendMalwareRequestDone,
base::Unretained(this)));
phishing_url_ = url;
msg_loop_.Run();
return is_malware_;
}
void SetModelFetchResponse(std::string response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
factory_->SetFakeResponse(GURL(ClientSideDetectionService::kClientModelUrl),
response_data, response_code, status);
}
void SetClientReportPhishingResponse(std::string response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
factory_->SetFakeResponse(
ClientSideDetectionService::GetClientReportUrl(
ClientSideDetectionService::kClientReportPhishingUrl),
response_data, response_code, status);
}
void SetClientReportMalwareResponse(std::string response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
factory_->SetFakeResponse(
ClientSideDetectionService::GetClientReportUrl(
ClientSideDetectionService::kClientReportMalwareUrl),
response_data, response_code, status);
}
int GetNumReports(std::queue<base::Time>* report_times) {
return csd_service_->GetNumReports(report_times);
}
std::queue<base::Time>& GetPhishingReportTimes() {
return csd_service_->phishing_report_times_;
}
std::queue<base::Time>& GetMalwareReportTimes() {
return csd_service_->malware_report_times_;
}
void SetCache(const GURL& gurl, bool is_phishing, base::Time time) {
csd_service_->cache_[gurl] =
make_linked_ptr(new ClientSideDetectionService::CacheState(is_phishing,
time));
}
void TestCache() {
ClientSideDetectionService::PhishingCache& cache = csd_service_->cache_;
base::Time now = base::Time::Now();
base::Time time =
now - base::TimeDelta::FromDays(
ClientSideDetectionService::kNegativeCacheIntervalDays) +
base::TimeDelta::FromMinutes(5);
cache[GURL("http://first.url.com/")] =
make_linked_ptr(new ClientSideDetectionService::CacheState(false,
time));
time =
now - base::TimeDelta::FromDays(
ClientSideDetectionService::kNegativeCacheIntervalDays) -
base::TimeDelta::FromHours(1);
cache[GURL("http://second.url.com/")] =
make_linked_ptr(new ClientSideDetectionService::CacheState(false,
time));
time =
now - base::TimeDelta::FromMinutes(
ClientSideDetectionService::kPositiveCacheIntervalMinutes) -
base::TimeDelta::FromMinutes(5);
cache[GURL("http://third.url.com/")] =
make_linked_ptr(new ClientSideDetectionService::CacheState(true, time));
time =
now - base::TimeDelta::FromMinutes(
ClientSideDetectionService::kPositiveCacheIntervalMinutes) +
base::TimeDelta::FromMinutes(5);
cache[GURL("http://fourth.url.com/")] =
make_linked_ptr(new ClientSideDetectionService::CacheState(true, time));
csd_service_->UpdateCache();
EXPECT_EQ(3U, cache.size());
EXPECT_TRUE(cache.find(GURL("http://first.url.com/")) != cache.end());
EXPECT_TRUE(cache.find(GURL("http://third.url.com/")) != cache.end());
EXPECT_TRUE(cache.find(GURL("http://fourth.url.com/")) != cache.end());
bool is_phishing;
EXPECT_TRUE(csd_service_->GetValidCachedResult(
GURL("http://first.url.com"), &is_phishing));
EXPECT_FALSE(is_phishing);
EXPECT_FALSE(csd_service_->GetValidCachedResult(
GURL("http://third.url.com"), &is_phishing));
EXPECT_TRUE(csd_service_->GetValidCachedResult(
GURL("http://fourth.url.com"), &is_phishing));
EXPECT_TRUE(is_phishing);
}
void AddFeature(const std::string& name, double value,
ClientPhishingRequest* request) {
ClientPhishingRequest_Feature* feature = request->add_feature_map();
feature->set_name(name);
feature->set_value(value);
}
void AddNonModelFeature(const std::string& name, double value,
ClientPhishingRequest* request) {
ClientPhishingRequest_Feature* feature =
request->add_non_model_feature_map();
feature->set_name(name);
feature->set_value(value);
}
void CheckConfirmedMalwareUrl(GURL url) {
ASSERT_EQ(confirmed_malware_url_, url);
}
protected:
scoped_ptr<ClientSideDetectionService> csd_service_;
scoped_ptr<net::FakeURLFetcherFactory> factory_;
base::MessageLoop msg_loop_;
private:
void SendRequestDone(GURL phishing_url, bool is_phishing) {
ASSERT_EQ(phishing_url, phishing_url_);
is_phishing_ = is_phishing;
msg_loop_.Quit();
}
void SendMalwareRequestDone(GURL original_url, GURL malware_url,
bool is_malware) {
ASSERT_EQ(phishing_url_, original_url);
confirmed_malware_url_ = malware_url;
is_malware_ = is_malware;
msg_loop_.Quit();
}
scoped_ptr<content::TestBrowserThread> browser_thread_;
scoped_ptr<content::TestBrowserThread> file_thread_;
GURL phishing_url_;
GURL confirmed_malware_url_;
bool is_phishing_;
bool is_malware_;
};
TEST_F(ClientSideDetectionServiceTest, FetchModelTest) {
MockClientSideDetectionService service;
EXPECT_CALL(service, ScheduleFetchModel(_)).Times(1);
service.SetEnabledAndRefreshState(true);
SetModelFetchResponse("blamodel", net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_FETCH_FAILED))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
SetModelFetchResponse(std::string(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(ClientSideDetectionService::MODEL_EMPTY))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
SetModelFetchResponse(
std::string(ClientSideDetectionService::kMaxModelSizeBytes + 1, 'x'),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_TOO_LARGE))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
SetModelFetchResponse("Invalid model file", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_PARSE_ERROR))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
ClientSideModel model;
model.set_max_words_per_term(4);
SetModelFetchResponse(model.SerializePartialAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_MISSING_FIELDS))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
model.set_version(10);
model.add_hashes("bla");
model.add_page_term(1);
SetModelFetchResponse(model.SerializePartialAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_BAD_HASH_IDS))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
model.set_page_term(0, 0);
model.set_version(-1);
SetModelFetchResponse(model.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_INVALID_VERSION_NUMBER))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
model.set_version(10);
SetModelFetchResponse(model.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_SUCCESS))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
service.model_.reset(new ClientSideModel(model));
service.model_->set_version(11);
SetModelFetchResponse(model.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_INVALID_VERSION_NUMBER))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
service.model_->set_version(10);
SetModelFetchResponse(model.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(service, EndFetchModel(
ClientSideDetectionService::MODEL_NOT_CHANGED))
.WillOnce(QuitCurrentMessageLoop());
service.StartFetchModel();
msg_loop_.Run();
Mock::VerifyAndClearExpectations(&service);
}
TEST_F(ClientSideDetectionServiceTest, ServiceObjectDeletedBeforeCallbackDone) {
SetModelFetchResponse("bogus model", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
csd_service_.reset(ClientSideDetectionService::Create(NULL));
csd_service_->SetEnabledAndRefreshState(true);
EXPECT_TRUE(csd_service_.get() != NULL);
csd_service_.reset();
msg_loop_.RunUntilIdle();
}
TEST_F(ClientSideDetectionServiceTest, SendClientReportPhishingRequest) {
SetModelFetchResponse("bogus model", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
csd_service_.reset(ClientSideDetectionService::Create(NULL));
csd_service_->SetEnabledAndRefreshState(true);
GURL url("http://a.com/");
float score = 0.4f;
base::Time before = base::Time::Now();
SetClientReportPhishingResponse("invalid proto response", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_FALSE(SendClientReportPhishingRequest(url, score));
ClientPhishingResponse response;
response.set_phishy(true);
SetClientReportPhishingResponse(response.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_TRUE(SendClientReportPhishingRequest(url, score));
GURL second_url("http://b.com/");
response.set_phishy(false);
SetClientReportPhishingResponse(response.SerializeAsString(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
EXPECT_FALSE(SendClientReportPhishingRequest(second_url, score));
base::Time after = base::Time::Now();
std::queue<base::Time>& report_times = GetPhishingReportTimes();
EXPECT_EQ(3U, report_times.size());
while (!report_times.empty()) {
base::Time time = report_times.back();
report_times.pop();
EXPECT_LE(before, time);
EXPECT_GE(after, time);
}
bool is_phishing;
EXPECT_TRUE(csd_service_->IsInCache(url));
EXPECT_TRUE(csd_service_->GetValidCachedResult(url, &is_phishing));
EXPECT_TRUE(is_phishing);
EXPECT_FALSE(csd_service_->IsInCache(second_url));
}
TEST_F(ClientSideDetectionServiceTest, SendClientReportMalwareRequest) {
SetModelFetchResponse("bogus model", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
csd_service_.reset(ClientSideDetectionService::Create(NULL));
csd_service_->SetEnabledAndRefreshState(true);
GURL url("http://a.com/");
base::Time before = base::Time::Now();
SetClientReportMalwareResponse("invalid proto response", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_FALSE(SendClientReportMalwareRequest(url));
ClientMalwareResponse response;
response.set_blacklist(true);
SetClientReportMalwareResponse(response.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_FALSE(SendClientReportMalwareRequest(url));
response.set_blacklist(true);
response.set_bad_url("http://response-bad.com/");
SetClientReportMalwareResponse(response.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_TRUE(SendClientReportMalwareRequest(url));
CheckConfirmedMalwareUrl(GURL("http://response-bad.com/"));
response.set_blacklist(false);
SetClientReportMalwareResponse(response.SerializeAsString(),
net::HTTP_INTERNAL_SERVER_ERROR,
net::URLRequestStatus::FAILED);
EXPECT_FALSE(SendClientReportMalwareRequest(url));
response.set_blacklist(false);
SetClientReportMalwareResponse(response.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_FALSE(SendClientReportMalwareRequest(url));
base::Time after = base::Time::Now();
std::queue<base::Time>& report_times = GetMalwareReportTimes();
EXPECT_EQ(5U, report_times.size());
EXPECT_TRUE(csd_service_->OverMalwareReportLimit());
report_times = GetMalwareReportTimes();
EXPECT_EQ(5U, report_times.size());
while (!report_times.empty()) {
base::Time time = report_times.back();
report_times.pop();
EXPECT_LE(before, time);
EXPECT_GE(after, time);
}
}
TEST_F(ClientSideDetectionServiceTest, GetNumReportTest) {
SetModelFetchResponse("bogus model", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
csd_service_.reset(ClientSideDetectionService::Create(NULL));
std::queue<base::Time>& report_times = GetPhishingReportTimes();
base::Time now = base::Time::Now();
base::TimeDelta twenty_five_hours = base::TimeDelta::FromHours(25);
report_times.push(now - twenty_five_hours);
report_times.push(now - twenty_five_hours);
report_times.push(now);
report_times.push(now);
EXPECT_EQ(2, GetNumReports(&report_times));
}
TEST_F(ClientSideDetectionServiceTest, CacheTest) {
SetModelFetchResponse("bogus model", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
csd_service_.reset(ClientSideDetectionService::Create(NULL));
TestCache();
}
TEST_F(ClientSideDetectionServiceTest, IsPrivateIPAddress) {
SetModelFetchResponse("bogus model", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
csd_service_.reset(ClientSideDetectionService::Create(NULL));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("10.1.2.3"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("127.0.0.1"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("172.24.3.4"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("192.168.1.1"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("fc00::"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("fec0::"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("fec0:1:2::3"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("::1"));
EXPECT_FALSE(csd_service_->IsPrivateIPAddress("1.2.3.4"));
EXPECT_FALSE(csd_service_->IsPrivateIPAddress("200.1.1.1"));
EXPECT_FALSE(csd_service_->IsPrivateIPAddress("2001:0db8:ac10:fe01::"));
EXPECT_TRUE(csd_service_->IsPrivateIPAddress("blah"));
}
TEST_F(ClientSideDetectionServiceTest, SetBadSubnets) {
ClientSideModel model;
ClientSideDetectionService::BadSubnetMap bad_subnets;
ClientSideDetectionService::SetBadSubnets(model, &bad_subnets);
EXPECT_EQ(0U, bad_subnets.size());
ClientSideModel::IPSubnet* subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(crypto::kSHA256Length, '.'));
subnet->set_size(130);
subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(crypto::kSHA256Length, '.'));
subnet->set_size(-1);
subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(16, '.'));
subnet->set_size(64);
ClientSideDetectionService::SetBadSubnets(model, &bad_subnets);
EXPECT_EQ(0U, bad_subnets.size());
subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(crypto::kSHA256Length, '.'));
subnet->set_size(64);
subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(crypto::kSHA256Length, ','));
subnet->set_size(64);
subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(crypto::kSHA256Length, '.'));
subnet->set_size(128);
subnet = model.add_bad_subnet();
subnet->set_prefix(std::string(crypto::kSHA256Length, '.'));
subnet->set_size(100);
ClientSideDetectionService::SetBadSubnets(model, &bad_subnets);
EXPECT_EQ(3U, bad_subnets.size());
ClientSideDetectionService::BadSubnetMap::const_iterator it;
std::string mask = std::string(8, '\xFF') + std::string(8, '\x00');
EXPECT_TRUE(bad_subnets.count(mask));
EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, '.')));
EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, ',')));
mask = std::string(16, '\xFF');
EXPECT_TRUE(bad_subnets.count(mask));
EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, '.')));
mask = std::string(12, '\xFF') + "\xF0" + std::string(3, '\x00');
EXPECT_TRUE(bad_subnets.count(mask));
EXPECT_TRUE(bad_subnets[mask].count(std::string(crypto::kSHA256Length, '.')));
}
TEST_F(ClientSideDetectionServiceTest, ModelHasValidHashIds) {
ClientSideModel model;
EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model));
model.add_hashes("bla");
EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model));
model.add_page_term(0);
EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model));
model.add_page_term(-1);
EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model));
model.set_page_term(1, 1);
EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model));
model.set_page_term(1, 0);
EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model));
model.add_hashes("blu");
ClientSideModel::Rule* rule = model.add_rule();
rule->add_feature(0);
rule->add_feature(1);
rule->set_weight(0.1f);
EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model));
rule = model.add_rule();
rule->add_feature(0);
rule->add_feature(1);
rule->add_feature(-1);
rule->set_weight(0.2f);
EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model));
rule->set_feature(2, 2);
EXPECT_FALSE(ClientSideDetectionService::ModelHasValidHashIds(model));
rule->set_feature(2, 1);
EXPECT_TRUE(ClientSideDetectionService::ModelHasValidHashIds(model));
}
TEST_F(ClientSideDetectionServiceTest, SetEnabledAndRefreshState) {
csd_service_.reset(ClientSideDetectionService::Create(NULL));
EXPECT_FALSE(csd_service_->enabled());
EXPECT_TRUE(csd_service_->model_fetcher_.get() == NULL);
MockClientSideDetectionService* service =
new StrictMock<MockClientSideDetectionService>();
csd_service_.reset(service);
EXPECT_FALSE(csd_service_->enabled());
EXPECT_TRUE(csd_service_->model_fetcher_.get() == NULL);
Mock::VerifyAndClearExpectations(service);
ClientSideModel model;
model.set_version(10);
model.set_max_words_per_term(4);
SetModelFetchResponse(model.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_CALL(*service, ScheduleFetchModel(_))
.WillOnce(Invoke(service, &MockClientSideDetectionService::Schedule));
EXPECT_CALL(*service, EndFetchModel(
ClientSideDetectionService::MODEL_SUCCESS))
.WillOnce(QuitCurrentMessageLoop());
csd_service_->SetEnabledAndRefreshState(true);
EXPECT_TRUE(csd_service_->model_fetcher_.get() != NULL);
msg_loop_.Run();
Mock::VerifyAndClearExpectations(service);
csd_service_->SetEnabledAndRefreshState(true);
Mock::VerifyAndClearExpectations(service);
EXPECT_CALL(*service, ScheduleFetchModel(_))
.WillOnce(Invoke(service, &MockClientSideDetectionService::Schedule));
csd_service_->SetEnabledAndRefreshState(false);
csd_service_->SetEnabledAndRefreshState(true);
Mock::VerifyAndClearExpectations(service);
EXPECT_TRUE(csd_service_->model_fetcher_.get() != NULL);
csd_service_->SetEnabledAndRefreshState(false);
EXPECT_TRUE(csd_service_->model_fetcher_.get() == NULL);
msg_loop_.RunUntilIdle();
Mock::VerifyAndClearExpectations(service);
ClientPhishingResponse response;
response.set_phishy(true);
SetClientReportPhishingResponse(response.SerializeAsString(), net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_FALSE(SendClientReportPhishingRequest(GURL("http://a.com/"), 0.4f));
EXPECT_CALL(*service, ScheduleFetchModel(_))
.WillOnce(Invoke(service, &MockClientSideDetectionService::Schedule));
EXPECT_CALL(*service, EndFetchModel(
ClientSideDetectionService::MODEL_NOT_CHANGED))
.WillOnce(Invoke(service, &MockClientSideDetectionService::Disable));
csd_service_->SetEnabledAndRefreshState(true);
EXPECT_FALSE(SendClientReportPhishingRequest(GURL("http://a.com/"), 0.4f));
Mock::VerifyAndClearExpectations(service);
}
}