| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/search/suggestions/suggestions_service.h" | 5 #include "components/suggestions/suggestions_service.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
| 13 #include "base/message_loop/message_loop.h" |
| 13 #include "base/metrics/field_trial.h" | 14 #include "base/metrics/field_trial.h" |
| 14 #include "base/prefs/pref_service.h" | 15 #include "base/prefs/pref_service.h" |
| 15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
| 16 #include "chrome/browser/search/suggestions/blacklist_store.h" | 17 #include "base/test/test_simple_task_runner.h" |
| 17 #include "chrome/browser/search/suggestions/image_manager.h" | 18 #include "components/suggestions/blacklist_store.h" |
| 18 #include "chrome/browser/search/suggestions/proto/suggestions.pb.h" | 19 #include "components/suggestions/image_manager.h" |
| 19 #include "chrome/browser/search/suggestions/suggestions_service_factory.h" | 20 #include "components/suggestions/proto/suggestions.pb.h" |
| 20 #include "chrome/browser/search/suggestions/suggestions_store.h" | 21 #include "components/suggestions/suggestions_store.h" |
| 21 #include "components/variations/entropy_provider.h" | 22 #include "components/variations/entropy_provider.h" |
| 22 #include "components/variations/variations_associated_data.h" | 23 #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" | 24 #include "net/http/http_response_headers.h" |
| 25 #include "net/http/http_status_code.h" | 25 #include "net/http/http_status_code.h" |
| 26 #include "net/url_request/test_url_fetcher_factory.h" | 26 #include "net/url_request/test_url_fetcher_factory.h" |
| 27 #include "net/url_request/url_request_status.h" | 27 #include "net/url_request/url_request_status.h" |
| 28 #include "net/url_request/url_request_test_util.h" | 28 #include "net/url_request/url_request_test_util.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 31 | 31 |
| 32 using testing::DoAll; | 32 using testing::DoAll; |
| 33 using ::testing::Eq; | 33 using ::testing::Eq; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 int suggestions_data_check_count_; | 137 int suggestions_data_check_count_; |
| 138 int suggestions_empty_data_count_; | 138 int suggestions_empty_data_count_; |
| 139 | 139 |
| 140 protected: | 140 protected: |
| 141 SuggestionsServiceTest() | 141 SuggestionsServiceTest() |
| 142 : suggestions_data_check_count_(0), | 142 : suggestions_data_check_count_(0), |
| 143 suggestions_empty_data_count_(0), | 143 suggestions_empty_data_count_(0), |
| 144 factory_(NULL, base::Bind(&CreateURLFetcher)), | 144 factory_(NULL, base::Bind(&CreateURLFetcher)), |
| 145 mock_suggestions_store_(NULL), | 145 mock_suggestions_store_(NULL), |
| 146 mock_thumbnail_manager_(NULL) {} | 146 mock_thumbnail_manager_(NULL), |
| 147 task_runner_(new base::TestSimpleTaskRunner()) {} |
| 147 | 148 |
| 148 virtual ~SuggestionsServiceTest() {} | 149 virtual ~SuggestionsServiceTest() {} |
| 149 | 150 |
| 150 virtual void SetUp() OVERRIDE { | 151 virtual void SetUp() OVERRIDE { |
| 151 request_context_ = | 152 request_context_ = new net::TestURLRequestContextGetter( |
| 152 new net::TestURLRequestContextGetter(base::MessageLoopProxy::current()); | 153 io_message_loop_.message_loop_proxy()); |
| 153 } | 154 } |
| 154 | 155 |
| 155 // Enables the "ChromeSuggestions.Group1" field trial. | 156 // Enables the "ChromeSuggestions.Group1" field trial. |
| 156 void EnableFieldTrial(const std::string& url, | 157 void EnableFieldTrial(const std::string& url, |
| 157 const std::string& common_params, | 158 const std::string& common_params, |
| 158 const std::string& blacklist_path, | 159 const std::string& blacklist_path, |
| 159 const std::string& blacklist_url_param, | 160 const std::string& blacklist_url_param, |
| 160 bool control_group) { | 161 bool control_group) { |
| 161 // Clear the existing |field_trial_list_| to avoid firing a DCHECK. | 162 // Clear the existing |field_trial_list_| to avoid firing a DCHECK. |
| 162 field_trial_list_.reset(NULL); | 163 field_trial_list_.reset(NULL); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 184 | 185 |
| 185 // Should not be called more than once per test since it stashes the | 186 // Should not be called more than once per test since it stashes the |
| 186 // SuggestionsStore in |mock_suggestions_store_|. | 187 // SuggestionsStore in |mock_suggestions_store_|. |
| 187 SuggestionsService* CreateSuggestionsServiceWithMocks() { | 188 SuggestionsService* CreateSuggestionsServiceWithMocks() { |
| 188 mock_suggestions_store_ = new StrictMock<MockSuggestionsStore>(); | 189 mock_suggestions_store_ = new StrictMock<MockSuggestionsStore>(); |
| 189 mock_thumbnail_manager_ = new NiceMock<MockImageManager>(); | 190 mock_thumbnail_manager_ = new NiceMock<MockImageManager>(); |
| 190 mock_blacklist_store_ = new MockBlacklistStore(); | 191 mock_blacklist_store_ = new MockBlacklistStore(); |
| 191 return new SuggestionsService( | 192 return new SuggestionsService( |
| 192 request_context_, scoped_ptr<SuggestionsStore>(mock_suggestions_store_), | 193 request_context_, scoped_ptr<SuggestionsStore>(mock_suggestions_store_), |
| 193 scoped_ptr<ImageManager>(mock_thumbnail_manager_), | 194 scoped_ptr<ImageManager>(mock_thumbnail_manager_), |
| 194 scoped_ptr<BlacklistStore>(mock_blacklist_store_)); | 195 scoped_ptr<BlacklistStore>(mock_blacklist_store_), |
| 196 task_runner_); |
| 195 } | 197 } |
| 196 | 198 |
| 197 void FetchSuggestionsDataNoTimeoutHelper(bool interleaved_requests) { | 199 void FetchSuggestionsDataNoTimeoutHelper(bool interleaved_requests) { |
| 198 // Field trial enabled with a specific suggestions URL. | 200 // Field trial enabled with a specific suggestions URL. |
| 199 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | 201 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, |
| 200 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | 202 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); |
| 201 scoped_ptr<SuggestionsService> suggestions_service( | 203 scoped_ptr<SuggestionsService> suggestions_service( |
| 202 CreateSuggestionsServiceWithMocks()); | 204 CreateSuggestionsServiceWithMocks()); |
| 203 EXPECT_TRUE(suggestions_service != NULL); | 205 EXPECT_TRUE(suggestions_service != NULL); |
| 204 scoped_ptr<SuggestionsProfile> suggestions_profile( | 206 scoped_ptr<SuggestionsProfile> suggestions_profile( |
| (...skipping 21 matching lines...) Expand all Loading... |
| 226 .Times(expected_count); | 228 .Times(expected_count); |
| 227 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | 229 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) |
| 228 .Times(expected_count) | 230 .Times(expected_count) |
| 229 .WillRepeatedly(Return(false)); | 231 .WillRepeatedly(Return(false)); |
| 230 | 232 |
| 231 // Send the request. The data will be returned to the callback. | 233 // Send the request. The data will be returned to the callback. |
| 232 suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind( | 234 suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind( |
| 233 &SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this))); | 235 &SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this))); |
| 234 | 236 |
| 235 if (!interleaved_requests) | 237 if (!interleaved_requests) |
| 236 base::MessageLoop::current()->RunUntilIdle(); // Let request complete. | 238 io_message_loop_.RunUntilIdle(); // Let request complete. |
| 237 | 239 |
| 238 // Send the request a second time. | 240 // Send the request a second time. |
| 239 suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind( | 241 suggestions_service->FetchSuggestionsDataNoTimeout(base::Bind( |
| 240 &SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this))); | 242 &SuggestionsServiceTest::CheckSuggestionsData, base::Unretained(this))); |
| 241 | 243 |
| 242 // (Testing only) wait until suggestion fetch is complete. | 244 // (Testing only) wait until suggestion fetch is complete. |
| 243 base::MessageLoop::current()->RunUntilIdle(); | 245 io_message_loop_.RunUntilIdle(); |
| 244 | 246 |
| 245 // Ensure that CheckSuggestionsData() ran twice. | 247 // Ensure that CheckSuggestionsData() ran twice. |
| 246 EXPECT_EQ(2, suggestions_data_check_count_); | 248 EXPECT_EQ(2, suggestions_data_check_count_); |
| 247 } | 249 } |
| 248 | 250 |
| 249 protected: | 251 protected: |
| 252 base::MessageLoopForIO io_message_loop_; |
| 250 net::FakeURLFetcherFactory factory_; | 253 net::FakeURLFetcherFactory factory_; |
| 251 // Only used if the SuggestionsService is built with mocks. Not owned. | 254 // Only used if the SuggestionsService is built with mocks. Not owned. |
| 252 MockSuggestionsStore* mock_suggestions_store_; | 255 MockSuggestionsStore* mock_suggestions_store_; |
| 253 MockImageManager* mock_thumbnail_manager_; | 256 MockImageManager* mock_thumbnail_manager_; |
| 254 MockBlacklistStore* mock_blacklist_store_; | 257 MockBlacklistStore* mock_blacklist_store_; |
| 255 scoped_refptr<net::TestURLRequestContextGetter> request_context_; | 258 scoped_refptr<net::TestURLRequestContextGetter> request_context_; |
| 259 scoped_refptr<base::TestSimpleTaskRunner> task_runner_; |
| 256 | 260 |
| 257 private: | 261 private: |
| 258 content::TestBrowserThreadBundle thread_bundle_; | |
| 259 scoped_ptr<base::FieldTrialList> field_trial_list_; | 262 scoped_ptr<base::FieldTrialList> field_trial_list_; |
| 260 scoped_refptr<base::FieldTrial> field_trial_; | 263 scoped_refptr<base::FieldTrial> field_trial_; |
| 261 | 264 |
| 262 DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest); | 265 DISALLOW_COPY_AND_ASSIGN(SuggestionsServiceTest); |
| 263 }; | 266 }; |
| 264 | 267 |
| 265 TEST_F(SuggestionsServiceTest, IsControlGroup) { | 268 TEST_F(SuggestionsServiceTest, IsControlGroup) { |
| 266 // Field trial enabled. | 269 // Field trial enabled. |
| 267 EnableFieldTrial("", "", "", "", false); | 270 EnableFieldTrial("", "", "", "", false); |
| 268 EXPECT_FALSE(SuggestionsService::IsControlGroup()); | 271 EXPECT_FALSE(SuggestionsService::IsControlGroup()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); | 305 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); |
| 303 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | 306 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) |
| 304 .WillOnce(Return(false)); | 307 .WillOnce(Return(false)); |
| 305 | 308 |
| 306 // Send the request. Empty data will be returned to the callback. | 309 // Send the request. Empty data will be returned to the callback. |
| 307 suggestions_service->FetchSuggestionsData( | 310 suggestions_service->FetchSuggestionsData( |
| 308 base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile, | 311 base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile, |
| 309 base::Unretained(this))); | 312 base::Unretained(this))); |
| 310 | 313 |
| 311 // (Testing only) wait until suggestion fetch is complete. | 314 // (Testing only) wait until suggestion fetch is complete. |
| 312 base::MessageLoop::current()->RunUntilIdle(); | 315 io_message_loop_.RunUntilIdle(); |
| 313 | 316 |
| 314 // Ensure that ExpectEmptySuggestionsProfile ran once. | 317 // Ensure that ExpectEmptySuggestionsProfile ran once. |
| 315 EXPECT_EQ(1, suggestions_empty_data_count_); | 318 EXPECT_EQ(1, suggestions_empty_data_count_); |
| 316 } | 319 } |
| 317 | 320 |
| 318 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) { | 321 TEST_F(SuggestionsServiceTest, FetchSuggestionsDataResponseNotOK) { |
| 319 // Field trial enabled with a specific suggestions URL. | 322 // Field trial enabled with a specific suggestions URL. |
| 320 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | 323 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, |
| 321 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | 324 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); |
| 322 scoped_ptr<SuggestionsService> suggestions_service( | 325 scoped_ptr<SuggestionsService> suggestions_service( |
| (...skipping 14 matching lines...) Expand all Loading... |
| 337 // blacklist. | 340 // blacklist. |
| 338 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | 341 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) |
| 339 .WillOnce(Return(false)); | 342 .WillOnce(Return(false)); |
| 340 | 343 |
| 341 // Send the request. Empty data will be returned to the callback. | 344 // Send the request. Empty data will be returned to the callback. |
| 342 suggestions_service->FetchSuggestionsData( | 345 suggestions_service->FetchSuggestionsData( |
| 343 base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile, | 346 base::Bind(&SuggestionsServiceTest::ExpectEmptySuggestionsProfile, |
| 344 base::Unretained(this))); | 347 base::Unretained(this))); |
| 345 | 348 |
| 346 // (Testing only) wait until suggestion fetch is complete. | 349 // (Testing only) wait until suggestion fetch is complete. |
| 347 base::MessageLoop::current()->RunUntilIdle(); | 350 io_message_loop_.RunUntilIdle(); |
| 348 | 351 |
| 349 // Ensure that ExpectEmptySuggestionsProfile ran once. | 352 // Ensure that ExpectEmptySuggestionsProfile ran once. |
| 350 EXPECT_EQ(1, suggestions_empty_data_count_); | 353 EXPECT_EQ(1, suggestions_empty_data_count_); |
| 351 } | 354 } |
| 352 | 355 |
| 353 TEST_F(SuggestionsServiceTest, BlacklistURL) { | 356 TEST_F(SuggestionsServiceTest, BlacklistURL) { |
| 354 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | 357 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, |
| 355 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | 358 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); |
| 356 scoped_ptr<SuggestionsService> suggestions_service( | 359 scoped_ptr<SuggestionsService> suggestions_service( |
| 357 CreateSuggestionsServiceWithMocks()); | 360 CreateSuggestionsServiceWithMocks()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 378 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); | 381 EXPECT_CALL(*mock_blacklist_store_, FilterSuggestions(_)); |
| 379 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) | 382 EXPECT_CALL(*mock_blacklist_store_, GetFirstUrlFromBlacklist(_)) |
| 380 .WillOnce(Return(false)); | 383 .WillOnce(Return(false)); |
| 381 | 384 |
| 382 // Send the request. The data will be returned to the callback. | 385 // Send the request. The data will be returned to the callback. |
| 383 suggestions_service->BlacklistURL( | 386 suggestions_service->BlacklistURL( |
| 384 blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData, | 387 blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData, |
| 385 base::Unretained(this))); | 388 base::Unretained(this))); |
| 386 | 389 |
| 387 // (Testing only) wait until blacklist request is complete. | 390 // (Testing only) wait until blacklist request is complete. |
| 388 base::MessageLoop::current()->RunUntilIdle(); | 391 io_message_loop_.RunUntilIdle(); |
| 389 | 392 |
| 390 // Ensure that CheckSuggestionsData() ran once. | 393 // Ensure that CheckSuggestionsData() ran once. |
| 391 EXPECT_EQ(1, suggestions_data_check_count_); | 394 EXPECT_EQ(1, suggestions_data_check_count_); |
| 392 } | 395 } |
| 393 | 396 |
| 394 // Initial blacklist request fails, triggering a scheduled upload which | 397 // Initial blacklist request fails, triggering a scheduled upload which |
| 395 // succeeds. | 398 // succeeds. |
| 396 TEST_F(SuggestionsServiceTest, BlacklistURLFails) { | 399 TEST_F(SuggestionsServiceTest, BlacklistURLFails) { |
| 397 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | 400 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, |
| 398 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | 401 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData, | 437 blacklist_url, base::Bind(&SuggestionsServiceTest::CheckSuggestionsData, |
| 435 base::Unretained(this))); | 438 base::Unretained(this))); |
| 436 | 439 |
| 437 // The first FakeURLFetcher was created; we can now set up behavior for the | 440 // The first FakeURLFetcher was created; we can now set up behavior for the |
| 438 // second call to blacklist. | 441 // second call to blacklist. |
| 439 factory_.SetFakeResponse(GURL(request_url), | 442 factory_.SetFakeResponse(GURL(request_url), |
| 440 suggestions_profile->SerializeAsString(), | 443 suggestions_profile->SerializeAsString(), |
| 441 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | 444 net::HTTP_OK, net::URLRequestStatus::SUCCESS); |
| 442 | 445 |
| 443 // (Testing only) wait until both requests are complete. | 446 // (Testing only) wait until both requests are complete. |
| 444 base::MessageLoop::current()->RunUntilIdle(); | 447 io_message_loop_.RunUntilIdle(); |
| 448 // ... Other task gets posted to TestSimpleTaskRunner. |
| 449 task_runner_->RunUntilIdle(); |
| 450 // ... And completes. |
| 451 io_message_loop_.RunUntilIdle(); |
| 445 | 452 |
| 446 // Ensure that CheckSuggestionsData() ran once. | 453 // Ensure that CheckSuggestionsData() ran once. |
| 447 EXPECT_EQ(1, suggestions_data_check_count_); | 454 EXPECT_EQ(1, suggestions_data_check_count_); |
| 448 } | 455 } |
| 449 | 456 |
| 450 TEST_F(SuggestionsServiceTest, GetBlacklistedUrl) { | 457 TEST_F(SuggestionsServiceTest, GetBlacklistedUrl) { |
| 451 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, | 458 EnableFieldTrial(kFakeSuggestionsURL, kFakeSuggestionsCommonParams, |
| 452 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); | 459 kFakeBlacklistPath, kFakeBlacklistUrlParam, false); |
| 453 | 460 |
| 454 scoped_ptr<GURL> request_url; | 461 scoped_ptr<GURL> request_url; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 // Delay increases on failure. | 495 // Delay increases on failure. |
| 489 suggestions_service->UpdateBlacklistDelay(false); | 496 suggestions_service->UpdateBlacklistDelay(false); |
| 490 EXPECT_GT(suggestions_service->blacklist_delay(), initial_delay); | 497 EXPECT_GT(suggestions_service->blacklist_delay(), initial_delay); |
| 491 | 498 |
| 492 // Delay resets on success. | 499 // Delay resets on success. |
| 493 suggestions_service->UpdateBlacklistDelay(true); | 500 suggestions_service->UpdateBlacklistDelay(true); |
| 494 EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay()); | 501 EXPECT_EQ(initial_delay, suggestions_service->blacklist_delay()); |
| 495 } | 502 } |
| 496 | 503 |
| 497 } // namespace suggestions | 504 } // namespace suggestions |
| OLD | NEW |