| 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/ntp_snippets_service.h" | 5 #include "components/ntp_snippets/ntp_snippets_service.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" | 34 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" |
| 35 #include "components/signin/core/browser/fake_signin_manager.h" | 35 #include "components/signin/core/browser/fake_signin_manager.h" |
| 36 #include "google_apis/google_api_keys.h" | 36 #include "google_apis/google_api_keys.h" |
| 37 #include "net/url_request/test_url_fetcher_factory.h" | 37 #include "net/url_request/test_url_fetcher_factory.h" |
| 38 #include "net/url_request/url_request_test_util.h" | 38 #include "net/url_request/url_request_test_util.h" |
| 39 #include "testing/gmock/include/gmock/gmock.h" | 39 #include "testing/gmock/include/gmock/gmock.h" |
| 40 #include "testing/gtest/include/gtest/gtest.h" | 40 #include "testing/gtest/include/gtest/gtest.h" |
| 41 | 41 |
| 42 using testing::ElementsAre; | 42 using testing::ElementsAre; |
| 43 using testing::Eq; | 43 using testing::Eq; |
| 44 using testing::Invoke; |
| 45 using testing::IsEmpty; |
| 46 using testing::Mock; |
| 44 using testing::Return; | 47 using testing::Return; |
| 45 using testing::IsEmpty; | |
| 46 using testing::SizeIs; | 48 using testing::SizeIs; |
| 47 using testing::StartsWith; | 49 using testing::StartsWith; |
| 48 using testing::_; | 50 using testing::_; |
| 49 | 51 |
| 50 namespace ntp_snippets { | 52 namespace ntp_snippets { |
| 51 | 53 |
| 52 namespace { | 54 namespace { |
| 53 | 55 |
| 54 MATCHER_P(IdEq, value, "") { | 56 MATCHER_P(IdEq, value, "") { |
| 55 return arg->id() == value; | 57 return arg->id() == value; |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 class MockScheduler : public NTPSnippetsScheduler { | 219 class MockScheduler : public NTPSnippetsScheduler { |
| 218 public: | 220 public: |
| 219 MOCK_METHOD4(Schedule, | 221 MOCK_METHOD4(Schedule, |
| 220 bool(base::TimeDelta period_wifi_charging, | 222 bool(base::TimeDelta period_wifi_charging, |
| 221 base::TimeDelta period_wifi, | 223 base::TimeDelta period_wifi, |
| 222 base::TimeDelta period_fallback, | 224 base::TimeDelta period_fallback, |
| 223 base::Time reschedule_time)); | 225 base::Time reschedule_time)); |
| 224 MOCK_METHOD0(Unschedule, bool()); | 226 MOCK_METHOD0(Unschedule, bool()); |
| 225 }; | 227 }; |
| 226 | 228 |
| 227 class MockServiceObserver : public NTPSnippetsServiceObserver { | 229 class MockProviderObserver : public ContentSuggestionsProvider::Observer { |
| 228 public: | 230 public: |
| 229 MOCK_METHOD0(NTPSnippetsServiceLoaded, void()); | 231 void OnNewSuggestions(ContentSuggestionsProvider* provider, |
| 230 MOCK_METHOD0(NTPSnippetsServiceShutdown, void()); | 232 Category category, |
| 231 MOCK_METHOD1(NTPSnippetsServiceDisabledReasonChanged, | 233 std::vector<ContentSuggestion> suggestions) override {} |
| 232 void(DisabledReason disabled_reason)); | 234 MOCK_METHOD3(OnCategoryStatusChanged, |
| 235 void(ContentSuggestionsProvider* provider, |
| 236 Category category, |
| 237 CategoryStatus new_status)); |
| 233 }; | 238 }; |
| 234 | 239 |
| 235 class WaitForDBLoad : public NTPSnippetsServiceObserver { | 240 class WaitForDBLoad { |
| 236 public: | 241 public: |
| 237 WaitForDBLoad(NTPSnippetsService* service) : service_(service) { | 242 WaitForDBLoad(MockProviderObserver* observer, NTPSnippetsService* service) |
| 238 service_->AddObserver(this); | 243 : observer_(observer) { |
| 239 if (!service_->ready()) | 244 EXPECT_CALL(*observer_, OnCategoryStatusChanged(_, _, _)) |
| 245 .WillOnce(Invoke(this, &WaitForDBLoad::OnCategoryStatusChanged)); |
| 246 if (!service->ready()) |
| 240 run_loop_.Run(); | 247 run_loop_.Run(); |
| 241 } | 248 } |
| 242 | 249 |
| 243 ~WaitForDBLoad() override { | 250 ~WaitForDBLoad() { Mock::VerifyAndClearExpectations(observer_); } |
| 244 service_->RemoveObserver(this); | |
| 245 } | |
| 246 | 251 |
| 247 private: | 252 private: |
| 248 void NTPSnippetsServiceLoaded() override { | 253 void OnCategoryStatusChanged(ContentSuggestionsProvider* provider, |
| 249 EXPECT_TRUE(service_->ready()); | 254 Category category, |
| 255 CategoryStatus new_status) { |
| 256 EXPECT_EQ(new_status, CategoryStatus::AVAILABLE_LOADING); |
| 250 run_loop_.Quit(); | 257 run_loop_.Quit(); |
| 251 } | 258 } |
| 252 | 259 |
| 253 void NTPSnippetsServiceShutdown() override {} | 260 MockProviderObserver* observer_; |
| 254 void NTPSnippetsServiceDisabledReasonChanged( | |
| 255 DisabledReason disabled_reason) override {} | |
| 256 | |
| 257 NTPSnippetsService* service_; | |
| 258 base::RunLoop run_loop_; | 261 base::RunLoop run_loop_; |
| 259 | 262 |
| 260 DISALLOW_COPY_AND_ASSIGN(WaitForDBLoad); | 263 DISALLOW_COPY_AND_ASSIGN(WaitForDBLoad); |
| 261 }; | 264 }; |
| 262 | 265 |
| 263 } // namespace | 266 } // namespace |
| 264 | 267 |
| 265 class NTPSnippetsServiceTest : public test::NTPSnippetsTestBase { | 268 class NTPSnippetsServiceTest : public test::NTPSnippetsTestBase { |
| 266 public: | 269 public: |
| 267 NTPSnippetsServiceTest() | 270 NTPSnippetsServiceTest() |
| 268 : fake_url_fetcher_factory_( | 271 : fake_url_fetcher_factory_( |
| 269 /*default_factory=*/&failing_url_fetcher_factory_), | 272 /*default_factory=*/&failing_url_fetcher_factory_), |
| 270 test_url_(base::StringPrintf(kTestContentSnippetsServerFormat, | 273 test_url_(base::StringPrintf(kTestContentSnippetsServerFormat, |
| 271 google_apis::GetAPIKey().c_str())) { | 274 google_apis::GetAPIKey().c_str())) { |
| 272 NTPSnippetsService::RegisterProfilePrefs(pref_service()->registry()); | 275 NTPSnippetsService::RegisterProfilePrefs(pref_service()->registry()); |
| 273 RequestThrottler::RegisterProfilePrefs(pref_service()->registry()); | 276 RequestThrottler::RegisterProfilePrefs(pref_service()->registry()); |
| 274 | 277 |
| 275 // Since no SuggestionsService is injected in tests, we need to force the | 278 // Since no SuggestionsService is injected in tests, we need to force the |
| 276 // service to fetch from all hosts. | 279 // service to fetch from all hosts. |
| 277 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 280 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 278 switches::kDontRestrict); | 281 switches::kDontRestrict); |
| 279 EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); | 282 EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); |
| 280 } | 283 } |
| 281 | 284 |
| 282 ~NTPSnippetsServiceTest() override { | 285 ~NTPSnippetsServiceTest() override { |
| 283 if (service_) | |
| 284 service_->Shutdown(); | |
| 285 | |
| 286 // We need to run the message loop after deleting the database, because | 286 // We need to run the message loop after deleting the database, because |
| 287 // ProtoDatabaseImpl deletes the actual LevelDB asynchronously on the task | 287 // ProtoDatabaseImpl deletes the actual LevelDB asynchronously on the task |
| 288 // runner. Without this, we'd get reports of memory leaks. | 288 // runner. Without this, we'd get reports of memory leaks. |
| 289 Mock::VerifyAndClear(&mock_scheduler()); |
| 289 service_.reset(); | 290 service_.reset(); |
| 290 base::RunLoop().RunUntilIdle(); | 291 base::RunLoop().RunUntilIdle(); |
| 291 } | 292 } |
| 292 | 293 |
| 293 void SetUp() override { | 294 void SetUp() override { |
| 294 test::NTPSnippetsTestBase::SetUp(); | 295 test::NTPSnippetsTestBase::SetUp(); |
| 295 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); | 296 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); |
| 296 CreateSnippetsService(/*enabled=*/true); | 297 CreateSnippetsService(); |
| 297 } | 298 } |
| 298 | 299 |
| 299 void CreateSnippetsService(bool enabled) { | 300 void RecreateSnippetsService() { |
| 300 if (service_) | 301 Mock::VerifyAndClear(&mock_scheduler()); |
| 301 service_->Shutdown(); | 302 service_.reset(); |
| 303 base::RunLoop().RunUntilIdle(); |
| 304 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); |
| 305 CreateSnippetsService(); |
| 306 } |
| 307 |
| 308 void CreateSnippetsService() { |
| 309 DCHECK(!service_); |
| 302 | 310 |
| 303 scoped_refptr<base::SingleThreadTaskRunner> task_runner( | 311 scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| 304 base::ThreadTaskRunnerHandle::Get()); | 312 base::ThreadTaskRunnerHandle::Get()); |
| 305 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = | 313 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = |
| 306 new net::TestURLRequestContextGetter(task_runner.get()); | 314 new net::TestURLRequestContextGetter(task_runner.get()); |
| 307 | 315 |
| 308 // Delete the current service, so that the database is destroyed before we | |
| 309 // create the new one, otherwise opening the new database will fail. | |
| 310 service_.reset(); | |
| 311 | |
| 312 ResetSigninManager(); | 316 ResetSigninManager(); |
| 313 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher = | 317 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher = |
| 314 base::MakeUnique<NTPSnippetsFetcher>( | 318 base::MakeUnique<NTPSnippetsFetcher>( |
| 315 fake_signin_manager(), fake_token_service_.get(), | 319 fake_signin_manager(), fake_token_service_.get(), |
| 316 std::move(request_context_getter), pref_service(), | 320 std::move(request_context_getter), pref_service(), |
| 317 base::Bind(&ParseJson), | 321 base::Bind(&ParseJson), |
| 318 /*is_stable_channel=*/true); | 322 /*is_stable_channel=*/true); |
| 319 | 323 |
| 320 fake_signin_manager()->SignIn("foo@bar.com"); | 324 fake_signin_manager()->SignIn("foo@bar.com"); |
| 321 snippets_fetcher->SetPersonalizationForTesting( | 325 snippets_fetcher->SetPersonalizationForTesting( |
| 322 NTPSnippetsFetcher::Personalization::kNonPersonal); | 326 NTPSnippetsFetcher::Personalization::kNonPersonal); |
| 323 | 327 |
| 324 // Add an initial fetch response, as the service tries to fetch when there | 328 // Add an initial fetch response, as the service tries to fetch when there |
| 325 // is nothing in the DB. | 329 // is nothing in the DB. |
| 326 SetUpFetchResponse(GetTestJson({GetSnippet()})); | 330 SetUpFetchResponse(GetTestJson({GetSnippet()})); |
| 327 | 331 |
| 328 service_.reset(new NTPSnippetsService( | 332 service_.reset(new NTPSnippetsService( |
| 329 enabled, pref_service(), nullptr, &category_factory_, "fr", &scheduler_, | 333 &observer_, &category_factory_, pref_service(), nullptr, "fr", |
| 330 std::move(snippets_fetcher), /*image_fetcher=*/nullptr, | 334 &scheduler_, std::move(snippets_fetcher), /*image_fetcher=*/nullptr, |
| 331 /*image_fetcher=*/nullptr, base::MakeUnique<NTPSnippetsDatabase>( | 335 /*image_fetcher=*/nullptr, base::MakeUnique<NTPSnippetsDatabase>( |
| 332 database_dir_.path(), task_runner), | 336 database_dir_.path(), task_runner), |
| 333 base::MakeUnique<NTPSnippetsStatusService>(fake_signin_manager(), | 337 base::MakeUnique<NTPSnippetsStatusService>(fake_signin_manager(), |
| 334 pref_service()))); | 338 pref_service()))); |
| 335 | 339 |
| 336 if (enabled) | 340 WaitForDBLoad(&observer_, service_.get()); |
| 337 WaitForDBLoad(service_.get()); | |
| 338 } | 341 } |
| 339 | 342 |
| 340 std::string MakeUniqueID(const std::string& within_category_id) { | 343 std::string MakeUniqueID(const std::string& within_category_id) { |
| 341 return service()->MakeUniqueID( | 344 return service()->MakeUniqueID( |
| 342 category_factory_.FromKnownCategory(KnownCategories::ARTICLES), | 345 category_factory_.FromKnownCategory(KnownCategories::ARTICLES), |
| 343 within_category_id); | 346 within_category_id); |
| 344 } | 347 } |
| 345 | 348 |
| 346 protected: | 349 protected: |
| 347 const GURL& test_url() { return test_url_; } | 350 const GURL& test_url() { return test_url_; } |
| 348 NTPSnippetsService* service() { return service_.get(); } | 351 NTPSnippetsService* service() { return service_.get(); } |
| 349 MockScheduler& mock_scheduler() { return scheduler_; } | 352 MockProviderObserver& observer() { return observer_; } |
| 353 MockScheduler& mock_scheduler() { return scheduler_; } |
| 350 | 354 |
| 351 // Provide the json to be returned by the fake fetcher. | 355 // Provide the json to be returned by the fake fetcher. |
| 352 void SetUpFetchResponse(const std::string& json) { | 356 void SetUpFetchResponse(const std::string& json) { |
| 353 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, | 357 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, |
| 354 net::URLRequestStatus::SUCCESS); | 358 net::URLRequestStatus::SUCCESS); |
| 355 } | 359 } |
| 356 | 360 |
| 357 void LoadFromJSONString(const std::string& json) { | 361 void LoadFromJSONString(const std::string& json) { |
| 358 SetUpFetchResponse(json); | 362 SetUpFetchResponse(json); |
| 359 service()->FetchSnippets(true); | 363 service()->FetchSnippets(true); |
| 360 base::RunLoop().RunUntilIdle(); | 364 base::RunLoop().RunUntilIdle(); |
| 361 } | 365 } |
| 362 | 366 |
| 363 private: | 367 private: |
| 364 base::MessageLoop message_loop_; | 368 base::MessageLoop message_loop_; |
| 365 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; | 369 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; |
| 366 // Instantiation of factory automatically sets itself as URLFetcher's factory. | 370 // Instantiation of factory automatically sets itself as URLFetcher's factory. |
| 367 net::FakeURLFetcherFactory fake_url_fetcher_factory_; | 371 net::FakeURLFetcherFactory fake_url_fetcher_factory_; |
| 368 const GURL test_url_; | 372 const GURL test_url_; |
| 369 std::unique_ptr<OAuth2TokenService> fake_token_service_; | 373 std::unique_ptr<OAuth2TokenService> fake_token_service_; |
| 370 MockScheduler scheduler_; | 374 MockScheduler scheduler_; |
| 375 MockProviderObserver observer_; |
| 371 CategoryFactory category_factory_; | 376 CategoryFactory category_factory_; |
| 372 // Last so that the dependencies are deleted after the service. | 377 // Last so that the dependencies are deleted after the service. |
| 373 std::unique_ptr<NTPSnippetsService> service_; | 378 std::unique_ptr<NTPSnippetsService> service_; |
| 374 | 379 |
| 375 base::ScopedTempDir database_dir_; | 380 base::ScopedTempDir database_dir_; |
| 376 | 381 |
| 377 DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest); | 382 DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest); |
| 378 }; | 383 }; |
| 379 | 384 |
| 380 class NTPSnippetsServiceDisabledTest : public NTPSnippetsServiceTest { | 385 TEST_F(NTPSnippetsServiceTest, ScheduleOnStart) { |
| 381 public: | |
| 382 void SetUp() override { | |
| 383 test::NTPSnippetsTestBase::SetUp(); | |
| 384 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1); | |
| 385 CreateSnippetsService(/*enabled=*/false); | |
| 386 } | |
| 387 }; | |
| 388 | |
| 389 TEST_F(NTPSnippetsServiceTest, ScheduleIfEnabled) { | |
| 390 // SetUp() checks that Schedule is called. | 386 // SetUp() checks that Schedule is called. |
| 391 | 387 |
| 392 // When we have no snippets are all, loading the service initiates a fetch. | 388 // When we have no snippets are all, loading the service initiates a fetch. |
| 393 base::RunLoop().RunUntilIdle(); | 389 base::RunLoop().RunUntilIdle(); |
| 394 ASSERT_EQ("OK", service()->snippets_fetcher()->last_status()); | 390 ASSERT_EQ("OK", service()->snippets_fetcher()->last_status()); |
| 395 } | 391 } |
| 396 | 392 |
| 397 TEST_F(NTPSnippetsServiceDisabledTest, Unschedule) { | |
| 398 // SetUp() checks that Unschedule is called. | |
| 399 | |
| 400 // Make sure we don't fetch anything. | |
| 401 base::RunLoop().RunUntilIdle(); | |
| 402 EXPECT_THAT(service()->snippets_fetcher()->last_status(), IsEmpty()); | |
| 403 } | |
| 404 | |
| 405 TEST_F(NTPSnippetsServiceTest, Full) { | 393 TEST_F(NTPSnippetsServiceTest, Full) { |
| 406 std::string json_str(GetTestJson({GetSnippet()})); | 394 std::string json_str(GetTestJson({GetSnippet()})); |
| 407 | 395 |
| 408 LoadFromJSONString(json_str); | 396 LoadFromJSONString(json_str); |
| 409 ASSERT_THAT(service()->snippets(), SizeIs(1)); | 397 ASSERT_THAT(service()->snippets(), SizeIs(1)); |
| 410 const NTPSnippet& snippet = *service()->snippets().front(); | 398 const NTPSnippet& snippet = *service()->snippets().front(); |
| 411 | 399 |
| 412 EXPECT_EQ(snippet.id(), kSnippetUrl); | 400 EXPECT_EQ(snippet.id(), kSnippetUrl); |
| 413 EXPECT_EQ(snippet.title(), kSnippetTitle); | 401 EXPECT_EQ(snippet.title(), kSnippetTitle); |
| 414 EXPECT_EQ(snippet.snippet(), kSnippetText); | 402 EXPECT_EQ(snippet.snippet(), kSnippetText); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 | 502 |
| 515 // Dismiss the snippet. | 503 // Dismiss the snippet. |
| 516 service()->DismissSuggestion(MakeUniqueID(kSnippetUrl)); | 504 service()->DismissSuggestion(MakeUniqueID(kSnippetUrl)); |
| 517 EXPECT_THAT(service()->snippets(), IsEmpty()); | 505 EXPECT_THAT(service()->snippets(), IsEmpty()); |
| 518 | 506 |
| 519 // Make sure that fetching the same snippet again does not re-add it. | 507 // Make sure that fetching the same snippet again does not re-add it. |
| 520 LoadFromJSONString(json_str); | 508 LoadFromJSONString(json_str); |
| 521 EXPECT_THAT(service()->snippets(), IsEmpty()); | 509 EXPECT_THAT(service()->snippets(), IsEmpty()); |
| 522 | 510 |
| 523 // The snippet should stay dismissed even after re-creating the service. | 511 // The snippet should stay dismissed even after re-creating the service. |
| 524 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); | 512 RecreateSnippetsService(); |
| 525 CreateSnippetsService(/*enabled=*/true); | |
| 526 LoadFromJSONString(json_str); | 513 LoadFromJSONString(json_str); |
| 527 EXPECT_THAT(service()->snippets(), IsEmpty()); | 514 EXPECT_THAT(service()->snippets(), IsEmpty()); |
| 528 | 515 |
| 529 // The snippet can be added again after clearing dismissed snippets. | 516 // The snippet can be added again after clearing dismissed snippets. |
| 530 service()->ClearDismissedSuggestionsForDebugging(); | 517 service()->ClearDismissedSuggestionsForDebugging(); |
| 531 EXPECT_THAT(service()->snippets(), IsEmpty()); | 518 EXPECT_THAT(service()->snippets(), IsEmpty()); |
| 532 LoadFromJSONString(json_str); | 519 LoadFromJSONString(json_str); |
| 533 EXPECT_THAT(service()->snippets(), SizeIs(1)); | 520 EXPECT_THAT(service()->snippets(), SizeIs(1)); |
| 534 } | 521 } |
| 535 | 522 |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 base::Bucket(/*min=*/1, /*count=*/2))); | 816 base::Bucket(/*min=*/1, /*count=*/2))); |
| 830 // Dismissed snippets shouldn't influence NumArticlesFetched. | 817 // Dismissed snippets shouldn't influence NumArticlesFetched. |
| 831 EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"), | 818 EXPECT_THAT(tester.GetAllSamples("NewTabPage.Snippets.NumArticlesFetched"), |
| 832 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1), | 819 ElementsAre(base::Bucket(/*min=*/0, /*count=*/1), |
| 833 base::Bucket(/*min=*/1, /*count=*/3))); | 820 base::Bucket(/*min=*/1, /*count=*/3))); |
| 834 EXPECT_THAT( | 821 EXPECT_THAT( |
| 835 tester.GetAllSamples("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded"), | 822 tester.GetAllSamples("NewTabPage.Snippets.NumArticlesZeroDueToDiscarded"), |
| 836 ElementsAre(base::Bucket(/*min=*/1, /*count=*/1))); | 823 ElementsAre(base::Bucket(/*min=*/1, /*count=*/1))); |
| 837 // Recreating the service and loading from prefs shouldn't count as fetched | 824 // Recreating the service and loading from prefs shouldn't count as fetched |
| 838 // articles. | 825 // articles. |
| 839 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); | 826 RecreateSnippetsService(); |
| 840 CreateSnippetsService(/*enabled=*/true); | |
| 841 tester.ExpectTotalCount("NewTabPage.Snippets.NumArticlesFetched", 4); | 827 tester.ExpectTotalCount("NewTabPage.Snippets.NumArticlesFetched", 4); |
| 842 } | 828 } |
| 843 | 829 |
| 844 TEST_F(NTPSnippetsServiceTest, DismissShouldRespectAllKnownUrls) { | 830 TEST_F(NTPSnippetsServiceTest, DismissShouldRespectAllKnownUrls) { |
| 845 const std::string creation = | 831 const std::string creation = |
| 846 NTPSnippet::TimeToJsonString(GetDefaultCreationTime()); | 832 NTPSnippet::TimeToJsonString(GetDefaultCreationTime()); |
| 847 const std::string expiry = | 833 const std::string expiry = |
| 848 NTPSnippet::TimeToJsonString(GetDefaultExpirationTime()); | 834 NTPSnippet::TimeToJsonString(GetDefaultExpirationTime()); |
| 849 const std::vector<std::string> source_urls = { | 835 const std::vector<std::string> source_urls = { |
| 850 "http://mashable.com/2016/05/11/stolen", | 836 "http://mashable.com/2016/05/11/stolen", |
| (...skipping 13 matching lines...) Expand all Loading... |
| 864 service()->DismissSuggestion(MakeUniqueID(source_urls[0])); | 850 service()->DismissSuggestion(MakeUniqueID(source_urls[0])); |
| 865 EXPECT_THAT(service()->snippets(), IsEmpty()); | 851 EXPECT_THAT(service()->snippets(), IsEmpty()); |
| 866 | 852 |
| 867 // The same article from the AOL domain should now be detected as dismissed. | 853 // The same article from the AOL domain should now be detected as dismissed. |
| 868 LoadFromJSONString(GetTestJson({GetSnippetWithUrlAndTimesAndSources( | 854 LoadFromJSONString(GetTestJson({GetSnippetWithUrlAndTimesAndSources( |
| 869 source_urls[1], creation, expiry, source_urls, publishers, amp_urls)})); | 855 source_urls[1], creation, expiry, source_urls, publishers, amp_urls)})); |
| 870 ASSERT_THAT(service()->snippets(), IsEmpty()); | 856 ASSERT_THAT(service()->snippets(), IsEmpty()); |
| 871 } | 857 } |
| 872 | 858 |
| 873 TEST_F(NTPSnippetsServiceTest, StatusChanges) { | 859 TEST_F(NTPSnippetsServiceTest, StatusChanges) { |
| 874 MockServiceObserver mock_observer; | |
| 875 service()->AddObserver(&mock_observer); | |
| 876 | |
| 877 // Simulate user signed out | 860 // Simulate user signed out |
| 878 SetUpFetchResponse(GetTestJson({GetSnippet()})); | 861 SetUpFetchResponse(GetTestJson({GetSnippet()})); |
| 879 EXPECT_CALL(mock_observer, NTPSnippetsServiceDisabledReasonChanged( | 862 EXPECT_CALL(observer(), |
| 880 DisabledReason::SIGNED_OUT)); | 863 OnCategoryStatusChanged(_, _, CategoryStatus::SIGNED_OUT)); |
| 881 service()->OnDisabledReasonChanged(DisabledReason::SIGNED_OUT); | 864 service()->OnDisabledReasonChanged(DisabledReason::SIGNED_OUT); |
| 882 base::RunLoop().RunUntilIdle(); | 865 base::RunLoop().RunUntilIdle(); |
| 883 EXPECT_EQ(NTPSnippetsService::State::DISABLED, service()->state_); | 866 EXPECT_EQ(NTPSnippetsService::State::DISABLED, service()->state_); |
| 884 EXPECT_THAT(service()->snippets(), IsEmpty()); // No fetch should be made. | 867 EXPECT_THAT(service()->snippets(), IsEmpty()); // No fetch should be made. |
| 885 | 868 |
| 886 // Simulate user sign in. The service should be ready again and load snippets. | 869 // Simulate user sign in. The service should be ready again and load snippets. |
| 887 SetUpFetchResponse(GetTestJson({GetSnippet()})); | 870 SetUpFetchResponse(GetTestJson({GetSnippet()})); |
| 888 EXPECT_CALL(mock_observer, | 871 EXPECT_CALL(observer(), |
| 889 NTPSnippetsServiceDisabledReasonChanged(DisabledReason::NONE)); | 872 OnCategoryStatusChanged(_, _, CategoryStatus::AVAILABLE_LOADING)); |
| 890 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); | 873 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); |
| 891 service()->OnDisabledReasonChanged(DisabledReason::NONE); | 874 service()->OnDisabledReasonChanged(DisabledReason::NONE); |
| 875 EXPECT_CALL(observer(), |
| 876 OnCategoryStatusChanged(_, _, CategoryStatus::AVAILABLE)); |
| 892 base::RunLoop().RunUntilIdle(); | 877 base::RunLoop().RunUntilIdle(); |
| 893 EXPECT_EQ(NTPSnippetsService::State::READY, service()->state_); | 878 EXPECT_EQ(NTPSnippetsService::State::READY, service()->state_); |
| 894 EXPECT_FALSE(service()->snippets().empty()); | 879 EXPECT_FALSE(service()->snippets().empty()); |
| 895 | |
| 896 service()->RemoveObserver(&mock_observer); | |
| 897 } | 880 } |
| 898 | 881 |
| 899 } // namespace ntp_snippets | 882 } // namespace ntp_snippets |
| OLD | NEW |