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 |