Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1648)

Unified Diff: chrome/browser/search/suggestions/suggestions_service_unittest.cc

Issue 330473003: Offline blacklisting for SuggestionsService. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add UMA logging of local blacklist Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/search/suggestions/suggestions_service_unittest.cc
diff --git a/chrome/browser/search/suggestions/suggestions_service_unittest.cc b/chrome/browser/search/suggestions/suggestions_service_unittest.cc
index 674d7bc941b4c317cbd4eb517404d3ed5b82a2fe..1d6a2c6715f8d67f4dc86e4f1d4a3b8c34ac4625 100644
--- a/chrome/browser/search/suggestions/suggestions_service_unittest.cc
+++ b/chrome/browser/search/suggestions/suggestions_service_unittest.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/search/suggestions/suggestions_service.h"
#include <map>
+#include <sstream>
#include <string>
#include "base/bind.h"
@@ -13,6 +14,7 @@
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/history/history_types.h"
+#include "chrome/browser/search/suggestions/blacklist_store.h"
#include "chrome/browser/search/suggestions/proto/suggestions.pb.h"
#include "chrome/browser/search/suggestions/suggestions_service_factory.h"
#include "chrome/browser/search/suggestions/suggestions_store.h"
@@ -28,15 +30,19 @@
#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::StrictMock;
using ::testing::_;
namespace {
const char kFakeSuggestionsURL[] = "https://mysuggestions.com/proto";
-const char kFakeSuggestionsSuffix[] = "?foo=bar";
-const char kFakeBlacklistSuffix[] = "/blacklist?foo=bar&baz=";
+const char kFakeSuggestionsCommonParams[] = "foo=bar";
+const char kFakeBlacklistPath[] = "/blacklist";
+const char kFakeBlacklistUrlParam[] = "baz";
const char kTestTitle[] = "a title";
const char kTestUrl[] = "http://go.com";
@@ -58,6 +64,14 @@ scoped_ptr<net::FakeURLFetcher> CreateURLFetcher(
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
@@ -90,6 +104,14 @@ class MockSuggestionsStore : public suggestions::SuggestionsStore {
MOCK_METHOD0(ClearSuggestions, void());
};
+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*));
+};
+
} // namespace
class SuggestionsServiceTest : public testing::Test {
@@ -121,8 +143,9 @@ class SuggestionsServiceTest : public testing::Test {
// Enables the "ChromeSuggestions.Group1" field trial.
void EnableFieldTrial(const std::string& url,
- const std::string& suggestions_suffix,
- const std::string& blacklist_suffix) {
+ const std::string& common_params,
+ const std::string& blacklist_path,
+ const std::string& blacklist_url_param) {
// Clear the existing |field_trial_list_| to avoid firing a DCHECK.
field_trial_list_.reset(NULL);
field_trial_list_.reset(
@@ -133,8 +156,9 @@ class SuggestionsServiceTest : public testing::Test {
params[kSuggestionsFieldTrialStateParam] =
kSuggestionsFieldTrialStateEnabled;
params[kSuggestionsFieldTrialURLParam] = url;
- params[kSuggestionsFieldTrialSuggestionsSuffixParam] = suggestions_suffix;
- params[kSuggestionsFieldTrialBlacklistSuffixParam] = blacklist_suffix;
+ params[kSuggestionsFieldTrialCommonParamsParam] = common_params;
+ params[kSuggestionsFieldTrialBlacklistPathParam] = blacklist_path;
+ params[kSuggestionsFieldTrialBlacklistUrlParamParam] = blacklist_url_param;
chrome_variations::AssociateVariationParams(kSuggestionsFieldTrialName,
"Group1", params);
field_trial_ = base::FieldTrialList::CreateFieldTrial(
@@ -150,25 +174,27 @@ class SuggestionsServiceTest : public testing::Test {
// Should not be called more than once per test since it stashes the
// SuggestionsStore in |mock_suggestions_store_|.
- SuggestionsService* CreateSuggestionsServiceWithMockStore() {
+ SuggestionsService* CreateSuggestionsServiceWithMocks() {
mock_suggestions_store_ = new StrictMock<MockSuggestionsStore>();
+ mock_blacklist_store_ = new MockBlacklistStore();
return new SuggestionsService(
- profile_.get(), scoped_ptr<SuggestionsStore>(mock_suggestions_store_));
+ profile_.get(), scoped_ptr<SuggestionsStore>(mock_suggestions_store_),
+ scoped_ptr<BlacklistStore>(mock_blacklist_store_));
}
void FetchSuggestionsDataNoTimeoutHelper(bool interleaved_requests) {
// Field trial enabled with a specific suggestions URL.
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam);
scoped_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMockStore());
+ CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
scoped_ptr<SuggestionsProfile> suggestions_profile(
CreateSuggestionsProfile());
// Set up net::FakeURLFetcherFactory.
std::string expected_url =
- std::string(kFakeSuggestionsURL) + kFakeSuggestionsSuffix;
+ (std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams;
factory_.SetFakeResponse(GURL(expected_url),
suggestions_profile->SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
@@ -177,13 +203,20 @@ class SuggestionsServiceTest : public testing::Test {
// 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 = 2;
- if (interleaved_requests)
- expected_count = 1;
+ if (interleaved_requests) expected_count = 1;
EXPECT_CALL(*mock_suggestions_store_,
StoreSuggestions(EqualsProto(*suggestions_profile)))
.Times(expected_count)
.WillRepeatedly(Return(true));
+ // 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)));
@@ -204,9 +237,9 @@ class SuggestionsServiceTest : public testing::Test {
protected:
net::FakeURLFetcherFactory factory_;
- // Only used if the SuggestionsService is built with a MockSuggestionsStore.
- // Not owned.
+ // Only used if the SuggestionsService is built with a mocks. Not owned.
MockSuggestionsStore* mock_suggestions_store_;
+ MockBlacklistStore* mock_blacklist_store_;
private:
content::TestBrowserThreadBundle thread_bundle_;
@@ -223,7 +256,7 @@ TEST_F(SuggestionsServiceTest, ServiceBeingCreated) {
EXPECT_TRUE(CreateSuggestionsService() == NULL);
// Field trial enabled.
- EnableFieldTrial("", "", "");
+ EnableFieldTrial("", "", "", "");
EXPECT_TRUE(CreateSuggestionsService() != NULL);
}
@@ -237,15 +270,15 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoTimeoutInterleaved) {
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) {
// Field trial enabled with a specific suggestions URL.
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam);
scoped_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMockStore());
+ CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
// Fake a request error.
std::string expected_url =
- std::string(kFakeSuggestionsURL) + kFakeSuggestionsSuffix;
+ (std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams;
factory_.SetFakeResponse(GURL(expected_url), "irrelevant", net::HTTP_OK,
net::URLRequestStatus::FAILED);
@@ -253,6 +286,12 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) {
EXPECT_CALL(*mock_suggestions_store_, LoadSuggestions(_))
.WillOnce(Return(true));
+ // 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(
base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile,
@@ -267,15 +306,15 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) {
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) {
// Field trial enabled with a specific suggestions URL.
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam);
scoped_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMockStore());
+ CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
// Response code != 200.
std::string expected_url =
- std::string(kFakeSuggestionsURL) + kFakeSuggestionsSuffix;
+ (std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams;
factory_.SetFakeResponse(GURL(expected_url), "irrelevant",
net::HTTP_BAD_REQUEST,
net::URLRequestStatus::SUCCESS);
@@ -283,6 +322,11 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) {
// 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(
base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile,
@@ -296,18 +340,17 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) {
}
TEST_F(SuggestionsServiceTest, BlacklistURL) {
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam);
scoped_ptr<SuggestionsService> suggestions_service(
- CreateSuggestionsServiceWithMockStore());
+ CreateSuggestionsServiceWithMocks());
EXPECT_TRUE(suggestions_service != NULL);
- std::string expected_url(kFakeSuggestionsURL);
- expected_url.append(kFakeBlacklistSuffix)
- .append(net::EscapeQueryParamValue(GURL(kBlacklistUrl).spec(), true));
+ GURL blacklist_url(kBlacklistUrl);
+ std::string request_url = GetExpectedBlacklistRequestUrl(blacklist_url);
scoped_ptr<SuggestionsProfile> suggestions_profile(
CreateSuggestionsProfile());
- factory_.SetFakeResponse(GURL(expected_url),
+ factory_.SetFakeResponse(GURL(request_url),
suggestions_profile->SerializeAsString(),
net::HTTP_OK, net::URLRequestStatus::SUCCESS);
@@ -316,11 +359,19 @@ TEST_F(SuggestionsServiceTest, BlacklistURL) {
StoreSuggestions(EqualsProto(*suggestions_profile)))
.WillOnce(Return(true));
+ // 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(
- GURL(kBlacklistUrl),
- base::Bind(&SuggestionsServiceTest::CheckSuggestionsData,
- base::Unretained(this)));
+ blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData,
+ base::Unretained(this)));
// (Testing only) wait until blacklist request is complete.
base::MessageLoop::current()->RunUntilIdle();
@@ -329,4 +380,108 @@ TEST_F(SuggestionsServiceTest, BlacklistURL) {
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);
+ scoped_ptr<SuggestionsService> suggestions_service(
+ CreateSuggestionsServiceWithMocks());
+ EXPECT_TRUE(suggestions_service != NULL);
+ suggestions_service->SetBlacklistDelay(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.
Mathieu 2014/06/18 13:56:23 Can this be a bit closer to the "second request"
manzagop (departed) 2014/06/18 18:44:55 I believe (could be wrong) all expectations should
+ 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));
+
+ // 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.
+ base::MessageLoop::current()->RunUntilIdle();
+ base::MessageLoop::current()->RunUntilIdle();
Mathieu 2014/06/18 13:56:23 pretty sure two calls is redundant
manzagop (departed) 2014/06/18 18:44:55 Done.
+
+ // Ensure that CheckSuggestionsData() ran once.
+ EXPECT_EQ(1, suggestions_data_check_count_);
+}
+
+TEST_F(SuggestionsServiceTest, GetBlacklistedUrl) {
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam);
+
+ 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->GetBlacklistDelay();
+
+ // Delay unchanged on success.
+ suggestions_service->UpdateBlacklistDelay(true);
+ EXPECT_EQ(initial_delay, suggestions_service->GetBlacklistDelay());
+
+ // Delay increases on failure.
+ suggestions_service->UpdateBlacklistDelay(false);
+ EXPECT_GE(suggestions_service->GetBlacklistDelay(), initial_delay);
Mathieu 2014/06/18 13:56:23 EXPECT_GT?
manzagop (departed) 2014/06/18 18:44:55 Done. You're right it's probably better to break t
+
+ // Delay resets on success.
+ suggestions_service->UpdateBlacklistDelay(true);
+ EXPECT_EQ(initial_delay, suggestions_service->GetBlacklistDelay());
+}
+
} // namespace suggestions

Powered by Google App Engine
This is Rietveld 408576698