OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/command_line.h" | 5 #include "base/command_line.h" |
6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
7 #include "base/run_loop.h" | 7 #include "base/run_loop.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/test/histogram_tester.h" | 9 #include "base/test/histogram_tester.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 #include "components/signin/core/browser/account_reconcilor.h" | 26 #include "components/signin/core/browser/account_reconcilor.h" |
27 #include "components/signin/core/browser/account_tracker_service.h" | 27 #include "components/signin/core/browser/account_tracker_service.h" |
28 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" | 28 #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" |
29 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 29 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
30 #include "components/signin/core/browser/signin_manager.h" | 30 #include "components/signin/core/browser/signin_manager.h" |
31 #include "components/signin/core/browser/signin_metrics.h" | 31 #include "components/signin/core/browser/signin_metrics.h" |
32 #include "components/signin/core/browser/test_signin_client.h" | 32 #include "components/signin/core/browser/test_signin_client.h" |
33 #include "components/signin/core/common/profile_management_switches.h" | 33 #include "components/signin/core/common/profile_management_switches.h" |
34 #include "components/signin/core/common/signin_switches.h" | 34 #include "components/signin/core/common/signin_switches.h" |
35 #include "content/public/test/test_browser_thread_bundle.h" | 35 #include "content/public/test/test_browser_thread_bundle.h" |
| 36 #include "google_apis/gaia/fake_oauth2_token_service_delegate.h" |
36 #include "google_apis/gaia/gaia_constants.h" | 37 #include "google_apis/gaia/gaia_constants.h" |
37 #include "google_apis/gaia/gaia_urls.h" | 38 #include "google_apis/gaia/gaia_urls.h" |
38 #include "net/url_request/test_url_fetcher_factory.h" | 39 #include "net/url_request/test_url_fetcher_factory.h" |
39 #include "testing/gmock/include/gmock/gmock.h" | 40 #include "testing/gmock/include/gmock/gmock.h" |
40 #include "testing/gtest/include/gtest/gtest.h" | 41 #include "testing/gtest/include/gtest/gtest.h" |
41 | 42 |
42 namespace { | 43 namespace { |
43 | 44 |
44 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> { | 45 class MockAccountReconcilor : public testing::StrictMock<AccountReconcilor> { |
45 public: | 46 public: |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 } // namespace | 82 } // namespace |
82 | 83 |
83 class AccountReconcilorTest : public ::testing::TestWithParam<bool> { | 84 class AccountReconcilorTest : public ::testing::TestWithParam<bool> { |
84 public: | 85 public: |
85 AccountReconcilorTest(); | 86 AccountReconcilorTest(); |
86 void SetUp() override; | 87 void SetUp() override; |
87 | 88 |
88 TestingProfile* profile() { return profile_; } | 89 TestingProfile* profile() { return profile_; } |
89 FakeSigninManagerForTesting* signin_manager() { return signin_manager_; } | 90 FakeSigninManagerForTesting* signin_manager() { return signin_manager_; } |
90 FakeProfileOAuth2TokenService* token_service() { return token_service_; } | 91 FakeProfileOAuth2TokenService* token_service() { return token_service_; } |
| 92 FakeOAuth2TokenServiceDelegate* token_service_delegate() { |
| 93 return static_cast<FakeOAuth2TokenServiceDelegate*>( |
| 94 token_service_->GetDelegate()); |
| 95 } |
91 TestSigninClient* test_signin_client() { return test_signin_client_; } | 96 TestSigninClient* test_signin_client() { return test_signin_client_; } |
92 AccountTrackerService* account_tracker() { return account_tracker_; } | 97 AccountTrackerService* account_tracker() { return account_tracker_; } |
93 FakeGaiaCookieManagerService* cookie_manager_service() { | 98 FakeGaiaCookieManagerService* cookie_manager_service() { |
94 return cookie_manager_service_; | 99 return cookie_manager_service_; |
95 } | 100 } |
96 base::HistogramTester* histogram_tester() { return &histogram_tester_; } | 101 base::HistogramTester* histogram_tester() { return &histogram_tester_; } |
97 | 102 |
98 void SetFakeResponse(const std::string& url, | 103 void SetFakeResponse(const std::string& url, |
99 const std::string& data, | 104 const std::string& data, |
100 net::HttpStatusCode code, | 105 net::HttpStatusCode code, |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 // If an unknown account id is sent, it should not upset the state. | 760 // If an unknown account id is sent, it should not upset the state. |
756 SimulateAddAccountToCookieCompleted(reconcilor, "bogus_account_id", | 761 SimulateAddAccountToCookieCompleted(reconcilor, "bogus_account_id", |
757 GoogleServiceAuthError::AuthErrorNone()); | 762 GoogleServiceAuthError::AuthErrorNone()); |
758 ASSERT_TRUE(reconcilor->is_reconcile_started_); | 763 ASSERT_TRUE(reconcilor->is_reconcile_started_); |
759 | 764 |
760 SimulateAddAccountToCookieCompleted(reconcilor, account_id, | 765 SimulateAddAccountToCookieCompleted(reconcilor, account_id, |
761 GoogleServiceAuthError::AuthErrorNone()); | 766 GoogleServiceAuthError::AuthErrorNone()); |
762 ASSERT_FALSE(reconcilor->is_reconcile_started_); | 767 ASSERT_FALSE(reconcilor->is_reconcile_started_); |
763 } | 768 } |
764 | 769 |
| 770 #if !defined(OS_IOS) |
| 771 // These tests don't run on iOS because that platform uses a different |
| 772 // implementation of FakeOAuth2TokenServiceDelegate. However, iOS also removes |
| 773 // accounts when an auth error is detected, so the scenarios being tested here |
| 774 // do not apply. |
| 775 |
| 776 TEST_F(AccountReconcilorTest, NoLoopWithBadPrimary) { |
| 777 // Connect profile to a primary account and then add a secondary account. |
| 778 const std::string account_id1 = |
| 779 ConnectProfileToAccount("12345", "user@gmail.com"); |
| 780 const std::string account_id2 = |
| 781 PickAccountIdForAccount("67890", "other@gmail.com"); |
| 782 token_service()->UpdateCredentials(account_id2, "refresh_token"); |
| 783 |
| 784 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()); |
| 785 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id1)); |
| 786 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2)); |
| 787 |
| 788 // The primary account is in auth error, so it is not in the cookie. |
| 789 cookie_manager_service()->SetListAccountsResponseOneAccountWithExpiry( |
| 790 "other@gmail.com", "67890", true); |
| 791 |
| 792 AccountReconcilor* reconcilor = |
| 793 AccountReconcilorFactory::GetForProfile(profile()); |
| 794 ASSERT_TRUE(reconcilor); |
| 795 |
| 796 reconcilor->StartReconcile(); |
| 797 base::RunLoop().RunUntilIdle(); |
| 798 ASSERT_TRUE(reconcilor->is_reconcile_started_); |
| 799 |
| 800 GoogleServiceAuthError |
| 801 error(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| 802 |
| 803 // The primary cannot be added to cookie, so it fails. |
| 804 SimulateAddAccountToCookieCompleted( |
| 805 reconcilor, account_id1, error); |
| 806 SimulateAddAccountToCookieCompleted(reconcilor, account_id2, |
| 807 GoogleServiceAuthError::AuthErrorNone()); |
| 808 base::RunLoop().RunUntilIdle(); |
| 809 ASSERT_FALSE(reconcilor->is_reconcile_started_); |
| 810 ASSERT_TRUE(reconcilor->error_during_last_reconcile_); |
| 811 testing::Mock::VerifyAndClearExpectations(GetMockReconcilor()); |
| 812 |
| 813 // Now that we've tried once, the token service knows that the primary |
| 814 // account has an auth error. |
| 815 token_service_delegate()->SetLastErrorForAccount(account_id1, error); |
| 816 |
| 817 // A second attempt to reconcile should be a noop. |
| 818 reconcilor->StartReconcile(); |
| 819 base::RunLoop().RunUntilIdle(); |
| 820 ASSERT_FALSE(reconcilor->is_reconcile_started_); |
| 821 testing::Mock::VerifyAndClearExpectations(GetMockReconcilor()); |
| 822 } |
| 823 |
| 824 TEST_F(AccountReconcilorTest, WontMergeAccountsWithError) { |
| 825 // Connect profile to a primary account and then add a secondary account. |
| 826 const std::string account_id1 = |
| 827 ConnectProfileToAccount("12345", "user@gmail.com"); |
| 828 const std::string account_id2 = |
| 829 PickAccountIdForAccount("67890", "other@gmail.com"); |
| 830 token_service()->UpdateCredentials(account_id2, "refresh_token"); |
| 831 |
| 832 // Mark the secondary account in auth error state. |
| 833 token_service_delegate()->SetLastErrorForAccount( |
| 834 account_id2, |
| 835 GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); |
| 836 |
| 837 // The cookie starts empty. |
| 838 cookie_manager_service()->SetListAccountsResponseNoAccounts(); |
| 839 |
| 840 // Since the cookie jar starts empty, the reconcilor should attempt to merge |
| 841 // accounts into it. However, it should only try accounts not in auth |
| 842 // error state. |
| 843 EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()); |
| 844 EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id1)); |
| 845 |
| 846 AccountReconcilor* reconcilor = |
| 847 AccountReconcilorFactory::GetForProfile(profile()); |
| 848 ASSERT_TRUE(reconcilor); |
| 849 |
| 850 reconcilor->StartReconcile(); |
| 851 base::RunLoop().RunUntilIdle(); |
| 852 ASSERT_TRUE(reconcilor->is_reconcile_started_); |
| 853 |
| 854 SimulateAddAccountToCookieCompleted( |
| 855 reconcilor, account_id1, GoogleServiceAuthError::AuthErrorNone()); |
| 856 base::RunLoop().RunUntilIdle(); |
| 857 ASSERT_FALSE(reconcilor->is_reconcile_started_); |
| 858 ASSERT_FALSE(reconcilor->error_during_last_reconcile_); |
| 859 } |
| 860 |
| 861 #endif // OS_IOS |
| 862 |
765 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled, | 863 INSTANTIATE_TEST_CASE_P(AccountReconcilorMaybeEnabled, |
766 AccountReconcilorTest, | 864 AccountReconcilorTest, |
767 testing::Bool()); | 865 testing::Bool()); |
OLD | NEW |