Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "components/ntp_snippets/remote/remote_suggestions_provider.h" | 5 #include "components/ntp_snippets/remote/remote_suggestions_provider.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <utility> | 8 #include <utility> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/files/scoped_temp_dir.h" | 13 #include "base/files/scoped_temp_dir.h" |
| 14 #include "base/json/json_reader.h" | 14 #include "base/json/json_reader.h" |
| 15 #include "base/macros.h" | 15 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 16 #include "base/memory/ptr_util.h" |
| 17 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
| 18 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 19 #include "base/strings/string_number_conversions.h" | 19 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/string_util.h" | 20 #include "base/strings/string_util.h" |
| 21 #include "base/strings/stringprintf.h" | 21 #include "base/strings/stringprintf.h" |
| 22 #include "base/test/histogram_tester.h" | 22 #include "base/test/histogram_tester.h" |
| 23 #include "base/test/simple_test_clock.h" | 23 #include "base/test/simple_test_clock.h" |
| 24 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
| 25 #include "base/time/time.h" | 25 #include "base/time/time.h" |
| 26 #include "components/image_fetcher/image_decoder.h" | 26 #include "components/image_fetcher/image_decoder.h" |
| 27 #include "components/image_fetcher/image_fetcher.h" | 27 #include "components/image_fetcher/image_fetcher.h" |
| 28 #include "components/image_fetcher/image_fetcher_delegate.h" | 28 #include "components/image_fetcher/image_fetcher_delegate.h" |
| 29 #include "components/ntp_snippets/category_factory.h" | 29 #include "components/ntp_snippets/category.h" |
| 30 #include "components/ntp_snippets/category_info.h" | 30 #include "components/ntp_snippets/category_info.h" |
| 31 #include "components/ntp_snippets/category_rankers/category_ranker.h" | |
| 32 #include "components/ntp_snippets/category_rankers/constant_category_ranker.h" | |
| 31 #include "components/ntp_snippets/ntp_snippets_constants.h" | 33 #include "components/ntp_snippets/ntp_snippets_constants.h" |
| 32 #include "components/ntp_snippets/pref_names.h" | 34 #include "components/ntp_snippets/pref_names.h" |
| 33 #include "components/ntp_snippets/remote/ntp_snippet.h" | 35 #include "components/ntp_snippets/remote/ntp_snippet.h" |
| 34 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" | 36 #include "components/ntp_snippets/remote/ntp_snippets_fetcher.h" |
| 35 #include "components/ntp_snippets/remote/ntp_snippets_scheduler.h" | 37 #include "components/ntp_snippets/remote/ntp_snippets_scheduler.h" |
| 36 #include "components/ntp_snippets/remote/remote_suggestions_database.h" | 38 #include "components/ntp_snippets/remote/remote_suggestions_database.h" |
| 37 #include "components/ntp_snippets/remote/test_utils.h" | 39 #include "components/ntp_snippets/remote/test_utils.h" |
| 38 #include "components/ntp_snippets/user_classifier.h" | 40 #include "components/ntp_snippets/user_classifier.h" |
| 39 #include "components/prefs/testing_pref_service.h" | 41 #include "components/prefs/testing_pref_service.h" |
| 40 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" | 42 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 base::Time GetDefaultCreationTime() { | 111 base::Time GetDefaultCreationTime() { |
| 110 base::Time out_time; | 112 base::Time out_time; |
| 111 EXPECT_TRUE(base::Time::FromUTCExploded(kDefaultCreationTime, &out_time)); | 113 EXPECT_TRUE(base::Time::FromUTCExploded(kDefaultCreationTime, &out_time)); |
| 112 return out_time; | 114 return out_time; |
| 113 } | 115 } |
| 114 | 116 |
| 115 base::Time GetDefaultExpirationTime() { | 117 base::Time GetDefaultExpirationTime() { |
| 116 return base::Time::Now() + base::TimeDelta::FromHours(1); | 118 return base::Time::Now() + base::TimeDelta::FromHours(1); |
| 117 } | 119 } |
| 118 | 120 |
| 121 std::string GetCategoryJson(const std::vector<std::string>& snippets, | |
| 122 int remote_category_id, | |
| 123 const std::string& category_title) { | |
| 124 return base::StringPrintf( | |
| 125 " {\n" | |
| 126 " \"id\": %d,\n" | |
| 127 " \"localizedTitle\": \"%s\",\n" | |
| 128 " \"suggestions\": [%s]\n" | |
| 129 " }\n", | |
| 130 remote_category_id, category_title.c_str(), | |
| 131 base::JoinString(snippets, ", ").c_str()); | |
| 132 } | |
| 133 | |
| 134 class MutliCategoryJsonBuilder { | |
|
Marc Treib
2016/12/14 10:24:31
s/Mutli/Multi/g
vitaliii
2016/12/15 15:30:12
Done.
| |
| 135 public: | |
| 136 MutliCategoryJsonBuilder() {} | |
| 137 | |
| 138 MutliCategoryJsonBuilder& AddCategoryWithCustomTitle( | |
| 139 const std::vector<std::string>& snippets, | |
| 140 int remote_category_id, | |
| 141 const std::string& category_title) { | |
| 142 category_json.push_back( | |
| 143 GetCategoryJson(snippets, remote_category_id, category_title)); | |
| 144 return *this; | |
| 145 } | |
| 146 | |
| 147 MutliCategoryJsonBuilder& AddCategory( | |
| 148 const std::vector<std::string>& snippets, | |
| 149 int remote_category_id) { | |
| 150 return AddCategoryWithCustomTitle( | |
| 151 snippets, remote_category_id, | |
| 152 "Title" + base::IntToString(remote_category_id)); | |
| 153 } | |
| 154 | |
| 155 std::string Build() { | |
| 156 return base::StringPrintf( | |
| 157 "{\n" | |
| 158 " \"categories\": [\n" | |
| 159 "%s\n" | |
| 160 " ]\n" | |
| 161 "}\n", | |
| 162 base::JoinString(category_json, " ,\n").c_str()); | |
| 163 } | |
| 164 | |
| 165 private: | |
| 166 std::vector<std::string> category_json; | |
| 167 }; | |
| 168 | |
| 119 std::string GetTestJson(const std::vector<std::string>& snippets, | 169 std::string GetTestJson(const std::vector<std::string>& snippets, |
| 120 const std::string& category_title) { | 170 const std::string& category_title) { |
| 121 return base::StringPrintf( | 171 return MutliCategoryJsonBuilder() |
| 122 "{\n" | 172 .AddCategoryWithCustomTitle(snippets, /*remote_category_id=*/1, |
| 123 " \"categories\": [{\n" | 173 category_title) |
| 124 " \"id\": 1,\n" | 174 .Build(); |
| 125 " \"localizedTitle\": \"%s\",\n" | |
| 126 " \"suggestions\": [%s]\n" | |
| 127 " }]\n" | |
| 128 "}\n", | |
| 129 category_title.c_str(), base::JoinString(snippets, ", ").c_str()); | |
| 130 } | 175 } |
| 131 | 176 |
| 132 std::string GetTestJson(const std::vector<std::string>& snippets) { | 177 std::string GetTestJson(const std::vector<std::string>& snippets) { |
| 133 return GetTestJson(snippets, kTestJsonDefaultCategoryTitle); | 178 return GetTestJson(snippets, kTestJsonDefaultCategoryTitle); |
| 134 } | 179 } |
| 135 | 180 |
| 136 // TODO(tschumann): Remove the default parameter other_id. It makes the tests | |
| 137 // less explicit and hard to read. Also get rid of the convenience | |
| 138 // other_category() and unknown_category() helpers -- tests can just define | |
| 139 // their own. | |
| 140 std::string GetMultiCategoryJson(const std::vector<std::string>& articles, | |
| 141 const std::vector<std::string>& others, | |
| 142 int other_id = 2) { | |
| 143 return base::StringPrintf( | |
| 144 "{\n" | |
| 145 " \"categories\": [{\n" | |
| 146 " \"id\": 1,\n" | |
| 147 " \"localizedTitle\": \"Articles for You\",\n" | |
| 148 " \"suggestions\": [%s]\n" | |
| 149 " }, {\n" | |
| 150 " \"id\": %i,\n" | |
| 151 " \"localizedTitle\": \"Other Things\",\n" | |
| 152 " \"suggestions\": [%s]\n" | |
| 153 " }]\n" | |
| 154 "}\n", | |
| 155 base::JoinString(articles, ", ").c_str(), other_id, | |
| 156 base::JoinString(others, ", ").c_str()); | |
| 157 } | |
| 158 | |
| 159 std::string FormatTime(const base::Time& t) { | 181 std::string FormatTime(const base::Time& t) { |
| 160 base::Time::Exploded x; | 182 base::Time::Exploded x; |
| 161 t.UTCExplode(&x); | 183 t.UTCExplode(&x); |
| 162 return base::StringPrintf("%04d-%02d-%02dT%02d:%02d:%02dZ", x.year, x.month, | 184 return base::StringPrintf("%04d-%02d-%02dT%02d:%02d:%02dZ", x.year, x.month, |
| 163 x.day_of_month, x.hour, x.minute, x.second); | 185 x.day_of_month, x.hour, x.minute, x.second); |
| 164 } | 186 } |
| 165 | 187 |
| 166 std::string GetSnippetWithUrlAndTimesAndSource( | 188 std::string GetSnippetWithUrlAndTimesAndSource( |
| 167 const std::vector<std::string>& ids, | 189 const std::vector<std::string>& ids, |
| 168 const std::string& url, | 190 const std::string& url, |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 class RemoteSuggestionsProviderTest : public ::testing::Test { | 416 class RemoteSuggestionsProviderTest : public ::testing::Test { |
| 395 public: | 417 public: |
| 396 RemoteSuggestionsProviderTest() | 418 RemoteSuggestionsProviderTest() |
| 397 : params_manager_(ntp_snippets::kStudyName, | 419 : params_manager_(ntp_snippets::kStudyName, |
| 398 {{"content_suggestions_backend", | 420 {{"content_suggestions_backend", |
| 399 kTestContentSuggestionsServerEndpoint}, | 421 kTestContentSuggestionsServerEndpoint}, |
| 400 {"fetching_personalization", "non_personal"}}), | 422 {"fetching_personalization", "non_personal"}}), |
| 401 fake_url_fetcher_factory_( | 423 fake_url_fetcher_factory_( |
| 402 /*default_factory=*/&failing_url_fetcher_factory_), | 424 /*default_factory=*/&failing_url_fetcher_factory_), |
| 403 test_url_(kTestContentSuggestionsServerWithAPIKey), | 425 test_url_(kTestContentSuggestionsServerWithAPIKey), |
| 426 category_ranker_(base::MakeUnique<ConstantCategoryRanker>()), | |
| 404 user_classifier_(/*pref_service=*/nullptr), | 427 user_classifier_(/*pref_service=*/nullptr), |
| 405 image_fetcher_(nullptr), | 428 image_fetcher_(nullptr), |
| 406 image_decoder_(nullptr) { | 429 image_decoder_(nullptr) { |
| 407 RemoteSuggestionsProvider::RegisterProfilePrefs( | 430 RemoteSuggestionsProvider::RegisterProfilePrefs( |
| 408 utils_.pref_service()->registry()); | 431 utils_.pref_service()->registry()); |
| 409 RequestThrottler::RegisterProfilePrefs(utils_.pref_service()->registry()); | 432 RequestThrottler::RegisterProfilePrefs(utils_.pref_service()->registry()); |
| 410 | 433 |
| 411 EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); | 434 EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); |
| 412 } | 435 } |
| 413 | 436 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 429 MakeSnippetsServiceWithoutInitialization() { | 452 MakeSnippetsServiceWithoutInitialization() { |
| 430 scoped_refptr<base::SingleThreadTaskRunner> task_runner( | 453 scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| 431 base::ThreadTaskRunnerHandle::Get()); | 454 base::ThreadTaskRunnerHandle::Get()); |
| 432 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = | 455 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = |
| 433 new net::TestURLRequestContextGetter(task_runner.get()); | 456 new net::TestURLRequestContextGetter(task_runner.get()); |
| 434 | 457 |
| 435 utils_.ResetSigninManager(); | 458 utils_.ResetSigninManager(); |
| 436 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher = | 459 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher = |
| 437 base::MakeUnique<NTPSnippetsFetcher>( | 460 base::MakeUnique<NTPSnippetsFetcher>( |
| 438 utils_.fake_signin_manager(), fake_token_service_.get(), | 461 utils_.fake_signin_manager(), fake_token_service_.get(), |
| 439 std::move(request_context_getter), utils_.pref_service(), | 462 std::move(request_context_getter), utils_.pref_service(), nullptr, |
| 440 &category_factory_, nullptr, base::Bind(&ParseJson), kAPIKey, | 463 base::Bind(&ParseJson), kAPIKey, &user_classifier_); |
| 441 &user_classifier_); | |
| 442 | 464 |
| 443 utils_.fake_signin_manager()->SignIn("foo@bar.com"); | 465 utils_.fake_signin_manager()->SignIn("foo@bar.com"); |
| 444 | 466 |
| 445 auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>(); | 467 auto image_fetcher = base::MakeUnique<NiceMock<MockImageFetcher>>(); |
| 446 | 468 |
| 447 image_fetcher_ = image_fetcher.get(); | 469 image_fetcher_ = image_fetcher.get(); |
| 448 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_)); | 470 EXPECT_CALL(*image_fetcher, SetImageFetcherDelegate(_)); |
| 449 auto image_decoder = base::MakeUnique<FakeImageDecoder>(); | 471 auto image_decoder = base::MakeUnique<FakeImageDecoder>(); |
| 450 image_decoder_ = image_decoder.get(); | 472 image_decoder_ = image_decoder.get(); |
| 451 EXPECT_FALSE(observer_); | 473 EXPECT_FALSE(observer_); |
| 452 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>(); | 474 observer_ = base::MakeUnique<FakeContentSuggestionsProviderObserver>(); |
| 453 return base::MakeUnique<RemoteSuggestionsProvider>( | 475 return base::MakeUnique<RemoteSuggestionsProvider>( |
| 454 observer_.get(), &category_factory_, utils_.pref_service(), "fr", | 476 observer_.get(), utils_.pref_service(), "fr", category_ranker_.get(), |
| 455 &user_classifier_, &scheduler_, std::move(snippets_fetcher), | 477 &user_classifier_, &scheduler_, std::move(snippets_fetcher), |
| 456 std::move(image_fetcher), std::move(image_decoder), | 478 std::move(image_fetcher), std::move(image_decoder), |
| 457 base::MakeUnique<RemoteSuggestionsDatabase>(database_dir_.GetPath(), | 479 base::MakeUnique<RemoteSuggestionsDatabase>(database_dir_.GetPath(), |
| 458 task_runner), | 480 task_runner), |
| 459 base::MakeUnique<RemoteSuggestionsStatusService>( | 481 base::MakeUnique<RemoteSuggestionsStatusService>( |
| 460 utils_.fake_signin_manager(), utils_.pref_service())); | 482 utils_.fake_signin_manager(), utils_.pref_service())); |
| 461 } | 483 } |
| 462 | 484 |
| 463 void WaitForSnippetsServiceInitialization(RemoteSuggestionsProvider* service, | 485 void WaitForSnippetsServiceInitialization(RemoteSuggestionsProvider* service, |
| 464 bool set_empty_response) { | 486 bool set_empty_response) { |
| 465 EXPECT_EQ(RemoteSuggestionsProvider::State::NOT_INITED, service->state_); | 487 EXPECT_EQ(RemoteSuggestionsProvider::State::NOT_INITED, service->state_); |
| 466 | 488 |
| 467 // Add an initial fetch response, as the service tries to fetch when there | 489 // Add an initial fetch response, as the service tries to fetch when there |
| 468 // is nothing in the DB. | 490 // is nothing in the DB. |
| 469 if (set_empty_response) { | 491 if (set_empty_response) { |
| 470 SetUpFetchResponse(GetTestJson(std::vector<std::string>())); | 492 SetUpFetchResponse(GetTestJson(std::vector<std::string>())); |
| 471 } | 493 } |
| 472 | 494 |
| 473 // TODO(treib): Find a better way to wait for initialization to finish. | 495 // TODO(treib): Find a better way to wait for initialization to finish. |
| 474 base::RunLoop().RunUntilIdle(); | 496 base::RunLoop().RunUntilIdle(); |
| 475 EXPECT_NE(RemoteSuggestionsProvider::State::NOT_INITED, service->state_); | 497 EXPECT_NE(RemoteSuggestionsProvider::State::NOT_INITED, service->state_); |
| 476 } | 498 } |
| 477 | 499 |
| 478 void ResetSnippetsService( | 500 void ResetSnippetsService( |
| 479 std::unique_ptr<RemoteSuggestionsProvider>* service) { | 501 std::unique_ptr<RemoteSuggestionsProvider>* service) { |
| 480 service->reset(); | 502 service->reset(); |
| 503 category_ranker_ = base::MakeUnique<ConstantCategoryRanker>(); | |
|
Marc Treib
2016/12/14 10:24:31
If this needs to be reset here, then it should als
vitaliii
2016/12/15 15:30:12
Done.
It does, ResetSnippetsService must simulat
| |
| 481 observer_.reset(); | 504 observer_.reset(); |
| 482 *service = MakeSnippetsService(); | 505 *service = MakeSnippetsService(); |
| 483 } | 506 } |
| 484 | 507 |
| 508 std::vector<Category> SortCategories(std::vector<Category> categories) { | |
|
Marc Treib
2016/12/14 10:24:31
Either pass by const ref, or pass in a pointer and
vitaliii
2016/12/15 15:30:12
Done.
The function was removed completely.
| |
| 509 std::sort(categories.begin(), categories.end(), | |
| 510 [this](Category left, Category right) { | |
| 511 return category_ranker_->Compare(left, right); | |
| 512 }); | |
| 513 return categories; | |
| 514 } | |
| 515 | |
| 485 ContentSuggestion::ID MakeArticleID(const std::string& id_within_category) { | 516 ContentSuggestion::ID MakeArticleID(const std::string& id_within_category) { |
| 486 return ContentSuggestion::ID(articles_category(), id_within_category); | 517 return ContentSuggestion::ID(articles_category(), id_within_category); |
| 487 } | 518 } |
| 488 | 519 |
| 489 Category articles_category() { | 520 Category articles_category() { |
| 490 return category_factory_.FromKnownCategory(KnownCategories::ARTICLES); | 521 return Category::FromKnownCategory(KnownCategories::ARTICLES); |
| 491 } | 522 } |
| 492 | 523 |
| 493 ContentSuggestion::ID MakeOtherID(const std::string& id_within_category) { | 524 ContentSuggestion::ID MakeOtherID(const std::string& id_within_category) { |
| 494 return ContentSuggestion::ID(other_category(), id_within_category); | 525 return ContentSuggestion::ID(other_category(), id_within_category); |
| 495 } | 526 } |
| 496 | 527 |
| 497 Category other_category() { return category_factory_.FromRemoteCategory(2); } | 528 // TODO(tschumann): Get rid of the convenience other_category() and |
| 529 // unknown_category() helpers -- tests can just define their own. | |
| 530 Category other_category() { return Category::FromRemoteCategory(2); } | |
| 498 | 531 |
| 499 Category unknown_category() { | 532 Category unknown_category() { |
| 500 return category_factory_.FromRemoteCategory(kUnknownRemoteCategoryId); | 533 return Category::FromRemoteCategory(kUnknownRemoteCategoryId); |
| 501 } | 534 } |
| 502 | 535 |
| 503 protected: | 536 protected: |
| 504 const GURL& test_url() { return test_url_; } | 537 const GURL& test_url() { return test_url_; } |
| 505 FakeContentSuggestionsProviderObserver& observer() { return *observer_; } | 538 FakeContentSuggestionsProviderObserver& observer() { return *observer_; } |
| 506 MockScheduler& mock_scheduler() { return scheduler_; } | 539 MockScheduler& mock_scheduler() { return scheduler_; } |
| 507 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary | 540 // TODO(tschumann): Make this a strict-mock. We want to avoid unneccesary |
| 508 // network requests. | 541 // network requests. |
| 509 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } | 542 NiceMock<MockImageFetcher>* image_fetcher() { return image_fetcher_; } |
| 510 FakeImageDecoder* image_decoder() { return image_decoder_; } | 543 FakeImageDecoder* image_decoder() { return image_decoder_; } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 535 | 568 |
| 536 private: | 569 private: |
| 537 variations::testing::VariationParamsManager params_manager_; | 570 variations::testing::VariationParamsManager params_manager_; |
| 538 test::RemoteSuggestionsTestUtils utils_; | 571 test::RemoteSuggestionsTestUtils utils_; |
| 539 base::MessageLoop message_loop_; | 572 base::MessageLoop message_loop_; |
| 540 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; | 573 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; |
| 541 // Instantiation of factory automatically sets itself as URLFetcher's factory. | 574 // Instantiation of factory automatically sets itself as URLFetcher's factory. |
| 542 net::FakeURLFetcherFactory fake_url_fetcher_factory_; | 575 net::FakeURLFetcherFactory fake_url_fetcher_factory_; |
| 543 const GURL test_url_; | 576 const GURL test_url_; |
| 544 std::unique_ptr<OAuth2TokenService> fake_token_service_; | 577 std::unique_ptr<OAuth2TokenService> fake_token_service_; |
| 578 std::unique_ptr<CategoryRanker> category_ranker_; | |
| 545 UserClassifier user_classifier_; | 579 UserClassifier user_classifier_; |
| 546 NiceMock<MockScheduler> scheduler_; | 580 NiceMock<MockScheduler> scheduler_; |
| 547 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; | 581 std::unique_ptr<FakeContentSuggestionsProviderObserver> observer_; |
| 548 CategoryFactory category_factory_; | |
| 549 NiceMock<MockImageFetcher>* image_fetcher_; | 582 NiceMock<MockImageFetcher>* image_fetcher_; |
| 550 FakeImageDecoder* image_decoder_; | 583 FakeImageDecoder* image_decoder_; |
| 551 | 584 |
| 552 base::ScopedTempDir database_dir_; | 585 base::ScopedTempDir database_dir_; |
| 553 | 586 |
| 554 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderTest); | 587 DISALLOW_COPY_AND_ASSIGN(RemoteSuggestionsProviderTest); |
| 555 }; | 588 }; |
| 556 | 589 |
| 557 TEST_F(RemoteSuggestionsProviderTest, ScheduleOnStart) { | 590 TEST_F(RemoteSuggestionsProviderTest, ScheduleOnStart) { |
| 558 // We should get two |Schedule| calls: The first when initialization | 591 // We should get two |Schedule| calls: The first when initialization |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 723 CategoryInfo info_with_title = service->GetCategoryInfo(articles_category()); | 756 CategoryInfo info_with_title = service->GetCategoryInfo(articles_category()); |
| 724 EXPECT_THAT(info_before.title(), Not(Eq(info_with_title.title()))); | 757 EXPECT_THAT(info_before.title(), Not(Eq(info_with_title.title()))); |
| 725 EXPECT_THAT(test_default_title, Eq(info_with_title.title())); | 758 EXPECT_THAT(test_default_title, Eq(info_with_title.title())); |
| 726 EXPECT_THAT(info_before.has_more_action(), Eq(true)); | 759 EXPECT_THAT(info_before.has_more_action(), Eq(true)); |
| 727 EXPECT_THAT(info_before.has_reload_action(), Eq(true)); | 760 EXPECT_THAT(info_before.has_reload_action(), Eq(true)); |
| 728 EXPECT_THAT(info_before.has_view_all_action(), Eq(false)); | 761 EXPECT_THAT(info_before.has_view_all_action(), Eq(false)); |
| 729 EXPECT_THAT(info_before.show_if_empty(), Eq(true)); | 762 EXPECT_THAT(info_before.show_if_empty(), Eq(true)); |
| 730 } | 763 } |
| 731 | 764 |
| 732 TEST_F(RemoteSuggestionsProviderTest, MultipleCategories) { | 765 TEST_F(RemoteSuggestionsProviderTest, MultipleCategories) { |
| 733 std::string json_str( | |
| 734 GetMultiCategoryJson({GetSnippetN(0)}, {GetSnippetN(1)})); | |
| 735 | |
| 736 auto service = MakeSnippetsService(); | 766 auto service = MakeSnippetsService(); |
| 737 | 767 std::string json_str = |
| 768 MutliCategoryJsonBuilder() | |
| 769 .AddCategory({GetSnippetN(0)}, /*remote_category_id=*/1) | |
| 770 .AddCategory({GetSnippetN(1)}, /*remote_category_id=*/2) | |
| 771 .Build(); | |
| 738 LoadFromJSONString(service.get(), json_str); | 772 LoadFromJSONString(service.get(), json_str); |
| 739 | 773 |
| 740 ASSERT_THAT(observer().statuses(), | 774 ASSERT_THAT(observer().statuses(), |
| 741 Eq(std::map<Category, CategoryStatus, Category::CompareByID>{ | 775 Eq(std::map<Category, CategoryStatus, Category::CompareByID>{ |
| 742 {articles_category(), CategoryStatus::AVAILABLE}, | 776 {articles_category(), CategoryStatus::AVAILABLE}, |
| 743 {other_category(), CategoryStatus::AVAILABLE}, | 777 {other_category(), CategoryStatus::AVAILABLE}, |
| 744 })); | 778 })); |
| 745 | 779 |
| 746 EXPECT_THAT(service->GetSnippetsForTesting(articles_category()), SizeIs(1)); | 780 EXPECT_THAT(service->GetSnippetsForTesting(articles_category()), SizeIs(1)); |
| 747 EXPECT_THAT(service->GetSnippetsForTesting(other_category()), SizeIs(1)); | 781 EXPECT_THAT(service->GetSnippetsForTesting(other_category()), SizeIs(1)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 780 auto service = MakeSnippetsService(); | 814 auto service = MakeSnippetsService(); |
| 781 CategoryInfo article_info = service->GetCategoryInfo(articles_category()); | 815 CategoryInfo article_info = service->GetCategoryInfo(articles_category()); |
| 782 EXPECT_THAT(article_info.has_more_action(), Eq(true)); | 816 EXPECT_THAT(article_info.has_more_action(), Eq(true)); |
| 783 EXPECT_THAT(article_info.has_reload_action(), Eq(true)); | 817 EXPECT_THAT(article_info.has_reload_action(), Eq(true)); |
| 784 EXPECT_THAT(article_info.has_view_all_action(), Eq(false)); | 818 EXPECT_THAT(article_info.has_view_all_action(), Eq(false)); |
| 785 EXPECT_THAT(article_info.show_if_empty(), Eq(true)); | 819 EXPECT_THAT(article_info.show_if_empty(), Eq(true)); |
| 786 } | 820 } |
| 787 | 821 |
| 788 TEST_F(RemoteSuggestionsProviderTest, ExperimentalCategoryInfo) { | 822 TEST_F(RemoteSuggestionsProviderTest, ExperimentalCategoryInfo) { |
| 789 auto service = MakeSnippetsService(); | 823 auto service = MakeSnippetsService(); |
| 790 | 824 std::string json_str = |
| 825 MutliCategoryJsonBuilder() | |
| 826 .AddCategory({GetSnippetN(0)}, /*remote_category_id=*/1) | |
| 827 .AddCategory({GetSnippetN(1)}, kUnknownRemoteCategoryId) | |
| 828 .Build(); | |
| 791 // Load data with multiple categories so that a new experimental category gets | 829 // Load data with multiple categories so that a new experimental category gets |
| 792 // registered. | 830 // registered. |
| 793 LoadFromJSONString(service.get(), | 831 LoadFromJSONString(service.get(), json_str); |
| 794 GetMultiCategoryJson({GetSnippetN(0)}, {GetSnippetN(1)}, | 832 |
| 795 kUnknownRemoteCategoryId)); | |
| 796 CategoryInfo info = service->GetCategoryInfo(unknown_category()); | 833 CategoryInfo info = service->GetCategoryInfo(unknown_category()); |
| 797 EXPECT_THAT(info.has_more_action(), Eq(false)); | 834 EXPECT_THAT(info.has_more_action(), Eq(false)); |
| 798 EXPECT_THAT(info.has_reload_action(), Eq(false)); | 835 EXPECT_THAT(info.has_reload_action(), Eq(false)); |
| 799 EXPECT_THAT(info.has_view_all_action(), Eq(false)); | 836 EXPECT_THAT(info.has_view_all_action(), Eq(false)); |
| 800 EXPECT_THAT(info.show_if_empty(), Eq(false)); | 837 EXPECT_THAT(info.show_if_empty(), Eq(false)); |
| 801 } | 838 } |
| 802 | 839 |
| 803 TEST_F(RemoteSuggestionsProviderTest, PersistCategoryInfos) { | 840 TEST_F(RemoteSuggestionsProviderTest, PersistCategoryInfos) { |
| 804 auto service = MakeSnippetsService(); | 841 auto service = MakeSnippetsService(); |
| 805 | 842 // TODO(vitaliii): Use |articles_category()| instead of constant ID below. |
| 806 LoadFromJSONString(service.get(), | 843 std::string json_str = |
| 807 GetMultiCategoryJson({GetSnippetN(0)}, {GetSnippetN(1)}, | 844 MutliCategoryJsonBuilder() |
| 808 kUnknownRemoteCategoryId)); | 845 .AddCategoryWithCustomTitle( |
| 846 {GetSnippetN(0)}, /*remote_category_id=*/1, "Articles for You") | |
| 847 .AddCategoryWithCustomTitle({GetSnippetN(1)}, | |
| 848 kUnknownRemoteCategoryId, "Other Things") | |
| 849 .Build(); | |
| 850 LoadFromJSONString(service.get(), json_str); | |
| 809 | 851 |
| 810 ASSERT_EQ(observer().StatusForCategory(articles_category()), | 852 ASSERT_EQ(observer().StatusForCategory(articles_category()), |
| 811 CategoryStatus::AVAILABLE); | 853 CategoryStatus::AVAILABLE); |
| 812 ASSERT_EQ(observer().StatusForCategory(unknown_category()), | 854 ASSERT_EQ(observer().StatusForCategory(unknown_category()), |
| 813 CategoryStatus::AVAILABLE); | 855 CategoryStatus::AVAILABLE); |
| 814 | 856 |
| 815 CategoryInfo info_articles_before = | 857 CategoryInfo info_articles_before = |
| 816 service->GetCategoryInfo(articles_category()); | 858 service->GetCategoryInfo(articles_category()); |
| 817 CategoryInfo info_unknown_before = | 859 CategoryInfo info_unknown_before = |
| 818 service->GetCategoryInfo(unknown_category()); | 860 service->GetCategoryInfo(unknown_category()); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 833 | 875 |
| 834 CategoryInfo info_articles_after = | 876 CategoryInfo info_articles_after = |
| 835 service->GetCategoryInfo(articles_category()); | 877 service->GetCategoryInfo(articles_category()); |
| 836 CategoryInfo info_unknown_after = | 878 CategoryInfo info_unknown_after = |
| 837 service->GetCategoryInfo(unknown_category()); | 879 service->GetCategoryInfo(unknown_category()); |
| 838 | 880 |
| 839 EXPECT_EQ(info_articles_before.title(), info_articles_after.title()); | 881 EXPECT_EQ(info_articles_before.title(), info_articles_after.title()); |
| 840 EXPECT_EQ(info_unknown_before.title(), info_unknown_after.title()); | 882 EXPECT_EQ(info_unknown_before.title(), info_unknown_after.title()); |
| 841 } | 883 } |
| 842 | 884 |
| 885 TEST_F(RemoteSuggestionsProviderTest, PersistRemoteCategoryOrder) { | |
| 886 auto service = MakeSnippetsService(); | |
| 887 std::string json_str = | |
| 888 MutliCategoryJsonBuilder() | |
| 889 .AddCategory({GetSnippetN(0)}, /*remote_category_id=*/1) | |
| 890 .AddCategory({GetSnippetN(1)}, /*remote_category_id=*/3) | |
| 891 .AddCategory({GetSnippetN(2)}, /*remote_category_id=*/2) | |
| 892 .Build(); | |
| 893 LoadFromJSONString(service.get(), json_str); | |
| 894 | |
| 895 std::vector<Category> unordered_categories = { | |
| 896 Category::FromRemoteCategory(1), Category::FromRemoteCategory(2), | |
| 897 Category::FromRemoteCategory(3)}; | |
| 898 std::vector<Category> ordered_categories = {Category::FromRemoteCategory(1), | |
| 899 Category::FromRemoteCategory(3), | |
| 900 Category::FromRemoteCategory(2)}; | |
| 901 ASSERT_EQ(ordered_categories, SortCategories(unordered_categories)); | |
| 902 | |
| 903 // Recreate the service to simulate a Chrome restart. The ranker does not | |
| 904 // persist the order. | |
| 905 ResetSnippetsService(&service); | |
| 906 | |
| 907 // The categories should have been restored in the same order. | |
| 908 EXPECT_EQ(ordered_categories, SortCategories(unordered_categories)); | |
|
Marc Treib
2016/12/14 10:24:31
Hm, I find this hard to follow - it's not easy to
vitaliii
2016/12/15 15:30:12
Done.
Rewrote with the mock, but I am not sure wh
| |
| 909 } | |
| 910 | |
| 843 TEST_F(RemoteSuggestionsProviderTest, PersistSuggestions) { | 911 TEST_F(RemoteSuggestionsProviderTest, PersistSuggestions) { |
| 844 auto service = MakeSnippetsService(); | 912 auto service = MakeSnippetsService(); |
| 845 | 913 std::string json_str = |
| 846 LoadFromJSONString(service.get(), | 914 MutliCategoryJsonBuilder() |
| 847 GetMultiCategoryJson({GetSnippetN(0)}, {GetSnippetN(1)})); | 915 .AddCategory({GetSnippetN(0)}, /*remote_category_id=*/1) |
| 916 .AddCategory({GetSnippetN(2)}, /*remote_category_id=*/2) | |
| 917 .Build(); | |
| 918 LoadFromJSONString(service.get(), json_str); | |
| 848 | 919 |
| 849 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), | 920 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), |
| 850 SizeIs(1)); | 921 SizeIs(1)); |
| 851 ASSERT_THAT(observer().SuggestionsForCategory(other_category()), SizeIs(1)); | 922 ASSERT_THAT(observer().SuggestionsForCategory(other_category()), SizeIs(1)); |
| 852 | 923 |
| 853 // Recreate the service to simulate a Chrome restart. | 924 // Recreate the service to simulate a Chrome restart. |
| 854 ResetSnippetsService(&service); | 925 ResetSnippetsService(&service); |
| 855 | 926 |
| 856 // The suggestions in both categories should have been restored. | 927 // The suggestions in both categories should have been restored. |
| 857 EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), | 928 EXPECT_THAT(observer().SuggestionsForCategory(articles_category()), |
| 858 SizeIs(1)); | 929 SizeIs(1)); |
| 859 EXPECT_THAT(observer().SuggestionsForCategory(other_category()), SizeIs(1)); | 930 EXPECT_THAT(observer().SuggestionsForCategory(other_category()), SizeIs(1)); |
| 860 } | 931 } |
| 861 | 932 |
| 862 TEST_F(RemoteSuggestionsProviderTest, DontNotifyIfNotAvailable) { | 933 TEST_F(RemoteSuggestionsProviderTest, DontNotifyIfNotAvailable) { |
| 863 // Get some suggestions into the database. | 934 // Get some suggestions into the database. |
| 864 auto service = MakeSnippetsService(); | 935 auto service = MakeSnippetsService(); |
| 865 LoadFromJSONString(service.get(), | 936 std::string json_str = |
| 866 GetMultiCategoryJson({GetSnippetN(0)}, {GetSnippetN(1)})); | 937 MutliCategoryJsonBuilder() |
| 938 .AddCategory({GetSnippetN(0)}, | |
| 939 /*remote_category_id=*/1) | |
| 940 .AddCategory({GetSnippetN(1)}, /*remote_category_id=*/2) | |
| 941 .Build(); | |
| 942 LoadFromJSONString(service.get(), json_str); | |
| 943 | |
| 867 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), | 944 ASSERT_THAT(observer().SuggestionsForCategory(articles_category()), |
| 868 SizeIs(1)); | 945 SizeIs(1)); |
| 869 ASSERT_THAT(observer().SuggestionsForCategory(other_category()), SizeIs(1)); | 946 ASSERT_THAT(observer().SuggestionsForCategory(other_category()), SizeIs(1)); |
| 870 | 947 |
| 871 service.reset(); | 948 service.reset(); |
| 872 | 949 |
| 873 // Set the pref that disables remote suggestions. | 950 // Set the pref that disables remote suggestions. |
| 874 pref_service()->SetBoolean(prefs::kEnableSnippets, false); | 951 pref_service()->SetBoolean(prefs::kEnableSnippets, false); |
| 875 | 952 |
| 876 // Recreate the service to simulate a Chrome start. | 953 // Recreate the service to simulate a Chrome start. |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1620 service->FetchSnippetsInTheBackground(); | 1697 service->FetchSnippetsInTheBackground(); |
| 1621 base::RunLoop().RunUntilIdle(); | 1698 base::RunLoop().RunUntilIdle(); |
| 1622 EXPECT_EQ( | 1699 EXPECT_EQ( |
| 1623 simple_test_clock_ptr->Now().ToInternalValue(), | 1700 simple_test_clock_ptr->Now().ToInternalValue(), |
| 1624 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime)); | 1701 pref_service()->GetInt64(prefs::kLastSuccessfulBackgroundFetchTime)); |
| 1625 // TODO(markusheintz): Add a test that simulates a browser restart once the | 1702 // TODO(markusheintz): Add a test that simulates a browser restart once the |
| 1626 // scheduler refactoring is done (crbug.com/672434). | 1703 // scheduler refactoring is done (crbug.com/672434). |
| 1627 } | 1704 } |
| 1628 | 1705 |
| 1629 } // namespace ntp_snippets | 1706 } // namespace ntp_snippets |
| OLD | NEW |