| // Copyright (c) 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/signin/core/browser/oauth2_token_service_delegate_android.h" |
| |
| #include "components/sync_preferences/testing_pref_service_syncable.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using ::testing::_; |
| using ::testing::InSequence; |
| using ::testing::Return; |
| using ::testing::Sequence; |
| using ::testing::StrictMock; |
| |
| namespace signin { |
| |
| namespace { |
| const std::vector<CoreAccountId> kEmptyVector; |
| class OAuth2TokenServiceDelegateAndroidForTest |
| : public OAuth2TokenServiceDelegateAndroid { |
| public: |
| OAuth2TokenServiceDelegateAndroidForTest( |
| AccountTrackerService* account_tracker_service) |
| : OAuth2TokenServiceDelegateAndroid(account_tracker_service) {} |
| MOCK_METHOD1(SetAccounts, void(const std::vector<CoreAccountId>&)); |
| }; |
| |
| class TestObserver : public OAuth2TokenServiceObserver { |
| public: |
| MOCK_METHOD1(OnRefreshTokenAvailable, void(const CoreAccountId&)); |
| MOCK_METHOD1(OnRefreshTokenRevoked, void(const CoreAccountId&)); |
| MOCK_METHOD0(OnRefreshTokensLoaded, void()); |
| }; |
| } // namespace |
| |
| class OAuth2TokenServiceDelegateAndroidTest : public testing::Test { |
| public: |
| OAuth2TokenServiceDelegateAndroidTest() {} |
| ~OAuth2TokenServiceDelegateAndroidTest() override = default; |
| |
| protected: |
| void SetUp() override { |
| testing::Test::SetUp(); |
| AccountTrackerService::RegisterPrefs(pref_service_.registry()); |
| account_tracker_service_.Initialize(&pref_service_, base::FilePath()); |
| OAuth2TokenServiceDelegateAndroid:: |
| set_disable_interaction_with_system_accounts(); |
| delegate_ = std::make_unique<OAuth2TokenServiceDelegateAndroidForTest>( |
| &account_tracker_service_); |
| delegate_->AddObserver(&observer_); |
| CreateAndSeedAccounts(); |
| } |
| |
| void TearDown() override { |
| delegate_->RemoveObserver(&observer_); |
| testing::Test::TearDown(); |
| } |
| |
| AccountInfo CreateAccountInfo(const std::string& gaia_id, |
| const std::string& email) { |
| AccountInfo account_info; |
| |
| account_info.gaia = gaia_id; |
| account_info.email = email; |
| account_info.full_name = "fullname"; |
| account_info.given_name = "givenname"; |
| account_info.hosted_domain = "example.com"; |
| account_info.locale = "en"; |
| account_info.picture_url = "https://example.com"; |
| account_info.is_child_account = false; |
| account_info.account_id = account_tracker_service_.PickAccountIdForAccount( |
| account_info.gaia, account_info.email); |
| |
| DCHECK(account_info.IsValid()); |
| |
| return account_info; |
| } |
| |
| void CreateAndSeedAccounts() { |
| account1_ = CreateAccountInfo("gaia-id-user-1", "user-1@example.com"); |
| account2_ = CreateAccountInfo("gaia-id-user-2", "user-2@example.com"); |
| // SeedAccountInfo is required for |
| // OAuth2TokenServiceDelegateAndrod::MapAccountNameToAccountId |
| account_tracker_service_.SeedAccountInfo(account1_); |
| account_tracker_service_.SeedAccountInfo(account2_); |
| } |
| |
| AccountTrackerService account_tracker_service_; |
| sync_preferences::TestingPrefServiceSyncable pref_service_; |
| std::unique_ptr<OAuth2TokenServiceDelegateAndroidForTest> delegate_; |
| StrictMock<TestObserver> observer_; |
| |
| AccountInfo account1_; |
| AccountInfo account2_; |
| }; |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith0SystemAccount0AccountAndNotSignedIn) { |
| EXPECT_CALL(*delegate_, SetAccounts(kEmptyVector)).WillOnce(Return()); |
| // No observer call expected |
| delegate_->UpdateAccountList(std::string(), {}, {}); |
| EXPECT_TRUE(account_tracker_service_.GetAccounts().empty()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount0AccountAndNotSignedIn) { |
| EXPECT_CALL(*delegate_, SetAccounts(kEmptyVector)).WillOnce(Return()); |
| // No observer call expected |
| delegate_->UpdateAccountList(std::string(), {}, {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount1AccountAndNotSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, SetAccounts(kEmptyVector)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| // Stored account from |GetAccounts| must fire a revoked event |
| EXPECT_CALL(observer_, OnRefreshTokenRevoked(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(std::string(), {account1_.account_id}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount0AccountAndSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, |
| SetAccounts(std::vector<CoreAccountId>({account1_.account_id}))) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account1_.account_id, {}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount1AccountAndSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, |
| SetAccounts(std::vector<CoreAccountId>({account1_.account_id}))) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account1_.account_id, {account1_.account_id}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount1AccountDifferentAndSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, |
| SetAccounts(std::vector<CoreAccountId>({account1_.account_id}))) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| // Previously stored account is removed, new account is available |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenRevoked(account2_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account1_.account_id, {account2_.account_id}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith0SystemAccount1AccountSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, SetAccounts(kEmptyVector)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenRevoked(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account1_.account_id, {account1_.account_id}, |
| {}); |
| EXPECT_TRUE(account_tracker_service_.GetAccounts().empty()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount0AccountAndSignedInDifferent) { |
| EXPECT_CALL(*delegate_, SetAccounts(kEmptyVector)).WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account2_.account_id, {}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| // Test Getsysaccounts return a user != from signed user while GetAccounts not |
| // empty |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount1AccountAndSignedInDifferent) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, SetAccounts(kEmptyVector)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenRevoked(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account2_.account_id, {account1_.account_id}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>{account1_}, |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith2SystemAccount0AccountAndSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, SetAccounts(std::vector<CoreAccountId>( |
| {account1_.account_id, account2_.account_id}))) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| // OnRefreshTokenAvailable fired, signed in account should go first. |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account2_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account2_.account_id, {}, |
| {account1_.account_id, account2_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>({account1_, account2_}), |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith2SystemAccount1AccountAndSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, SetAccounts(std::vector<CoreAccountId>( |
| {account1_.account_id, account2_.account_id}))) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| // OnRefreshTokenAvailable fired, signed in account should go first. |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account2_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| delegate_->UpdateAccountList(account1_.account_id, {account2_.account_id}, |
| {account1_.account_id, account2_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>({account1_, account2_}), |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| TEST_F(OAuth2TokenServiceDelegateAndroidTest, |
| UpdateAccountListWith1SystemAccount2AccountAndSignedIn) { |
| Sequence seq; |
| EXPECT_CALL(*delegate_, |
| SetAccounts(std::vector<CoreAccountId>({account1_.account_id}))) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| // OnRefreshTokenAvailable fired, signed in account should go first. |
| EXPECT_CALL(observer_, OnRefreshTokenAvailable(account1_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| EXPECT_CALL(observer_, OnRefreshTokenRevoked(account2_.account_id)) |
| .InSequence(seq) |
| .WillOnce(Return()); |
| |
| delegate_->UpdateAccountList(account1_.account_id, |
| {account1_.account_id, account2_.account_id}, |
| {account1_.account_id}); |
| EXPECT_EQ(std::vector<AccountInfo>({account1_}), |
| account_tracker_service_.GetAccounts()); |
| } |
| |
| } // namespace signin |