blob: a4d60585866e9e7bc448099af68066cc455a56ed [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/suggestions/suggestions_service.h"
#include <map>
#include <sstream>
#include <string>
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/field_trial.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "components/suggestions/blacklist_store.h"
#include "components/suggestions/image_manager.h"
#include "components/suggestions/proto/suggestions.pb.h"
#include "components/suggestions/suggestions_store.h"
#include "components/suggestions/suggestions_utils.h"
#include "components/variations/entropy_provider.h"
#include "components/variations/variations_associated_data.h"
#include "net/http/http_response_headers.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 "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::DoAll;
using ::testing::Eq;
using ::testing::Return;
using testing::SetArgPointee;
using ::testing::NiceMock;
using ::testing::StrictMock;
using ::testing::_;
namespace {
const char kFakeSuggestionsURL[] = "https://mysuggestions.com/proto";
const char kFakeSuggestionsCommonParams[] = "foo=bar";
const char kFakeBlacklistPath[] = "/blacklist";
const char kFakeBlacklistUrlParam[] = "baz";
const char kTestTitle[] = "a title";
const char kTestUrl[] = "http://go.com";
const char kBlacklistUrl[] = "http://blacklist.com";
const int64 kTestDefaultExpiry = 1402200000000000;
const int64 kTestSetExpiry = 1404792000000000;
scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
const GURL& url, net::URLFetcherDelegate* delegate,
const std::string& response_data, net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
scoped_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher(
url, delegate, response_data, response_code, status));
if (response_code == net::HTTP_OK) {
scoped_refptr<net::HttpResponseHeaders> download_headers(
new net::HttpResponseHeaders(""));
download_headers->AddHeader("Content-Type: text/html");
fetcher->set_response_headers(download_headers);
}
return fetcher.Pass();
}
std::string GetExpectedBlacklistRequestUrl(const GURL& blacklist_url) {
std::stringstream request_url;
request_url << kFakeSuggestionsURL << kFakeBlacklistPath << "?"
<< kFakeSuggestionsCommonParams << "&" << kFakeBlacklistUrlParam
<< "=" << net::EscapeQueryParamValue(blacklist_url.spec(), true);
return request_url.str();
}
// GMock matcher for protobuf equality.
MATCHER_P(EqualsProto, message, "") {
// This implementation assumes protobuf serialization is deterministic, which
// is true in practice but technically not something that code is supposed
// to rely on. However, it vastly simplifies the implementation.
std::string expected_serialized, actual_serialized;
message.SerializeToString(&expected_serialized);
arg.SerializeToString(&actual_serialized);
return expected_serialized == actual_serialized;
}
} // namespace
namespace suggestions {
scoped_ptr<SuggestionsProfile> CreateSuggestionsProfile() {
scoped_ptr<SuggestionsProfile> profile(new SuggestionsProfile());
ChromeSuggestion* suggestion = profile->add_suggestions();
suggestion->set_title(kTestTitle);
suggestion->set_url(kTestUrl);
suggestion->set_expiry_ts(kTestSetExpiry);
return profile.Pass();
}
// Creates one suggestion with expiry timestamp and one without.
SuggestionsProfile CreateSuggestionsProfileWithExpiryTimestamps() {
SuggestionsProfile profile;
ChromeSuggestion* suggestion = profile.add_suggestions();
suggestion->set_title(kTestTitle);
suggestion->set_url(kTestUrl);
suggestion->set_expiry_ts(kTestSetExpiry);
suggestion = profile.add_suggestions();
suggestion->set_title(kTestTitle);
suggestion->set_url(kTestUrl);
return profile;
}
class MockSuggestionsStore : public suggestions::SuggestionsStore {
public:
MOCK_METHOD1(LoadSuggestions, bool(SuggestionsProfile*));
MOCK_METHOD1(StoreSuggestions, bool(const SuggestionsProfile&));
MOCK_METHOD0(ClearSuggestions, void());
};
class MockImageManager : public suggestions::ImageManager {
public:
MockImageManager() {}
virtual ~MockImageManager() {}
MOCK_METHOD1(Initialize, void(const SuggestionsProfile&));
MOCK_METHOD2(GetImageForURL,
void(const GURL&,
base::Callback<void(const GURL&, const SkBitmap*)>));
};
class MockBlacklistStore : public suggestions::BlacklistStore {
public:
MOCK_METHOD1(BlacklistUrl, bool(const GURL&));
MOCK_METHOD1(GetFirstUrlFromBlacklist, bool(GURL*));
MOCK_METHOD1(RemoveUrl, bool(const GURL&));
MOCK_METHOD1(FilterSuggestions, void(SuggestionsProfile*));
};
class SuggestionsServiceTest : public testing::Test {
public:
void CheckSuggestionsData(const SuggestionsProfile& suggestions_profile) {
EXPECT_EQ(1, suggestions_profile.suggestions_size());
EXPECT_EQ(kTestTitle, suggestions_profile.suggestions(0).title());
EXPECT_EQ(kTestUrl, suggestions_profile.suggestions(0).url());
++suggestions_data_check_count_;
}
void ExpectEmptySuggestionsProfile(const SuggestionsProfile& profile) {
EXPECT_EQ(0, profile.suggestions_size());
++suggestions_empty_data_count_;
}
int suggestions_data_check_count_;
int suggestions_empty_data_count_;
protected:
SuggestionsServiceTest()
: suggestions_data_check_count_(0),
suggestions_empty_data_count_(0),
factory_(NULL, base::Bind(&CreateURLFetcher)),
mock_suggestions_store_(NULL),
mock_thumbnail_manager_(NULL) {}
virtual ~SuggestionsServiceTest() {}
virtual void SetUp() OVERRIDE {
request_context_ = new net::TestURLRequestContextGetter(
io_message_loop_.message_loop_proxy());
}
// Enables the "ChromeSuggestions.Group1" field trial.
void EnableFieldTrial(const std::string& url,
const std::string& common_params,
const std::string& blacklist_path,
const std::string& blacklist_url_param,
bool control_group) {
// Clear the existing |field_trial_list_| to avoid firing a DCHECK.
field_trial_list_.reset(NULL);
field_trial_list_.reset(
new base::FieldTrialList(new metrics::SHA1EntropyProvider("foo")));
variations::testing::ClearAllVariationParams();
std::map<std::string, std::string> params;
params[kSuggestionsFieldTrialStateParam] =
kSuggestionsFieldTrialStateEnabled;
if (control_group) {
params[kSuggestionsFieldTrialControlParam] =
kSuggestionsFieldTrialStateEnabled;
}
params[kSuggestionsFieldTrialURLParam] = url;
params[kSuggestionsFieldTrialCommonParamsParam] = common_params;
params[kSuggestionsFieldTrialBlacklistPathParam] = blacklist_path;
params[kSuggestionsFieldTrialBlacklistUrlParam] = blacklist_url_param;
variations::AssociateVariationParams(kSuggestionsFieldTrialName, "Group1",
params);
field_trial_ = base::FieldTrialList::CreateFieldTrial(
kSuggestionsFieldTrialName, "Group1");
field_trial_->group();
}
// Should not be called more than once per test since it stashes the
// SuggestionsStore in |mock_suggestions_store_|.
SuggestionsService* CreateSuggestionsServiceWithMocks() {
mock_suggestions_store_ = new StrictMock<MockSuggestionsStore>();
mock_thumbnail_manager_ = new StrictMock<MockImageManager>();
mock_blacklist_store_ = new MockBlacklistStore();
return new SuggestionsService(
request_context_, scoped_ptr<SuggestionsStore>(mock_suggestions_store_),
scoped_ptr<ImageManager>(mock_thumbnail_manager_),
scoped_ptr<BlacklistStore>(mock_blacklist_store_));
}
void FetchSuggestionsDataNoTimeoutHelper(bool interleaved_requests) {
// Field trial enabled with a specific suggestions URL.
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
scoped_ptr<SuggestionsProfile> suggestions_profile(
CreateSuggestionsProfile());
// Set up net::FakeURLFetcherFactory.
std::string expected_url =
(std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams;
factory_.SetFakeResponse(GURL(expected_url),
suggestions_profile->SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
// Set up expectations on the SuggestionsStore. The number depends on
// whether the second request is issued (it won't be issued if the second
// fetch occurs before the first request has completed).
int expected_count = interleaved_requests ? 1 : 2;
EXPECT_CALL(*mock_suggestions_store_,
StoreSuggestions(EqualsProto(*suggestions_profile)))
.Times(expected_count)
.WillRepeatedly(Return(true));
// Since there are two requests below, Initialize() will be called twice.
EXPECT_CALL(*mock_thumbnail_manager_,
Initialize(EqualsProto(*suggestions_profile)))
.Times(expected_count);
// Expect a call to the blacklist store. Return that there's nothing to
// blacklist.
EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_))
.Times(expected_count);
EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_))
.Times(expected_count)
.WillRepeatedly(Return(false));
// Send the request. The data will be returned to the callback.
suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind(
&SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this)));
if (!interleaved_requests)
io_message_loop_.RunUntilIdle(); // Let request complete.
// Send the request a second time.
suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind(
&SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this)));
// (Testing only) wait until suggestion fetch is complete.
io_message_loop_.RunUntilIdle();
// Ensure that CheckSuggestionsData() ran twice.
EXPECT_EQ(2, suggestions_data_check_count_);
}
protected:
base::MessageLoopForIO io_message_loop_;
net::FakeURLFetcherFactory factory_;
// Only used if the SuggestionsService is built with mocks. Not owned.
MockSuggestionsStore* mock_suggestions_store_;
MockImageManager* mock_thumbnail_manager_;
MockBlacklistStore* mock_blacklist_store_;
scoped_refptr<net::TestURLRequestContextGetter> request_context_;
private:
scoped_ptr<base::FieldTrialList> field_trial_list_;
scoped_refptr<base::FieldTrial> field_trial_;
DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest);
};
TEST_F(SuggestionsServiceTest, IsControlGroup) {
// Field trial enabled.
EnableFieldTrial("", "", "", "", false);
EXPECT_FALSE(SuggestionsService::IsControlGroup());
EnableFieldTrial("", "", "", "", true);
EXPECT_TRUE(SuggestionsService::IsControlGroup());
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoTimeout) {
FetchSuggestionsDataNoTimeoutHelper(false);
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoTimeoutInterleaved) {
FetchSuggestionsDataNoTimeoutHelper(true);
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) {
// Field trial enabled with a specific suggestions URL.
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
// Fake a request error.
std::string expected_url =
(std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams;
factory_.SetFakeResponse(GURL(expected_url), "irrelevant", net::HTTP_OK,
net::URLRequestStatus::FAILED);
// Set up expectations on the SuggestionsStore.
EXPECT_CALL(*mock_suggestions_store_, LoadSuggestions(_))
.WillOnce(Return(true));
EXPECT_CALL(*mock_thumbnail_manager_, Initialize(_));
// Expect a call to the blacklist store. Return that there's nothing to
// blacklist.
EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_));
EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_))
.WillOnce(Return(false));
// Send the request. Empty data will be returned to the callback.
suggestions_service->FetchSuggestionsData(
INITIALIZED_ENABLED_HISTORY, // Normal mode.
base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile,
base::Unretained(this)));
// (Testing only) wait until suggestion fetch is complete.
io_message_loop_.RunUntilIdle();
// Ensure that ExpectEmptySuggestionsProfile ran once.
EXPECT_EQ(1, suggestions_empty_data_count_);
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) {
// Field trial enabled with a specific suggestions URL.
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
// Response code != 200.
std::string expected_url =
(std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams;
factory_.SetFakeResponse(GURL(expected_url), "irrelevant",
net::HTTP_BAD_REQUEST,
net::URLRequestStatus::SUCCESS);
// Set up expectations on the SuggestionsStore.
EXPECT_CALL(*mock_suggestions_store_, ClearSuggestions());
// Expect a call to the blacklist store. Return that there's nothing to
// blacklist.
EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_))
.WillOnce(Return(false));
// Send the request. Empty data will be returned to the callback.
suggestions_service->FetchSuggestionsData(
INITIALIZED_ENABLED_HISTORY, // Normal mode.
base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile,
base::Unretained(this)));
// (Testing only) wait until suggestion fetch is complete.
io_message_loop_.RunUntilIdle();
// Ensure that ExpectEmptySuggestionsProfile ran once.
EXPECT_EQ(1, suggestions_empty_data_count_);
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncDisabled) {
// Field trial enabled with a specific suggestions URL.
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
// Set up expectations on the SuggestionsStore.
EXPECT_CALL(*mock_suggestions_store_, ClearSuggestions());
// Send the request. Cache is cleared and empty data will be returned to the
// callback.
suggestions_service->FetchSuggestionsData(
SYNC_OR_HISTORY_SYNC_DISABLED,
base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile,
base::Unretained(this)));
// Wait for posted task to complete.
base::MessageLoop::current()->RunUntilIdle();
// Ensure that ExpectEmptySuggestionsProfile ran once.
EXPECT_EQ(1, suggestions_empty_data_count_);
}
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataSyncNotInitializedEnabled) {
// Field trial enabled with a specific suggestions URL.
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
scoped_ptr<SuggestionsProfile> suggestions_profile(
CreateSuggestionsProfile());
// Expectations.
EXPECT_CALL(*mock_suggestions_store_, LoadSuggestions(_))
.WillOnce(DoAll(SetArgPointee<0>(*suggestions_profile), Return(true)));
EXPECT_CALL(*mock_thumbnail_manager_,
Initialize(EqualsProto(*suggestions_profile)));
EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_));
// Send the request. In this state, cached data will be returned to the
// caller.
suggestions_service->FetchSuggestionsData(
NOT_INITIALIZED_ENABLED,
base::Bind(&SuggestionsServiceTest::CheckSuggestionsData,
base::Unretained(this)));
// Wait for posted task to complete.
base::MessageLoop::current()->RunUntilIdle();
// Ensure that CheckSuggestionsData ran once.
EXPECT_EQ(1, suggestions_data_check_count_);
}
TEST_F(SuggestionsServiceTest, BlacklistURL) {
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
GURL blacklist_url(kBlacklistUrl);
std::string request_url = GetExpectedBlacklistRequestUrl(blacklist_url);
scoped_ptr<SuggestionsProfile> suggestions_profile(
CreateSuggestionsProfile());
factory_.SetFakeResponse(GURL(request_url),
suggestions_profile->SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
// Set up expectations on the SuggestionsStore.
EXPECT_CALL(*mock_suggestions_store_,
StoreSuggestions(EqualsProto(*suggestions_profile)))
.WillOnce(Return(true));
EXPECT_CALL(*mock_thumbnail_manager_,
Initialize(EqualsProto(*suggestions_profile)));
// Expected calls to the blacklist store.
EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklist_url)))
.WillOnce(Return(true));
EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklist_url)))
.WillOnce(Return(true));
EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_));
EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_))
.WillOnce(Return(false));
// Send the request. The data will be returned to the callback.
suggestions_service->BlacklistURL(
blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData,
base::Unretained(this)));
// (Testing only) wait until blacklist request is complete.
io_message_loop_.RunUntilIdle();
// Ensure that CheckSuggestionsData() ran once.
EXPECT_EQ(1, suggestions_data_check_count_);
}
// Initial blacklist request fails, triggering a scheduled upload which
// succeeds.
TEST_F(SuggestionsServiceTest, BlacklistURLFails) {
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
suggestions_service->set_blacklist_delay(0); // Don't wait during a test!
scoped_ptr<SuggestionsProfile> suggestions_profile(
CreateSuggestionsProfile());
GURL blacklist_url(kBlacklistUrl);
// Set up behavior for the first call to blacklist.
std::string request_url = GetExpectedBlacklistRequestUrl(blacklist_url);
factory_.SetFakeResponse(GURL(request_url), "irrelevant", net::HTTP_OK,
net::URLRequestStatus::FAILED);
// Expectations specific to the first request.
EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklist_url)))
.WillOnce(Return(true));
EXPECT_CALL(*mock_suggestions_store_, LoadSuggestions(_))
.WillOnce(DoAll(SetArgPointee<0>(*suggestions_profile), Return(true)));
// Expectations specific to the second request.
EXPECT_CALL(*mock_suggestions_store_,
StoreSuggestions(EqualsProto(*suggestions_profile)))
.WillOnce(Return(true));
EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklist_url)))
.WillOnce(Return(true));
// Expectations pertaining to both requests.
EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(2);
EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_))
.WillOnce(Return(true))
.WillOnce(DoAll(SetArgPointee<0>(blacklist_url), Return(true)))
.WillOnce(Return(false));
// There will be two calls to Initialize() (one store, one load).
EXPECT_CALL(*mock_thumbnail_manager_,
Initialize(EqualsProto(*suggestions_profile)))
.Times(2);
// Send the request. The data will be returned to the callback.
suggestions_service->BlacklistURL(
blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData,
base::Unretained(this)));
// The first FakeURLFetcher was created; we can now set up behavior for the
// second call to blacklist.
factory_.SetFakeResponse(GURL(request_url),
suggestions_profile->SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
// (Testing only) wait until both requests are complete.
io_message_loop_.RunUntilIdle();
// ... Other task gets posted to the message loop.
base::MessageLoop::current()->RunUntilIdle();
// ... And completes.
io_message_loop_.RunUntilIdle();
// Ensure that CheckSuggestionsData() ran once.
EXPECT_EQ(1, suggestions_data_check_count_);
}
TEST_F(SuggestionsServiceTest, GetBlacklistedUrl) {
EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
scoped_ptr<GURL> request_url;
scoped_ptr<net::FakeURLFetcher> fetcher;
GURL retrieved_url;
// Not a blacklist request.
request_url.reset(new GURL("http://not-blacklisting.com/a?b=c"));
fetcher = CreateURLFetcher(*request_url, NULL, "", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_FALSE(SuggestionsService::GetBlacklistedUrl(*fetcher, &retrieved_url));
// An actual blacklist request.
string blacklisted_url = "http://blacklisted.com/a?b=c&d=e";
string encoded_blacklisted_url =
"http%3A%2F%2Fblacklisted.com%2Fa%3Fb%3Dc%26d%3De";
string blacklist_request_prefix =
"https://mysuggestions.com/proto/blacklist?foo=bar&baz=";
request_url.reset(
new GURL(blacklist_request_prefix + encoded_blacklisted_url));
fetcher.reset();
fetcher = CreateURLFetcher(*request_url, NULL, "", net::HTTP_OK,
net::URLRequestStatus::SUCCESS);
EXPECT_TRUE(SuggestionsService::GetBlacklistedUrl(*fetcher, &retrieved_url));
EXPECT_EQ(blacklisted_url, retrieved_url.spec());
}
TEST_F(SuggestionsServiceTest, UpdateBlacklistDelay) {
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
int initial_delay = suggestions_service->blacklist_delay();
// Delay unchanged on success.
suggestions_service->UpdateBlacklistDelay(true);
EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay());
// Delay increases on failure.
suggestions_service->UpdateBlacklistDelay(false);
EXPECT_GT(suggestions_service->blacklist_delay(), initial_delay);
// Delay resets on success.
suggestions_service->UpdateBlacklistDelay(true);
EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay());
}
TEST_F(SuggestionsServiceTest, CheckDefaultTimeStamps) {
scoped_ptr<SuggestionsService> suggestions_service(
CreateSuggestionsServiceWithMocks());
SuggestionsProfile suggestions =
CreateSuggestionsProfileWithExpiryTimestamps();
suggestions_service->SetDefaultExpiryTimestamp(&suggestions,
kTestDefaultExpiry);
EXPECT_EQ(kTestSetExpiry, suggestions.suggestions(0).expiry_ts());
EXPECT_EQ(kTestDefaultExpiry, suggestions.suggestions(1).expiry_ts());
}
} // namespace suggestions