| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/search/suggestions/suggestions_service.h" | |
| 6 | |
| 7 #include <map> | |
| 8 #include <sstream> | |
| 9 #include <string> | |
| 10 | |
| 11 #include "base/bind.h" | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "base/metrics/field_trial.h" | |
| 14 #include "base/prefs/pref_service.h" | |
| 15 #include "base/strings/utf_string_conversions.h" | |
| 16 #include "chrome/browser/search/suggestions/blacklist_store.h" | |
| 17 #include "chrome/browser/search/suggestions/image_manager.h" | |
| 18 #include "chrome/browser/search/suggestions/proto/suggestions.pb.h" | |
| 19 #include "chrome/browser/search/suggestions/suggestions_service_factory.h" | |
| 20 #include "chrome/browser/search/suggestions/suggestions_store.h" | |
| 21 #include "components/variations/entropy_provider.h" | |
| 22 #include "components/variations/variations_associated_data.h" | |
| 23 #include "content/public/test/test_browser_thread_bundle.h" | |
| 24 #include "net/http/http_response_headers.h" | |
| 25 #include "net/http/http_status_code.h" | |
| 26 #include "net/url_request/test_url_fetcher_factory.h" | |
| 27 #include "net/url_request/url_request_status.h" | |
| 28 #include "net/url_request/url_request_test_util.h" | |
| 29 #include "testing/gmock/include/gmock/gmock.h" | |
| 30 #include "testing/gtest/include/gtest/gtest.h" | |
| 31 | |
| 32 using testing::DoAll; | |
| 33 using ::testing::Eq; | |
| 34 using ::testing::Return; | |
| 35 using testing::SetArgPointee; | |
| 36 using ::testing::NiceMock; | |
| 37 using ::testing::StrictMock; | |
| 38 using ::testing::_; | |
| 39 | |
| 40 namespace { | |
| 41 | |
| 42 const char kFakeSuggestionsURL[] = "https://mysuggestions.com/proto"; | |
| 43 const char kFakeSuggestionsCommonParams[] = "foo=bar"; | |
| 44 const char kFakeBlacklistPath[] = "/blacklist"; | |
| 45 const char kFakeBlacklistUrlParam[] = "baz"; | |
| 46 | |
| 47 const char kTestTitle[] = "a title"; | |
| 48 const char kTestUrl[] = "http://go.com"; | |
| 49 const char kBlacklistUrl[] = "http://blacklist.com"; | |
| 50 | |
| 51 scoped_ptr<net::FakeURLFetcher> CreateURLFetcher( | |
| 52 const GURL& url, net::URLFetcherDelegate* delegate, | |
| 53 const std::string& response_data, net::HttpStatusCode response_code, | |
| 54 net::URLRequestStatus::Status status) { | |
| 55 scoped_ptr<net::FakeURLFetcher> fetcher(new net::FakeURLFetcher( | |
| 56 url, delegate, response_data, response_code, status)); | |
| 57 | |
| 58 if (response_code == net::HTTP_OK) { | |
| 59 scoped_refptr<net::HttpResponseHeaders> download_headers( | |
| 60 new net::HttpResponseHeaders("")); | |
| 61 download_headers->AddHeader("Content-Type: text/html"); | |
| 62 fetcher->set_response_headers(download_headers); | |
| 63 } | |
| 64 return fetcher.Pass(); | |
| 65 } | |
| 66 | |
| 67 std::string GetExpectedBlacklistRequestUrl(const GURL& blacklist_url) { | |
| 68 std::stringstream request_url; | |
| 69 request_url << kFakeSuggestionsURL << kFakeBlacklistPath << "?" | |
| 70 << kFakeSuggestionsCommonParams << "&" << kFakeBlacklistUrlParam | |
| 71 << "=" << net::EscapeQueryParamValue(blacklist_url.spec(), true); | |
| 72 return request_url.str(); | |
| 73 } | |
| 74 | |
| 75 // GMock matcher for protobuf equality. | |
| 76 MATCHER_P(EqualsProto, message, "") { | |
| 77 // This implementation assumes protobuf serialization is deterministic, which | |
| 78 // is true in practice but technically not something that code is supposed | |
| 79 // to rely on. However, it vastly simplifies the implementation. | |
| 80 std::string expected_serialized, actual_serialized; | |
| 81 message.SerializeToString(&expected_serialized); | |
| 82 arg.SerializeToString(&actual_serialized); | |
| 83 return expected_serialized == actual_serialized; | |
| 84 } | |
| 85 | |
| 86 } // namespace | |
| 87 | |
| 88 namespace suggestions { | |
| 89 | |
| 90 scoped_ptr<SuggestionsProfile> CreateSuggestionsProfile() { | |
| 91 scoped_ptr<SuggestionsProfile> profile(new SuggestionsProfile()); | |
| 92 ChromeSuggestion* suggestion = profile->add_suggestions(); | |
| 93 suggestion->set_title(kTestTitle); | |
| 94 suggestion->set_url(kTestUrl); | |
| 95 return profile.Pass(); | |
| 96 } | |
| 97 | |
| 98 class MockSuggestionsStore : public suggestions::SuggestionsStore { | |
| 99 public: | |
| 100 MOCK_METHOD1(LoadSuggestions, bool(SuggestionsProfile*)); | |
| 101 MOCK_METHOD1(StoreSuggestions, bool(const SuggestionsProfile&)); | |
| 102 MOCK_METHOD0(ClearSuggestions, void()); | |
| 103 }; | |
| 104 | |
| 105 class MockImageManager : public suggestions::ImageManager { | |
| 106 public: | |
| 107 MockImageManager() {} | |
| 108 virtual ~MockImageManager() {} | |
| 109 MOCK_METHOD1(Initialize, void(const SuggestionsProfile&)); | |
| 110 MOCK_METHOD2(GetImageForURL, | |
| 111 void(const GURL&, | |
| 112 base::Callback<void(const GURL&, const SkBitmap*)>)); | |
| 113 }; | |
| 114 | |
| 115 class MockBlacklistStore : public suggestions::BlacklistStore { | |
| 116 public: | |
| 117 MOCK_METHOD1(BlacklistUrl, bool(const GURL&)); | |
| 118 MOCK_METHOD1(GetFirstUrlFromBlacklist, bool(GURL*)); | |
| 119 MOCK_METHOD1(RemoveUrl, bool(const GURL&)); | |
| 120 MOCK_METHOD1(FilterSuggestions, void(SuggestionsProfile*)); | |
| 121 }; | |
| 122 | |
| 123 class SuggestionsServiceTest : public testing::Test { | |
| 124 public: | |
| 125 void CheckSuggestionsData(const SuggestionsProfile& suggestions_profile) { | |
| 126 EXPECT_EQ(1, suggestions_profile.suggestions_size()); | |
| 127 EXPECT_EQ(kTestTitle, suggestions_profile.suggestions(0).title()); | |
| 128 EXPECT_EQ(kTestUrl, suggestions_profile.suggestions(0).url()); | |
| 129 ++suggestions_data_check_count_; | |
| 130 } | |
| 131 | |
| 132 void ExpectEmptySuggestionsProfile(const SuggestionsProfile& profile) { | |
| 133 EXPECT_EQ(0, profile.suggestions_size()); | |
| 134 ++suggestions_empty_data_count_; | |
| 135 } | |
| 136 | |
| 137 int suggestions_data_check_count_; | |
| 138 int suggestions_empty_data_count_; | |
| 139 | |
| 140 protected: | |
| 141 SuggestionsServiceTest() | |
| 142 : suggestions_data_check_count_(0), | |
| 143 suggestions_empty_data_count_(0), | |
| 144 factory_(NULL, base::Bind(&CreateURLFetcher)), | |
| 145 mock_suggestions_store_(NULL), | |
| 146 mock_thumbnail_manager_(NULL) {} | |
| 147 | |
| 148 virtual ~SuggestionsServiceTest() {} | |
| 149 | |
| 150 virtual void SetUp() OVERRIDE { | |
| 151 request_context_ = | |
| 152 new net::TestURLRequestContextGetter(base::MessageLoopProxy::current()); | |
| 153 } | |
| 154 | |
| 155 // Enables the "ChromeSuggestions.Group1" field trial. | |
| 156 void EnableFieldTrial(const std::string& url, | |
| 157 const std::string& common_params, | |
| 158 const std::string& blacklist_path, | |
| 159 const std::string& blacklist_url_param, | |
| 160 bool control_group) { | |
| 161 // Clear the existing |field_trial_list_| to avoid firing a DCHECK. | |
| 162 field_trial_list_.reset(NULL); | |
| 163 field_trial_list_.reset( | |
| 164 new base::FieldTrialList(new metrics::SHA1EntropyProvider("foo"))); | |
| 165 | |
| 166 chrome_variations::testing::ClearAllVariationParams(); | |
| 167 std::map<std::string, std::string> params; | |
| 168 params[kSuggestionsFieldTrialStateParam] = | |
| 169 kSuggestionsFieldTrialStateEnabled; | |
| 170 if (control_group) { | |
| 171 params[kSuggestionsFieldTrialControlParam] = | |
| 172 kSuggestionsFieldTrialStateEnabled; | |
| 173 } | |
| 174 params[kSuggestionsFieldTrialURLParam] = url; | |
| 175 params[kSuggestionsFieldTrialCommonParamsParam] = common_params; | |
| 176 params[kSuggestionsFieldTrialBlacklistPathParam] = blacklist_path; | |
| 177 params[kSuggestionsFieldTrialBlacklistUrlParam] = blacklist_url_param; | |
| 178 chrome_variations::AssociateVariationParams(kSuggestionsFieldTrialName, | |
| 179 "Group1", params); | |
| 180 field_trial_ = base::FieldTrialList::CreateFieldTrial( | |
| 181 kSuggestionsFieldTrialName, "Group1"); | |
| 182 field_trial_->group(); | |
| 183 } | |
| 184 | |
| 185 // Should not be called more than once per test since it stashes the | |
| 186 // SuggestionsStore in |mock_suggestions_store_|. | |
| 187 SuggestionsService* CreateSuggestionsServiceWithMocks() { | |
| 188 mock_suggestions_store_ = new StrictMock<MockSuggestionsStore>(); | |
| 189 mock_thumbnail_manager_ = new NiceMock<MockImageManager>(); | |
| 190 mock_blacklist_store_ = new MockBlacklistStore(); | |
| 191 return new SuggestionsService( | |
| 192 request_context_, scoped_ptr<SuggestionsStore>(mock_suggestions_store_), | |
| 193 scoped_ptr<ImageManager>(mock_thumbnail_manager_), | |
| 194 scoped_ptr<BlacklistStore>(mock_blacklist_store_)); | |
| 195 } | |
| 196 | |
| 197 void FetchSuggestionsDataNoTimeoutHelper(bool interleaved_requests) { | |
| 198 // Field trial enabled with a specific suggestions URL. | |
| 199 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | |
| 200 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | |
| 201 scoped_ptr<SuggestionsService> suggestions_service( | |
| 202 CreateSuggestionsServiceWithMocks()); | |
| 203 EXPECT_TRUE(suggestions_service != NULL); | |
| 204 scoped_ptr<SuggestionsProfile> suggestions_profile( | |
| 205 CreateSuggestionsProfile()); | |
| 206 | |
| 207 // Set up net::FakeURLFetcherFactory. | |
| 208 std::string expected_url = | |
| 209 (std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams; | |
| 210 factory_.SetFakeResponse(GURL(expected_url), | |
| 211 suggestions_profile->SerializeAsString(), | |
| 212 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | |
| 213 | |
| 214 // Set up expectations on the SuggestionsStore. The number depends on | |
| 215 // whether the second request is issued (it won't be issued if the second | |
| 216 // fetch occurs before the first request has completed). | |
| 217 int expected_count = interleaved_requests ? 1 : 2; | |
| 218 EXPECT_CALL(*mock_suggestions_store_, | |
| 219 StoreSuggestions(EqualsProto(*suggestions_profile))) | |
| 220 .Times(expected_count) | |
| 221 .WillRepeatedly(Return(true)); | |
| 222 | |
| 223 // Expect a call to the blacklist store. Return that there's nothing to | |
| 224 // blacklist. | |
| 225 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)) | |
| 226 .Times(expected_count); | |
| 227 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | |
| 228 .Times(expected_count) | |
| 229 .WillRepeatedly(Return(false)); | |
| 230 | |
| 231 // Send the request. The data will be returned to the callback. | |
| 232 suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind( | |
| 233 &SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this))); | |
| 234 | |
| 235 if (!interleaved_requests) | |
| 236 base::MessageLoop::current()->RunUntilIdle(); // Let request complete. | |
| 237 | |
| 238 // Send the request a second time. | |
| 239 suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind( | |
| 240 &SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this))); | |
| 241 | |
| 242 // (Testing only) wait until suggestion fetch is complete. | |
| 243 base::MessageLoop::current()->RunUntilIdle(); | |
| 244 | |
| 245 // Ensure that CheckSuggestionsData() ran twice. | |
| 246 EXPECT_EQ(2, suggestions_data_check_count_); | |
| 247 } | |
| 248 | |
| 249 protected: | |
| 250 net::FakeURLFetcherFactory factory_; | |
| 251 // Only used if the SuggestionsService is built with mocks. Not owned. | |
| 252 MockSuggestionsStore* mock_suggestions_store_; | |
| 253 MockImageManager* mock_thumbnail_manager_; | |
| 254 MockBlacklistStore* mock_blacklist_store_; | |
| 255 scoped_refptr<net::TestURLRequestContextGetter> request_context_; | |
| 256 | |
| 257 private: | |
| 258 content::TestBrowserThreadBundle thread_bundle_; | |
| 259 scoped_ptr<base::FieldTrialList> field_trial_list_; | |
| 260 scoped_refptr<base::FieldTrial> field_trial_; | |
| 261 | |
| 262 DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest); | |
| 263 }; | |
| 264 | |
| 265 TEST_F(SuggestionsServiceTest, IsControlGroup) { | |
| 266 // Field trial enabled. | |
| 267 EnableFieldTrial("", "", "", "", false); | |
| 268 EXPECT_FALSE(SuggestionsService::IsControlGroup()); | |
| 269 | |
| 270 EnableFieldTrial("", "", "", "", true); | |
| 271 EXPECT_TRUE(SuggestionsService::IsControlGroup()); | |
| 272 } | |
| 273 | |
| 274 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoTimeout) { | |
| 275 FetchSuggestionsDataNoTimeoutHelper(false); | |
| 276 } | |
| 277 | |
| 278 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataNoTimeoutInterleaved) { | |
| 279 FetchSuggestionsDataNoTimeoutHelper(true); | |
| 280 } | |
| 281 | |
| 282 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataRequestError) { | |
| 283 // Field trial enabled with a specific suggestions URL. | |
| 284 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | |
| 285 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | |
| 286 scoped_ptr<SuggestionsService> suggestions_service( | |
| 287 CreateSuggestionsServiceWithMocks()); | |
| 288 EXPECT_TRUE(suggestions_service != NULL); | |
| 289 | |
| 290 // Fake a request error. | |
| 291 std::string expected_url = | |
| 292 (std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams; | |
| 293 factory_.SetFakeResponse(GURL(expected_url), "irrelevant", net::HTTP_OK, | |
| 294 net::URLRequestStatus::FAILED); | |
| 295 | |
| 296 // Set up expectations on the SuggestionsStore. | |
| 297 EXPECT_CALL(*mock_suggestions_store_, LoadSuggestions(_)) | |
| 298 .WillOnce(Return(true)); | |
| 299 | |
| 300 // Expect a call to the blacklist store. Return that there's nothing to | |
| 301 // blacklist. | |
| 302 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); | |
| 303 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | |
| 304 .WillOnce(Return(false)); | |
| 305 | |
| 306 // Send the request. Empty data will be returned to the callback. | |
| 307 suggestions_service->FetchSuggestionsData( | |
| 308 base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile, | |
| 309 base::Unretained(this))); | |
| 310 | |
| 311 // (Testing only) wait until suggestion fetch is complete. | |
| 312 base::MessageLoop::current()->RunUntilIdle(); | |
| 313 | |
| 314 // Ensure that ExpectEmptySuggestionsProfile ran once. | |
| 315 EXPECT_EQ(1, suggestions_empty_data_count_); | |
| 316 } | |
| 317 | |
| 318 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) { | |
| 319 // Field trial enabled with a specific suggestions URL. | |
| 320 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | |
| 321 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | |
| 322 scoped_ptr<SuggestionsService> suggestions_service( | |
| 323 CreateSuggestionsServiceWithMocks()); | |
| 324 EXPECT_TRUE(suggestions_service != NULL); | |
| 325 | |
| 326 // Response code != 200. | |
| 327 std::string expected_url = | |
| 328 (std::string(kFakeSuggestionsURL) + "?") + kFakeSuggestionsCommonParams; | |
| 329 factory_.SetFakeResponse(GURL(expected_url), "irrelevant", | |
| 330 net::HTTP_BAD_REQUEST, | |
| 331 net::URLRequestStatus::SUCCESS); | |
| 332 | |
| 333 // Set up expectations on the SuggestionsStore. | |
| 334 EXPECT_CALL(*mock_suggestions_store_, ClearSuggestions()); | |
| 335 | |
| 336 // Expect a call to the blacklist store. Return that there's nothing to | |
| 337 // blacklist. | |
| 338 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | |
| 339 .WillOnce(Return(false)); | |
| 340 | |
| 341 // Send the request. Empty data will be returned to the callback. | |
| 342 suggestions_service->FetchSuggestionsData( | |
| 343 base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile, | |
| 344 base::Unretained(this))); | |
| 345 | |
| 346 // (Testing only) wait until suggestion fetch is complete. | |
| 347 base::MessageLoop::current()->RunUntilIdle(); | |
| 348 | |
| 349 // Ensure that ExpectEmptySuggestionsProfile ran once. | |
| 350 EXPECT_EQ(1, suggestions_empty_data_count_); | |
| 351 } | |
| 352 | |
| 353 TEST_F(SuggestionsServiceTest, BlacklistURL) { | |
| 354 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | |
| 355 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | |
| 356 scoped_ptr<SuggestionsService> suggestions_service( | |
| 357 CreateSuggestionsServiceWithMocks()); | |
| 358 EXPECT_TRUE(suggestions_service != NULL); | |
| 359 | |
| 360 GURL blacklist_url(kBlacklistUrl); | |
| 361 std::string request_url = GetExpectedBlacklistRequestUrl(blacklist_url); | |
| 362 scoped_ptr<SuggestionsProfile> suggestions_profile( | |
| 363 CreateSuggestionsProfile()); | |
| 364 factory_.SetFakeResponse(GURL(request_url), | |
| 365 suggestions_profile->SerializeAsString(), | |
| 366 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | |
| 367 | |
| 368 // Set up expectations on the SuggestionsStore. | |
| 369 EXPECT_CALL(*mock_suggestions_store_, | |
| 370 StoreSuggestions(EqualsProto(*suggestions_profile))) | |
| 371 .WillOnce(Return(true)); | |
| 372 | |
| 373 // Expected calls to the blacklist store. | |
| 374 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklist_url))) | |
| 375 .WillOnce(Return(true)); | |
| 376 EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklist_url))) | |
| 377 .WillOnce(Return(true)); | |
| 378 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); | |
| 379 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | |
| 380 .WillOnce(Return(false)); | |
| 381 | |
| 382 // Send the request. The data will be returned to the callback. | |
| 383 suggestions_service->BlacklistURL( | |
| 384 blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData, | |
| 385 base::Unretained(this))); | |
| 386 | |
| 387 // (Testing only) wait until blacklist request is complete. | |
| 388 base::MessageLoop::current()->RunUntilIdle(); | |
| 389 | |
| 390 // Ensure that CheckSuggestionsData() ran once. | |
| 391 EXPECT_EQ(1, suggestions_data_check_count_); | |
| 392 } | |
| 393 | |
| 394 // Initial blacklist request fails, triggering a scheduled upload which | |
| 395 // succeeds. | |
| 396 TEST_F(SuggestionsServiceTest, BlacklistURLFails) { | |
| 397 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | |
| 398 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | |
| 399 scoped_ptr<SuggestionsService> suggestions_service( | |
| 400 CreateSuggestionsServiceWithMocks()); | |
| 401 EXPECT_TRUE(suggestions_service != NULL); | |
| 402 suggestions_service->set_blacklist_delay(0); // Don't wait during a test! | |
| 403 scoped_ptr<SuggestionsProfile> suggestions_profile( | |
| 404 CreateSuggestionsProfile()); | |
| 405 GURL blacklist_url(kBlacklistUrl); | |
| 406 | |
| 407 // Set up behavior for the first call to blacklist. | |
| 408 std::string request_url = GetExpectedBlacklistRequestUrl(blacklist_url); | |
| 409 factory_.SetFakeResponse(GURL(request_url), "irrelevant", net::HTTP_OK, | |
| 410 net::URLRequestStatus::FAILED); | |
| 411 | |
| 412 // Expectations specific to the first request. | |
| 413 EXPECT_CALL(*mock_blacklist_store_, BlacklistUrl(Eq(blacklist_url))) | |
| 414 .WillOnce(Return(true)); | |
| 415 EXPECT_CALL(*mock_suggestions_store_, LoadSuggestions(_)) | |
| 416 .WillOnce(DoAll(SetArgPointee<0>(*suggestions_profile), Return(true))); | |
| 417 | |
| 418 // Expectations specific to the second request. | |
| 419 EXPECT_CALL(*mock_suggestions_store_, | |
| 420 StoreSuggestions(EqualsProto(*suggestions_profile))) | |
| 421 .WillOnce(Return(true)); | |
| 422 EXPECT_CALL(*mock_blacklist_store_, RemoveUrl(Eq(blacklist_url))) | |
| 423 .WillOnce(Return(true)); | |
| 424 | |
| 425 // Expectations pertaining to both requests. | |
| 426 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)).Times(2); | |
| 427 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | |
| 428 .WillOnce(Return(true)) | |
| 429 .WillOnce(DoAll(SetArgPointee<0>(blacklist_url), Return(true))) | |
| 430 .WillOnce(Return(false)); | |
| 431 | |
| 432 // Send the request. The data will be returned to the callback. | |
| 433 suggestions_service->BlacklistURL( | |
| 434 blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData, | |
| 435 base::Unretained(this))); | |
| 436 | |
| 437 // The first FakeURLFetcher was created; we can now set up behavior for the | |
| 438 // second call to blacklist. | |
| 439 factory_.SetFakeResponse(GURL(request_url), | |
| 440 suggestions_profile->SerializeAsString(), | |
| 441 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | |
| 442 | |
| 443 // (Testing only) wait until both requests are complete. | |
| 444 base::MessageLoop::current()->RunUntilIdle(); | |
| 445 | |
| 446 // Ensure that CheckSuggestionsData() ran once. | |
| 447 EXPECT_EQ(1, suggestions_data_check_count_); | |
| 448 } | |
| 449 | |
| 450 TEST_F(SuggestionsServiceTest, GetBlacklistedUrl) { | |
| 451 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | |
| 452 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | |
| 453 | |
| 454 scoped_ptr<GURL> request_url; | |
| 455 scoped_ptr<net::FakeURLFetcher> fetcher; | |
| 456 GURL retrieved_url; | |
| 457 | |
| 458 // Not a blacklist request. | |
| 459 request_url.reset(new GURL("http://not-blacklisting.com/a?b=c")); | |
| 460 fetcher = CreateURLFetcher(*request_url, NULL, "", net::HTTP_OK, | |
| 461 net::URLRequestStatus::SUCCESS); | |
| 462 EXPECT_FALSE(SuggestionsService::GetBlacklistedUrl(*fetcher, &retrieved_url)); | |
| 463 | |
| 464 // An actual blacklist request. | |
| 465 string blacklisted_url = "http://blacklisted.com/a?b=c&d=e"; | |
| 466 string encoded_blacklisted_url = | |
| 467 "http%3A%2F%2Fblacklisted.com%2Fa%3Fb%3Dc%26d%3De"; | |
| 468 string blacklist_request_prefix = | |
| 469 "https://mysuggestions.com/proto/blacklist?foo=bar&baz="; | |
| 470 request_url.reset( | |
| 471 new GURL(blacklist_request_prefix + encoded_blacklisted_url)); | |
| 472 fetcher.reset(); | |
| 473 fetcher = CreateURLFetcher(*request_url, NULL, "", net::HTTP_OK, | |
| 474 net::URLRequestStatus::SUCCESS); | |
| 475 EXPECT_TRUE(SuggestionsService::GetBlacklistedUrl(*fetcher, &retrieved_url)); | |
| 476 EXPECT_EQ(blacklisted_url, retrieved_url.spec()); | |
| 477 } | |
| 478 | |
| 479 TEST_F(SuggestionsServiceTest, UpdateBlacklistDelay) { | |
| 480 scoped_ptr<SuggestionsService> suggestions_service( | |
| 481 CreateSuggestionsServiceWithMocks()); | |
| 482 int initial_delay = suggestions_service->blacklist_delay(); | |
| 483 | |
| 484 // Delay unchanged on success. | |
| 485 suggestions_service->UpdateBlacklistDelay(true); | |
| 486 EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay()); | |
| 487 | |
| 488 // Delay increases on failure. | |
| 489 suggestions_service->UpdateBlacklistDelay(false); | |
| 490 EXPECT_GT(suggestions_service->blacklist_delay(), initial_delay); | |
| 491 | |
| 492 // Delay resets on success. | |
| 493 suggestions_service->UpdateBlacklistDelay(true); | |
| 494 EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay()); | |
| 495 } | |
| 496 | |
| 497 } // namespace suggestions | |
| OLD | NEW |