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

Side by Side Diff: components/ntp_snippets/remote/remote_suggestions_provider_unittest.cc

Issue 2568033005: [NTP::SectionOrder] Replace CategoryFactory with a category ranker. (Closed)
Patch Set: rebase & treib@ comments & ios. Created 4 years 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 unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698