| 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" |
| 11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
| 12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "base/test/histogram_tester.h" | 21 #include "base/test/histogram_tester.h" |
| 22 #include "base/threading/thread_task_runner_handle.h" | 22 #include "base/threading/thread_task_runner_handle.h" |
| 23 #include "base/time/time.h" | 23 #include "base/time/time.h" |
| 24 #include "components/image_fetcher/image_decoder.h" | 24 #include "components/image_fetcher/image_decoder.h" |
| 25 #include "components/image_fetcher/image_fetcher.h" | 25 #include "components/image_fetcher/image_fetcher.h" |
| 26 #include "components/ntp_snippets/ntp_snippet.h" | 26 #include "components/ntp_snippets/ntp_snippet.h" |
| 27 #include "components/ntp_snippets/ntp_snippets_database.h" | 27 #include "components/ntp_snippets/ntp_snippets_database.h" |
| 28 #include "components/ntp_snippets/ntp_snippets_fetcher.h" | 28 #include "components/ntp_snippets/ntp_snippets_fetcher.h" |
| 29 #include "components/ntp_snippets/ntp_snippets_scheduler.h" | 29 #include "components/ntp_snippets/ntp_snippets_scheduler.h" |
| 30 #include "components/ntp_snippets/ntp_snippets_test_utils.h" |
| 30 #include "components/ntp_snippets/switches.h" | 31 #include "components/ntp_snippets/switches.h" |
| 31 #include "components/prefs/testing_pref_service.h" | 32 #include "components/prefs/testing_pref_service.h" |
| 32 #include "components/signin/core/browser/account_tracker_service.h" | |
| 33 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" | 33 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" |
| 34 #include "components/signin/core/browser/fake_signin_manager.h" | 34 #include "components/signin/core/browser/fake_signin_manager.h" |
| 35 #include "components/signin/core/browser/test_signin_client.h" | |
| 36 #include "components/sync_driver/fake_sync_service.h" | |
| 37 #include "google_apis/google_api_keys.h" | 35 #include "google_apis/google_api_keys.h" |
| 38 #include "net/url_request/test_url_fetcher_factory.h" | 36 #include "net/url_request/test_url_fetcher_factory.h" |
| 39 #include "net/url_request/url_request_test_util.h" | 37 #include "net/url_request/url_request_test_util.h" |
| 40 #include "testing/gmock/include/gmock/gmock.h" | 38 #include "testing/gmock/include/gmock/gmock.h" |
| 41 #include "testing/gtest/include/gtest/gtest.h" | 39 #include "testing/gtest/include/gtest/gtest.h" |
| 42 | 40 |
| 43 using testing::ElementsAre; | 41 using testing::ElementsAre; |
| 44 using testing::Eq; | 42 using testing::Eq; |
| 45 using testing::Return; | 43 using testing::Return; |
| 46 using testing::IsEmpty; | 44 using testing::IsEmpty; |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 error_callback.Run(json_reader.GetErrorMessage()); | 198 error_callback.Run(json_reader.GetErrorMessage()); |
| 201 } | 199 } |
| 202 } | 200 } |
| 203 | 201 |
| 204 // Factory for FakeURLFetcher objects that always generate errors. | 202 // Factory for FakeURLFetcher objects that always generate errors. |
| 205 class FailingFakeURLFetcherFactory : public net::URLFetcherFactory { | 203 class FailingFakeURLFetcherFactory : public net::URLFetcherFactory { |
| 206 public: | 204 public: |
| 207 std::unique_ptr<net::URLFetcher> CreateURLFetcher( | 205 std::unique_ptr<net::URLFetcher> CreateURLFetcher( |
| 208 int id, const GURL& url, net::URLFetcher::RequestType request_type, | 206 int id, const GURL& url, net::URLFetcher::RequestType request_type, |
| 209 net::URLFetcherDelegate* d) override { | 207 net::URLFetcherDelegate* d) override { |
| 210 return base::WrapUnique(new net::FakeURLFetcher( | 208 return base::MakeUnique<net::FakeURLFetcher>( |
| 211 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND, | 209 url, d, /*response_data=*/std::string(), net::HTTP_NOT_FOUND, |
| 212 net::URLRequestStatus::FAILED)); | 210 net::URLRequestStatus::FAILED); |
| 213 } | 211 } |
| 214 }; | 212 }; |
| 215 | 213 |
| 216 class MockScheduler : public NTPSnippetsScheduler { | 214 class MockScheduler : public NTPSnippetsScheduler { |
| 217 public: | 215 public: |
| 218 MOCK_METHOD4(Schedule, | 216 MOCK_METHOD4(Schedule, |
| 219 bool(base::TimeDelta period_wifi_charging, | 217 bool(base::TimeDelta period_wifi_charging, |
| 220 base::TimeDelta period_wifi, | 218 base::TimeDelta period_wifi, |
| 221 base::TimeDelta period_fallback, | 219 base::TimeDelta period_fallback, |
| 222 base::Time reschedule_time)); | 220 base::Time reschedule_time)); |
| 223 MOCK_METHOD0(Unschedule, bool()); | 221 MOCK_METHOD0(Unschedule, bool()); |
| 224 }; | 222 }; |
| 225 | 223 |
| 226 class MockSyncService : public sync_driver::FakeSyncService { | |
| 227 public: | |
| 228 MockSyncService() {} | |
| 229 virtual ~MockSyncService() {} | |
| 230 MOCK_CONST_METHOD0(CanSyncStart, bool()); | |
| 231 MOCK_CONST_METHOD0(IsSyncActive, bool()); | |
| 232 MOCK_CONST_METHOD0(ConfigurationDone, bool()); | |
| 233 MOCK_CONST_METHOD0(GetActiveDataTypes, syncer::ModelTypeSet()); | |
| 234 }; | |
| 235 | |
| 236 class MockServiceObserver : public NTPSnippetsServiceObserver { | 224 class MockServiceObserver : public NTPSnippetsServiceObserver { |
| 237 public: | 225 public: |
| 238 MOCK_METHOD0(NTPSnippetsServiceLoaded, void()); | 226 MOCK_METHOD0(NTPSnippetsServiceLoaded, void()); |
| 239 MOCK_METHOD0(NTPSnippetsServiceShutdown, void()); | 227 MOCK_METHOD0(NTPSnippetsServiceShutdown, void()); |
| 240 MOCK_METHOD0(NTPSnippetsServiceDisabled, void()); | 228 MOCK_METHOD1(NTPSnippetsServiceDisabledReasonChanged, |
| 229 void(DisabledReason disabled_reason)); |
| 241 }; | 230 }; |
| 242 | 231 |
| 243 class WaitForDBLoad : public NTPSnippetsServiceObserver { | 232 class WaitForDBLoad : public NTPSnippetsServiceObserver { |
| 244 public: | 233 public: |
| 245 WaitForDBLoad(NTPSnippetsService* service) : service_(service) { | 234 WaitForDBLoad(NTPSnippetsService* service) : service_(service) { |
| 246 service_->AddObserver(this); | 235 service_->AddObserver(this); |
| 247 if (!service_->ready()) | 236 if (!service_->ready()) |
| 248 run_loop_.Run(); | 237 run_loop_.Run(); |
| 249 } | 238 } |
| 250 | 239 |
| 251 ~WaitForDBLoad() override { | 240 ~WaitForDBLoad() override { |
| 252 service_->RemoveObserver(this); | 241 service_->RemoveObserver(this); |
| 253 } | 242 } |
| 254 | 243 |
| 255 private: | 244 private: |
| 256 void NTPSnippetsServiceLoaded() override { | 245 void NTPSnippetsServiceLoaded() override { |
| 257 EXPECT_TRUE(service_->ready()); | 246 EXPECT_TRUE(service_->ready()); |
| 258 run_loop_.Quit(); | 247 run_loop_.Quit(); |
| 259 } | 248 } |
| 260 | 249 |
| 261 void NTPSnippetsServiceShutdown() override {} | 250 void NTPSnippetsServiceShutdown() override {} |
| 262 void NTPSnippetsServiceDisabled() override {} | 251 void NTPSnippetsServiceDisabledReasonChanged( |
| 252 DisabledReason disabled_reason) override {} |
| 263 | 253 |
| 264 NTPSnippetsService* service_; | 254 NTPSnippetsService* service_; |
| 265 base::RunLoop run_loop_; | 255 base::RunLoop run_loop_; |
| 266 | 256 |
| 267 DISALLOW_COPY_AND_ASSIGN(WaitForDBLoad); | 257 DISALLOW_COPY_AND_ASSIGN(WaitForDBLoad); |
| 268 }; | 258 }; |
| 269 | 259 |
| 270 } // namespace | 260 } // namespace |
| 271 | 261 |
| 272 class NTPSnippetsServiceTest : public testing::Test { | 262 class NTPSnippetsServiceTest : public test::NTPSnippetsTestBase { |
| 273 public: | 263 public: |
| 274 NTPSnippetsServiceTest() | 264 NTPSnippetsServiceTest() |
| 275 : fake_url_fetcher_factory_( | 265 : fake_url_fetcher_factory_( |
| 276 /*default_factory=*/&failing_url_fetcher_factory_), | 266 /*default_factory=*/&failing_url_fetcher_factory_), |
| 277 test_url_(base::StringPrintf(kTestContentSnippetsServerFormat, | 267 test_url_(base::StringPrintf(kTestContentSnippetsServerFormat, |
| 278 google_apis::GetAPIKey().c_str())), | 268 google_apis::GetAPIKey().c_str())) { |
| 279 pref_service_(new TestingPrefServiceSimple()), | 269 NTPSnippetsService::RegisterProfilePrefs(pref_service()->registry()); |
| 280 signin_client_(new TestSigninClient(nullptr)), | 270 |
| 281 account_tracker_(new AccountTrackerService()), | |
| 282 fake_signin_manager_(new FakeSigninManagerBase(signin_client_.get(), | |
| 283 account_tracker_.get())), | |
| 284 fake_token_service_(new FakeProfileOAuth2TokenService()) { | |
| 285 NTPSnippetsService::RegisterProfilePrefs(pref_service_->registry()); | |
| 286 // Since no SuggestionsService is injected in tests, we need to force the | 271 // Since no SuggestionsService is injected in tests, we need to force the |
| 287 // service to fetch from all hosts. | 272 // service to fetch from all hosts. |
| 288 base::CommandLine::ForCurrentProcess()->AppendSwitch( | 273 base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| 289 switches::kDontRestrict); | 274 switches::kDontRestrict); |
| 290 EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); | 275 EXPECT_TRUE(database_dir_.CreateUniqueTempDir()); |
| 291 } | 276 } |
| 292 | 277 |
| 293 ~NTPSnippetsServiceTest() override { | 278 ~NTPSnippetsServiceTest() override { |
| 294 if (service_) | 279 if (service_) |
| 295 service_->Shutdown(); | 280 service_->Shutdown(); |
| 296 | 281 |
| 297 // We need to run the message loop after deleting the database, because | 282 // We need to run the message loop after deleting the database, because |
| 298 // ProtoDatabaseImpl deletes the actual LevelDB asynchronously on the task | 283 // ProtoDatabaseImpl deletes the actual LevelDB asynchronously on the task |
| 299 // runner. Without this, we'd get reports of memory leaks. | 284 // runner. Without this, we'd get reports of memory leaks. |
| 300 service_.reset(); | 285 service_.reset(); |
| 301 base::RunLoop().RunUntilIdle(); | 286 base::RunLoop().RunUntilIdle(); |
| 302 } | 287 } |
| 303 | 288 |
| 304 void SetUp() override { | 289 void SetUp() override { |
| 305 ResetSyncServiceMock(); | 290 test::NTPSnippetsTestBase::SetUp(); |
| 306 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); | 291 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); |
| 307 CreateSnippetsService(/*enabled=*/true); | 292 CreateSnippetsService(/*enabled=*/true); |
| 308 } | 293 } |
| 309 | 294 |
| 310 void CreateSnippetsService(bool enabled) { | 295 void CreateSnippetsService(bool enabled) { |
| 311 if (service_) | 296 if (service_) |
| 312 service_->Shutdown(); | 297 service_->Shutdown(); |
| 313 | 298 |
| 314 scoped_refptr<base::SingleThreadTaskRunner> task_runner( | 299 scoped_refptr<base::SingleThreadTaskRunner> task_runner( |
| 315 base::ThreadTaskRunnerHandle::Get()); | 300 base::ThreadTaskRunnerHandle::Get()); |
| 316 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = | 301 scoped_refptr<net::TestURLRequestContextGetter> request_context_getter = |
| 317 new net::TestURLRequestContextGetter(task_runner.get()); | 302 new net::TestURLRequestContextGetter(task_runner.get()); |
| 318 | 303 |
| 319 // Delete the current service, so that the database is destroyed before we | 304 // Delete the current service, so that the database is destroyed before we |
| 320 // create the new one, otherwise opening the new database will fail. | 305 // create the new one, otherwise opening the new database will fail. |
| 321 service_.reset(); | 306 service_.reset(); |
| 322 | 307 |
| 308 ResetSigninManager(); |
| 309 std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher = |
| 310 base::MakeUnique<NTPSnippetsFetcher>( |
| 311 fake_signin_manager(), fake_token_service_.get(), |
| 312 std::move(request_context_getter), base::Bind(&ParseJson), |
| 313 /*is_stable_channel=*/true); |
| 314 |
| 315 fake_signin_manager()->SignIn("foo@bar.com"); |
| 316 snippets_fetcher->SetPersonalizationForTesting( |
| 317 NTPSnippetsFetcher::Personalization::kNonPersonal); |
| 318 |
| 323 service_.reset(new NTPSnippetsService( | 319 service_.reset(new NTPSnippetsService( |
| 324 enabled, pref_service_.get(), mock_sync_service_.get(), nullptr, | 320 enabled, pref_service(), nullptr, "fr", &scheduler_, |
| 325 std::string("fr"), &scheduler_, | 321 std::move(snippets_fetcher), /*image_fetcher=*/nullptr, |
| 326 base::WrapUnique(new NTPSnippetsFetcher( | 322 /*image_fetcher=*/nullptr, base::MakeUnique<NTPSnippetsDatabase>( |
| 327 fake_signin_manager_.get(), fake_token_service_.get(), | 323 database_dir_.path(), task_runner), |
| 328 std::move(request_context_getter), base::Bind(&ParseJson), | 324 base::MakeUnique<NTPSnippetsStatusService>(fake_signin_manager(), |
| 329 /*is_stable_channel=*/true)), | 325 mock_sync_service()))); |
| 330 /*image_fetcher=*/nullptr, /*image_decoder=*/nullptr, | 326 |
| 331 base::WrapUnique(new NTPSnippetsDatabase(database_dir_.path(), | |
| 332 task_runner)))); | |
| 333 if (enabled) | 327 if (enabled) |
| 334 WaitForDBLoad(service_.get()); | 328 WaitForDBLoad(service_.get()); |
| 335 } | 329 } |
| 336 | 330 |
| 337 protected: | 331 protected: |
| 338 const GURL& test_url() { return test_url_; } | 332 const GURL& test_url() { return test_url_; } |
| 339 NTPSnippetsService* service() { return service_.get(); } | 333 NTPSnippetsService* service() { return service_.get(); } |
| 340 MockScheduler& mock_scheduler() { return scheduler_; } | 334 MockScheduler& mock_scheduler() { return scheduler_; } |
| 341 MockSyncService* mock_sync_service() { return mock_sync_service_.get(); } | |
| 342 | 335 |
| 343 // Provide the json to be returned by the fake fetcher. | 336 // Provide the json to be returned by the fake fetcher. |
| 344 void SetUpFetchResponse(const std::string& json) { | 337 void SetUpFetchResponse(const std::string& json) { |
| 345 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, | 338 fake_url_fetcher_factory_.SetFakeResponse(test_url_, json, net::HTTP_OK, |
| 346 net::URLRequestStatus::SUCCESS); | 339 net::URLRequestStatus::SUCCESS); |
| 347 } | 340 } |
| 348 | 341 |
| 349 void LoadFromJSONString(const std::string& json) { | 342 void LoadFromJSONString(const std::string& json) { |
| 350 SetUpFetchResponse(json); | 343 SetUpFetchResponse(json); |
| 351 service()->FetchSnippets(); | 344 service()->FetchSnippets(); |
| 352 base::RunLoop().RunUntilIdle(); | 345 base::RunLoop().RunUntilIdle(); |
| 353 } | 346 } |
| 354 | 347 |
| 355 // Call before the service is set up to initialize a sync service. | |
| 356 // Subsequent calls reset the return values of the mocked methods. | |
| 357 void ResetSyncServiceMock() { | |
| 358 if (!mock_sync_service_) { | |
| 359 // Use a NiceMock to avoid the "uninteresting call" warnings. | |
| 360 mock_sync_service_.reset(new testing::NiceMock<MockSyncService>); | |
| 361 } | |
| 362 | |
| 363 ON_CALL(*mock_sync_service_, CanSyncStart()).WillByDefault(Return(true)); | |
| 364 ON_CALL(*mock_sync_service_, IsSyncActive()).WillByDefault(Return(true)); | |
| 365 ON_CALL(*mock_sync_service_, ConfigurationDone()) | |
| 366 .WillByDefault(Return(true)); | |
| 367 ON_CALL(*mock_sync_service_, GetActiveDataTypes()) | |
| 368 .WillByDefault( | |
| 369 Return(syncer::ModelTypeSet(syncer::HISTORY_DELETE_DIRECTIVES))); | |
| 370 } | |
| 371 | |
| 372 private: | 348 private: |
| 373 base::MessageLoop message_loop_; | 349 base::MessageLoop message_loop_; |
| 374 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; | 350 FailingFakeURLFetcherFactory failing_url_fetcher_factory_; |
| 375 // Instantiation of factory automatically sets itself as URLFetcher's factory. | 351 // Instantiation of factory automatically sets itself as URLFetcher's factory. |
| 376 net::FakeURLFetcherFactory fake_url_fetcher_factory_; | 352 net::FakeURLFetcherFactory fake_url_fetcher_factory_; |
| 377 const GURL test_url_; | 353 const GURL test_url_; |
| 378 std::unique_ptr<TestingPrefServiceSimple> pref_service_; | |
| 379 std::unique_ptr<TestSigninClient> signin_client_; | |
| 380 std::unique_ptr<AccountTrackerService> account_tracker_; | |
| 381 std::unique_ptr<MockSyncService> mock_sync_service_; // Null by default. | |
| 382 std::unique_ptr<SigninManagerBase> fake_signin_manager_; | |
| 383 std::unique_ptr<OAuth2TokenService> fake_token_service_; | 354 std::unique_ptr<OAuth2TokenService> fake_token_service_; |
| 384 MockScheduler scheduler_; | 355 MockScheduler scheduler_; |
| 385 // Last so that the dependencies are deleted after the service. | 356 // Last so that the dependencies are deleted after the service. |
| 386 std::unique_ptr<NTPSnippetsService> service_; | 357 std::unique_ptr<NTPSnippetsService> service_; |
| 387 | 358 |
| 388 base::ScopedTempDir database_dir_; | 359 base::ScopedTempDir database_dir_; |
| 389 | 360 |
| 390 DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest); | 361 DISALLOW_COPY_AND_ASSIGN(NTPSnippetsServiceTest); |
| 391 }; | 362 }; |
| 392 | 363 |
| 393 class NTPSnippetsServiceDisabledTest : public NTPSnippetsServiceTest { | 364 class NTPSnippetsServiceDisabledTest : public NTPSnippetsServiceTest { |
| 394 public: | 365 public: |
| 395 void SetUp() override { | 366 void SetUp() override { |
| 367 test::NTPSnippetsTestBase::SetUp(); |
| 396 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1); | 368 EXPECT_CALL(mock_scheduler(), Unschedule()).Times(1); |
| 397 CreateSnippetsService(/*enabled=*/false); | 369 CreateSnippetsService(/*enabled=*/false); |
| 398 } | 370 } |
| 399 }; | 371 }; |
| 400 | 372 |
| 401 TEST_F(NTPSnippetsServiceTest, ScheduleIfEnabled) { | 373 TEST_F(NTPSnippetsServiceTest, ScheduleIfEnabled) { |
| 402 // SetUp() checks that Schedule is called. | 374 // SetUp() checks that Schedule is called. |
| 403 } | 375 } |
| 404 | 376 |
| 405 TEST_F(NTPSnippetsServiceDisabledTest, Unschedule) { | 377 TEST_F(NTPSnippetsServiceDisabledTest, Unschedule) { |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 // Discard the snippet via the mashable source corpus ID. | 840 // Discard the snippet via the mashable source corpus ID. |
| 869 EXPECT_TRUE(service()->DiscardSnippet(source_urls[0])); | 841 EXPECT_TRUE(service()->DiscardSnippet(source_urls[0])); |
| 870 EXPECT_THAT(service()->snippets(), IsEmpty()); | 842 EXPECT_THAT(service()->snippets(), IsEmpty()); |
| 871 | 843 |
| 872 // The same article from the AOL domain should now be detected as discarded. | 844 // The same article from the AOL domain should now be detected as discarded. |
| 873 LoadFromJSONString(GetTestJson({GetSnippetWithUrlAndTimesAndSources( | 845 LoadFromJSONString(GetTestJson({GetSnippetWithUrlAndTimesAndSources( |
| 874 source_urls[1], creation, expiry, source_urls, publishers, amp_urls)})); | 846 source_urls[1], creation, expiry, source_urls, publishers, amp_urls)})); |
| 875 ASSERT_THAT(service()->snippets(), IsEmpty()); | 847 ASSERT_THAT(service()->snippets(), IsEmpty()); |
| 876 } | 848 } |
| 877 | 849 |
| 878 TEST_F(NTPSnippetsServiceTest, SyncStateCompatibility) { | |
| 879 // The default test setup has a compatible sync state. | |
| 880 EXPECT_EQ(DisabledReason::NONE, service()->GetDisabledReason()); | |
| 881 | |
| 882 // History sync disabled. | |
| 883 ON_CALL(*mock_sync_service(), GetActiveDataTypes()) | |
| 884 .WillByDefault(Return(syncer::ModelTypeSet())); | |
| 885 EXPECT_EQ(DisabledReason::HISTORY_SYNC_DISABLED, | |
| 886 service()->GetDisabledReason()); | |
| 887 ResetSyncServiceMock(); | |
| 888 | |
| 889 // Not done loading. | |
| 890 ON_CALL(*mock_sync_service(), ConfigurationDone()) | |
| 891 .WillByDefault(Return(false)); | |
| 892 ON_CALL(*mock_sync_service(), GetActiveDataTypes()) | |
| 893 .WillByDefault(Return(syncer::ModelTypeSet())); | |
| 894 EXPECT_EQ(DisabledReason::HISTORY_SYNC_STATE_UNKNOWN, | |
| 895 service()->GetDisabledReason()); | |
| 896 ResetSyncServiceMock(); | |
| 897 | |
| 898 // Sync disabled. | |
| 899 ON_CALL(*mock_sync_service(), CanSyncStart()).WillByDefault(Return(false)); | |
| 900 EXPECT_EQ(DisabledReason::HISTORY_SYNC_DISABLED, | |
| 901 service()->GetDisabledReason()); | |
| 902 ResetSyncServiceMock(); | |
| 903 | |
| 904 // No service. | |
| 905 service()->sync_service_ = nullptr; | |
| 906 EXPECT_EQ(DisabledReason::HISTORY_SYNC_DISABLED, | |
| 907 service()->GetDisabledReason()); | |
| 908 } | |
| 909 | |
| 910 TEST_F(NTPSnippetsServiceTest, HistorySyncStateChanges) { | 850 TEST_F(NTPSnippetsServiceTest, HistorySyncStateChanges) { |
| 911 MockServiceObserver mock_observer; | 851 MockServiceObserver mock_observer; |
| 912 service()->AddObserver(&mock_observer); | 852 service()->AddObserver(&mock_observer); |
| 913 | 853 |
| 914 // Simulate user disabled sync. | 854 // Simulate user signed out |
| 915 ON_CALL(*mock_sync_service(), CanSyncStart()).WillByDefault(Return(false)); | |
| 916 // The service should notify observers it's been disabled and clear the | |
| 917 // snippets instead of pulling new ones. | |
| 918 EXPECT_CALL(mock_observer, NTPSnippetsServiceDisabled()); | |
| 919 SetUpFetchResponse(GetTestJson({GetSnippet()})); | 855 SetUpFetchResponse(GetTestJson({GetSnippet()})); |
| 920 service()->OnStateChanged(); | 856 EXPECT_CALL(mock_observer, NTPSnippetsServiceDisabledReasonChanged( |
| 857 DisabledReason::SIGNED_OUT)); |
| 858 service()->UpdateStateForStatus(DisabledReason::SIGNED_OUT); |
| 921 base::RunLoop().RunUntilIdle(); | 859 base::RunLoop().RunUntilIdle(); |
| 922 EXPECT_EQ(NTPSnippetsService::State::DISABLED, service()->state_); | 860 EXPECT_EQ(NTPSnippetsService::State::DISABLED, service()->state_); |
| 923 EXPECT_THAT(service()->snippets(), IsEmpty()); // No fetch should be made. | 861 EXPECT_THAT(service()->snippets(), IsEmpty()); // No fetch should be made. |
| 924 | 862 |
| 925 // Simulate user sign in. | 863 // Simulate user sign in. The service should be ready again and load snippets. |
| 926 ResetSyncServiceMock(); | 864 SetUpFetchResponse(GetTestJson({GetSnippet()})); |
| 927 // The service should be ready again and load snippets. | 865 EXPECT_CALL(mock_observer, |
| 866 NTPSnippetsServiceDisabledReasonChanged(DisabledReason::NONE)); |
| 928 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); | 867 EXPECT_CALL(mock_scheduler(), Schedule(_, _, _, _)).Times(1); |
| 929 SetUpFetchResponse(GetTestJson({GetSnippet()})); | 868 service()->UpdateStateForStatus(DisabledReason::NONE); |
| 930 service()->OnStateChanged(); | |
| 931 base::RunLoop().RunUntilIdle(); | 869 base::RunLoop().RunUntilIdle(); |
| 932 EXPECT_EQ(NTPSnippetsService::State::READY, service()->state_); | 870 EXPECT_EQ(NTPSnippetsService::State::READY, service()->state_); |
| 933 EXPECT_FALSE(service()->snippets().empty()); | 871 EXPECT_FALSE(service()->snippets().empty()); |
| 934 | 872 |
| 935 service()->RemoveObserver(&mock_observer); | 873 service()->RemoveObserver(&mock_observer); |
| 936 } | 874 } |
| 937 | 875 |
| 938 } // namespace ntp_snippets | 876 } // namespace ntp_snippets |
| OLD | NEW |