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

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: Rebase. 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
« no previous file with comments | « chrome/browser/search/suggestions/suggestions_service_factory.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1b4c1ad2b1167d9814c7760446d622016397fe1b..335699c16c05d418e4ed5d16f9bed8890ee3aff8 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
@@ -100,6 +114,14 @@ class MockThumbnailManager : public suggestions::ThumbnailManager {
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*));
+};
+
} // namespace
class SuggestionsServiceTest : public testing::Test {
@@ -132,8 +154,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,
bool control_group) {
// Clear the existing |field_trial_list_| to avoid firing a DCHECK.
field_trial_list_.reset(NULL);
@@ -149,8 +172,9 @@ class SuggestionsServiceTest : public testing::Test {
kSuggestionsFieldTrialStateEnabled;
}
params[kSuggestionsFieldTrialURLParam] = url;
- params[kSuggestionsFieldTrialSuggestionsSuffixParam] = suggestions_suffix;
- params[kSuggestionsFieldTrialBlacklistSuffixParam] = blacklist_suffix;
+ params[kSuggestionsFieldTrialCommonParamsParam] = common_params;
+ params[kSuggestionsFieldTrialBlacklistPathParam] = blacklist_path;
+ params[kSuggestionsFieldTrialBlacklistUrlParam] = blacklist_url_param;
chrome_variations::AssociateVariationParams(kSuggestionsFieldTrialName,
"Group1", params);
field_trial_ = base::FieldTrialList::CreateFieldTrial(
@@ -166,27 +190,29 @@ 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_thumbnail_manager_ = new StrictMock<MockThumbnailManager>();
+ mock_blacklist_store_ = new MockBlacklistStore();
return new SuggestionsService(
profile_.get(), scoped_ptr<SuggestionsStore>(mock_suggestions_store_),
- scoped_ptr<ThumbnailManager>(mock_thumbnail_manager_));
+ scoped_ptr<ThumbnailManager>(mock_thumbnail_manager_),
+ scoped_ptr<BlacklistStore>(mock_blacklist_store_));
}
void FetchSuggestionsDataNoTimeoutHelper(bool interleaved_requests) {
// Field trial enabled with a specific suggestions URL.
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix, false);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
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);
@@ -200,6 +226,14 @@ class SuggestionsServiceTest : public testing::Test {
.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)));
@@ -223,6 +257,7 @@ class SuggestionsServiceTest : public testing::Test {
// Only used if the SuggestionsService is built with mocks. Not owned.
MockSuggestionsStore* mock_suggestions_store_;
MockThumbnailManager* mock_thumbnail_manager_;
+ MockBlacklistStore* mock_blacklist_store_;
private:
content::TestBrowserThreadBundle thread_bundle_;
@@ -239,16 +274,16 @@ TEST_F(SuggestionsServiceTest, ServiceBeingCreated) {
EXPECT_TRUE(CreateSuggestionsService() == NULL);
// Field trial enabled.
- EnableFieldTrial("", "", "", false);
+ EnableFieldTrial("", "", "", "", false);
EXPECT_TRUE(CreateSuggestionsService() != NULL);
}
TEST_F(SuggestionsServiceTest, IsControlGroup) {
// Field trial enabled.
- EnableFieldTrial("", "", "", false);
+ EnableFieldTrial("", "", "", "", false);
EXPECT_FALSE(SuggestionsService::IsControlGroup());
- EnableFieldTrial("", "", "", true);
+ EnableFieldTrial("", "", "", "", true);
EXPECT_TRUE(SuggestionsService::IsControlGroup());
}
@@ -262,15 +297,15 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoTimeoutInterleaved) {
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) {
// Field trial enabled with a specific suggestions URL.
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix, false);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
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);
@@ -278,6 +313,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,
@@ -292,15 +333,15 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) {
TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) {
// Field trial enabled with a specific suggestions URL.
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix, false);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
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);
@@ -308,6 +349,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,
@@ -321,18 +367,17 @@ TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) {
}
TEST_F(SuggestionsServiceTest, BlacklistURL) {
- EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsSuffix,
- kFakeBlacklistSuffix, false);
+ EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams,
+ kFakeBlacklistPath, kFakeBlacklistUrlParam, false);
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);
@@ -341,11 +386,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();
@@ -354,4 +407,107 @@ 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, 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));
+
+ // 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();
+
+ // 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());
+}
+
} // namespace suggestions
« no previous file with comments | « chrome/browser/search/suggestions/suggestions_service_factory.cc ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698