Commit 9dc792ae authored by chcunningham's avatar chcunningham Committed by Commit Bot

Implement IdentityManager::ClearPrimaryAccount(...)

Another step on the path to deprecating SigninManager. This method
replaces SigninManager::SignOut*(). See design discussion here:
https://groups.google.com/a/chromium.org/d/msg/identity-service-dev/hNrtJ_nIXJ4/6nMXfIcVBwAJ

Bug: 806781
Test: New unit tests

Change-Id: I39fe49925c980362b0cdf58db2ce961e107241b6
Reviewed-on: https://chromium-review.googlesource.com/1154985
Commit-Queue: Chrome Cunningham (In Paris) <chcunningham@chromium.org>
Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Reviewed-by: default avatarColin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580519}
parent 97436f6a
......@@ -4,6 +4,8 @@ include_rules = [
"+components/signin/core/browser/fake_gaia_cookie_manager_service.h",
"+components/signin/core/browser/gaia_cookie_manager_service.h",
"+components/signin/core/browser/profile_management_switches.h",
"+components/signin/core/browser/signin_metrics.h",
"+components/signin/core/browser/signin_switches.h",
"+google_apis/gaia/gaia_auth_util.h",
"+google_apis/gaia/google_service_auth_error.h",
"+google_apis/gaia/oauth2_token_service.h",
......
......@@ -154,6 +154,33 @@ bool IdentityManager::HasPrimaryAccount() const {
return !primary_account_info_.account_id.empty();
}
#if !defined(OS_CHROMEOS)
void IdentityManager::ClearPrimaryAccount(
ClearAccountTokensAction token_action,
signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric) {
SigninManager* signin_manager =
SigninManager::FromSigninManagerBase(signin_manager_);
switch (token_action) {
case IdentityManager::ClearAccountTokensAction::kDefault:
signin_manager->SignOut(signout_source_metric, signout_delete_metric);
break;
case IdentityManager::ClearAccountTokensAction::kKeepAll:
signin_manager->SignOutAndKeepAllAccounts(signout_source_metric,
signout_delete_metric);
break;
case IdentityManager::ClearAccountTokensAction::kRemoveAll:
signin_manager->SignOutAndRemoveAllAccounts(signout_source_metric,
signout_delete_metric);
break;
}
// NOTE: |primary_account_| member is cleared in WillFireGoogleSignedOut()
// and IdentityManager::Observers are notified in GoogleSignedOut();
}
#endif // defined(OS_CHROMEOS)
std::vector<AccountInfo> IdentityManager::GetAccountsWithRefreshTokens() const {
// TODO(blundell): It seems wasteful to construct this vector every time this
// method is called, but it also seems bad to maintain the vector as an ivar
......@@ -289,7 +316,6 @@ void IdentityManager::WillFireOnRefreshTokenAvailable(
const std::string& account_id,
bool is_valid) {
DCHECK(!pending_token_available_state_);
AccountInfo account_info =
account_tracker_service_->GetAccountInfo(account_id);
......
......@@ -11,6 +11,7 @@
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "services/identity/public/cpp/access_token_fetcher.h"
#if !defined(OS_CHROMEOS)
......@@ -68,8 +69,8 @@ class IdentityManager : public SigninManagerBase::Observer,
virtual void OnPrimaryAccountCleared(
const AccountInfo& previous_primary_account_info) {}
// TODO(blundell): Eventually we might need a callback for failure to log in
// to the primary account.
// TODO(https://crbug/869418): Eventually we might need a callback for
// failure to log in to the primary account.
// Called when a new refresh token is associated with |account_info|.
// |is_valid| indicates whether the new refresh token is valid.
......@@ -128,6 +129,29 @@ class IdentityManager : public SigninManagerBase::Observer,
// primary account info has a valid account ID.
bool HasPrimaryAccount() const;
// For ChromeOS, mutation of primary account state is not managed externally.
#if !defined(OS_CHROMEOS)
// Describes options for handling of tokens upon calling
// ClearPrimaryAccount().
enum class ClearAccountTokensAction{
// Default action (keep or remove tokens) based on internal policy.
kDefault,
// Keeps all account tokens for all accounts.
kKeepAll,
// Removes all accounts tokens for all accounts.
kRemoveAll,
};
// Clears the primary account, removing the preferences, and canceling all
// auth in progress. May optionally remove account tokens - see
// ClearAccountTokensAction. See definitions of signin_metrics::ProfileSignout
// and signin_metrics::SignoutDelete for usage. Observers will be notified via
// OnPrimaryAccountCleared() when complete.
void ClearPrimaryAccount(ClearAccountTokensAction token_action,
signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric);
#endif // defined(OS_CHROMEOS)
// Provides access to the latest cached information of all accounts that have
// refresh tokens.
// NOTE: The accounts should not be assumed to be in any particular order; in
......
......@@ -3,16 +3,21 @@
// found in the LICENSE file.
#include "services/identity/public/cpp/identity_manager.h"
#include "base/command_line.h"
#include "base/containers/flat_set.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h"
#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/signin/core/browser/profile_management_switches.h"
#include "components/signin/core/browser/signin_switches.h"
#include "components/signin/core/browser/test_signin_client.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -96,14 +101,20 @@ class TestSigninManagerObserver : public SigninManagerBase::Observer {
void set_on_google_signin_succeeded_callback(base::OnceClosure callback) {
on_google_signin_succeeded_callback_ = std::move(callback);
}
void set_on_google_signin_failed_callback(base::OnceClosure callback) {
on_google_signin_failed_callback_ = std::move(callback);
}
void set_on_google_signed_out_callback(base::OnceClosure callback) {
on_google_signed_out_callback_ = std::move(callback);
}
const AccountInfo& primary_account_from_signin_callback() {
const AccountInfo& primary_account_from_signin_callback() const {
return primary_account_from_signin_callback_;
}
const AccountInfo& primary_account_from_signout_callback() {
const GoogleServiceAuthError& error_from_signin_failed_callback() const {
return google_signin_failed_error_;
}
const AccountInfo& primary_account_from_signout_callback() const {
return primary_account_from_signout_callback_;
}
......@@ -116,6 +127,11 @@ class TestSigninManagerObserver : public SigninManagerBase::Observer {
if (on_google_signin_succeeded_callback_)
std::move(on_google_signin_succeeded_callback_).Run();
}
void GoogleSigninFailed(const GoogleServiceAuthError& error) override {
google_signin_failed_error_ = error;
if (on_google_signin_failed_callback_)
std::move(on_google_signin_failed_callback_).Run();
}
void GoogleSignedOut(const AccountInfo& account_info) override {
ASSERT_TRUE(identity_manager_);
primary_account_from_signout_callback_ =
......@@ -127,9 +143,11 @@ class TestSigninManagerObserver : public SigninManagerBase::Observer {
SigninManagerBase* signin_manager_;
IdentityManager* identity_manager_;
base::OnceClosure on_google_signin_succeeded_callback_;
base::OnceClosure on_google_signin_failed_callback_;
base::OnceClosure on_google_signed_out_callback_;
AccountInfo primary_account_from_signin_callback_;
AccountInfo primary_account_from_signout_callback_;
GoogleServiceAuthError google_signin_failed_error_;
};
// Class that observes updates from ProfileOAuth2TokenService and and verifies
......@@ -205,7 +223,10 @@ class TestIdentityManagerObserver : IdentityManager::Observer {
void set_on_refresh_token_updated_callback(base::OnceClosure callback) {
on_refresh_token_updated_callback_ = std::move(callback);
}
void set_on_refresh_token_removed_callback(base::OnceClosure callback) {
// This method uses a RepeatingCallback to simplify verification of multiple
// removed tokens.
void set_on_refresh_token_removed_callback(
base::RepeatingCallback<void(const AccountInfo&)> callback) {
on_refresh_token_removed_callback_ = std::move(callback);
}
......@@ -251,7 +272,7 @@ class TestIdentityManagerObserver : IdentityManager::Observer {
const AccountInfo& account_info) override {
account_from_refresh_token_removed_callback_ = account_info;
if (on_refresh_token_removed_callback_)
std::move(on_refresh_token_removed_callback_).Run();
on_refresh_token_removed_callback_.Run(account_info);
}
void OnAccountsInCookieUpdated(
const std::vector<AccountInfo>& accounts) override {
......@@ -264,7 +285,8 @@ class TestIdentityManagerObserver : IdentityManager::Observer {
base::OnceClosure on_primary_account_set_callback_;
base::OnceClosure on_primary_account_cleared_callback_;
base::OnceClosure on_refresh_token_updated_callback_;
base::OnceClosure on_refresh_token_removed_callback_;
base::RepeatingCallback<void(const AccountInfo&)>
on_refresh_token_removed_callback_;
base::OnceClosure on_accounts_in_cookie_updated_callback_;
AccountInfo primary_account_from_set_callback_;
AccountInfo primary_account_from_cleared_callback_;
......@@ -327,14 +349,6 @@ class IdentityManagerTest : public testing::Test {
public:
IdentityManagerTest()
: signin_client_(&pref_service_),
#if defined(OS_CHROMEOS)
signin_manager_(&signin_client_, &account_tracker_),
#else
signin_manager_(&signin_client_,
&token_service_,
&account_tracker_,
nullptr),
#endif
gaia_cookie_manager_service_(&token_service_,
"identity_manager_unittest",
&signin_client_) {
......@@ -344,9 +358,9 @@ class IdentityManagerTest : public testing::Test {
account_tracker_.Initialize(&signin_client_);
signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
RecreateIdentityManager();
RecreateSigninAndIdentityManager(
signin::AccountConsistencyMethod::kDisabled,
SigninManagerSetup::kWithAuthenticatedAccout);
}
IdentityManager* identity_manager() { return identity_manager_.get(); }
......@@ -358,7 +372,7 @@ class IdentityManagerTest : public testing::Test {
return identity_manager_diagnostics_observer_.get();
}
AccountTrackerServiceForTest* account_tracker() { return &account_tracker_; }
SigninManagerForTest* signin_manager() { return &signin_manager_; }
SigninManagerForTest* signin_manager() { return signin_manager_.get(); }
CustomFakeProfileOAuth2TokenService* token_service() {
return &token_service_;
}
......@@ -366,9 +380,58 @@ class IdentityManagerTest : public testing::Test {
return &gaia_cookie_manager_service_;
}
// See RecreateSigninAndIdentityManager.
enum class SigninManagerSetup {
kWithAuthenticatedAccout,
kNoAuthenticatedAccount
};
// Recreates SigninManager and IdentityManager with given
// |account_consistency| and optionally seeds with an authenticated account
// depending on |singin_manager_setup|. This process destroys any existing
// IdentityManager and its dependencies, then remakes them. Dependencies that
// outlive SigninManager (e.g. SigninClient) will be reused.
void RecreateSigninAndIdentityManager(
signin::AccountConsistencyMethod account_consistency,
SigninManagerSetup signin_manager_setup) {
// Reset dependents to null first to ensure that they're destroyed, as
// otherwise destructors of SigninManager and dependents will DCHECK because
// they still having living observers.
identity_manager_observer_.reset();
identity_manager_diagnostics_observer_.reset();
identity_manager_.reset();
#if defined(OS_CHROMEOS)
DCHECK_EQ(account_consistency, signin::AccountConsistencyMethod::kDisabled)
<< "AccountConsistency is not used by SigninManagerBase";
signin_manager_ = std::make_unique<FakeSigninManagerBase>(
&signin_client_, &account_tracker_);
#else
signin_manager_ = std::make_unique<FakeSigninManager>(
&signin_client_, &token_service_, &account_tracker_,
&gaia_cookie_manager_service_, nullptr, account_consistency);
#endif
// Passing this switch ensures that the new SigninManager starts with a
// clean slate. Otherwise SigninManagerBase::Initialize will use the account
// id stored in prefs::kGoogleServicesAccountId.
base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
cmd_line->AppendSwitch(switches::kClearTokenService);
signin_manager_->Initialize(&pref_service_);
if (signin_manager_setup == SigninManagerSetup::kWithAuthenticatedAccout) {
signin_manager()->SetAuthenticatedAccountInfo(kTestGaiaId, kTestEmail);
}
RecreateIdentityManager();
}
// Used by some tests that need to re-instantiate IdentityManager after
// performing some other setup.
void RecreateIdentityManager() {
DCHECK(signin_manager_) << "Create signin_manager_ first";
// Reset them all to null first to ensure that they're destroyed, as
// otherwise SigninManager ends up getting a new DiagnosticsObserver added
// before the old one is removed.
......@@ -377,7 +440,7 @@ class IdentityManagerTest : public testing::Test {
identity_manager_.reset();
identity_manager_.reset(
new IdentityManager(&signin_manager_, &token_service_,
new IdentityManager(signin_manager_.get(), &token_service_,
&account_tracker_, &gaia_cookie_manager_service_));
identity_manager_observer_.reset(
new TestIdentityManagerObserver(identity_manager_.get()));
......@@ -385,14 +448,94 @@ class IdentityManagerTest : public testing::Test {
new TestIdentityManagerDiagnosticsObserver(identity_manager_.get()));
}
#if !defined(OS_CHROMEOS)
enum class RemoveTokenExpectation{kKeepAll, kRemovePrimary, kRemoveAll};
// Helper for testing of ClearPrimaryAccount(). This method requires lots
// of tests due to having different behaviors based on its arguments. But the
// setup and execution of these test is all the boiler plate you see here:
// 1) Ensure you have 2 accounts, both with refresh tokens
// 2) Clear the primary account
// 3) Assert clearing succeeds and refresh tokens are optionally removed based
// on arguments.
void RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction token_action,
RemoveTokenExpectation token_expectation) {
EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
EXPECT_EQ(identity_manager()->GetPrimaryAccountInfo().email, kTestEmail);
// Ensure primary and secondary emails are set up with refresh tokens. Some
// tests may do this externally for the primary account.
if (!identity_manager()->HasPrimaryAccountWithRefreshToken())
SetRefreshTokenForPrimaryAccount(token_service(), identity_manager());
EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());
AccountInfo secondary_account_info = MakeAccountAvailable(
account_tracker(), token_service(), identity_manager(), kTestEmail2);
EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
secondary_account_info.account_id));
// Track Observer token removal notifications.
base::flat_set<std::string> observed_removals;
identity_manager_observer()->set_on_refresh_token_removed_callback(
base::BindRepeating(
[](base::flat_set<std::string>* observed_removals,
const AccountInfo& removed_account) {
observed_removals->insert(removed_account.email);
},
&observed_removals));
// Grab this before clearing for token checks below.
auto former_primary_account = identity_manager()->GetPrimaryAccountInfo();
base::RunLoop run_loop;
identity_manager_observer()->set_on_primary_account_cleared_callback(
run_loop.QuitClosure());
identity_manager()->ClearPrimaryAccount(
token_action, signin_metrics::SIGNOUT_TEST,
signin_metrics::SignoutDelete::IGNORE_METRIC);
run_loop.Run();
EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
// NOTE: IdentityManager _may_ still possess this token (see switch below),
// but it is no longer considered part of the primary account.
EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
switch (token_expectation) {
case RemoveTokenExpectation::kKeepAll:
EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
former_primary_account.account_id));
EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
secondary_account_info.account_id));
EXPECT_TRUE(observed_removals.empty());
break;
case RemoveTokenExpectation::kRemovePrimary:
EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(
former_primary_account.account_id));
EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
secondary_account_info.account_id));
EXPECT_TRUE(base::ContainsKey(observed_removals, kTestEmail));
EXPECT_FALSE(base::ContainsKey(observed_removals, kTestEmail2));
break;
case RemoveTokenExpectation::kRemoveAll:
EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(
former_primary_account.account_id));
EXPECT_FALSE(identity_manager()->HasAccountWithRefreshToken(
secondary_account_info.account_id));
EXPECT_TRUE(base::ContainsKey(observed_removals, kTestEmail));
EXPECT_TRUE(base::ContainsKey(observed_removals, kTestEmail2));
break;
}
}
#endif // !defined(OS_CHROMEOS)
private:
base::MessageLoop message_loop_;
sync_preferences::TestingPrefServiceSyncable pref_service_;
AccountTrackerServiceForTest account_tracker_;
TestSigninClient signin_client_;
SigninManagerForTest signin_manager_;
CustomFakeProfileOAuth2TokenService token_service_;
FakeGaiaCookieManagerService gaia_cookie_manager_service_;
std::unique_ptr<SigninManagerForTest> signin_manager_;
std::unique_ptr<IdentityManager> identity_manager_;
std::unique_ptr<TestIdentityManagerObserver> identity_manager_observer_;
std::unique_ptr<TestIdentityManagerDiagnosticsObserver>
......@@ -433,6 +576,143 @@ TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSignin) {
EXPECT_EQ(kTestEmail, primary_account_info.email);
}
TEST_F(IdentityManagerTest, ClearPrimaryAccount_RemoveAll) {
RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction::kRemoveAll,
RemoveTokenExpectation::kRemoveAll);
}
TEST_F(IdentityManagerTest, ClearPrimaryAccount_KeepAll) {
RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction::kKeepAll,
RemoveTokenExpectation::kKeepAll);
}
// Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kDefault
// and AccountConsistencyMethod::kDisabled (notably != kDice) removes all
// tokens.
TEST_F(IdentityManagerTest, ClearPrimaryAccount_Default_DisabledConsistency) {
// Tests default to kDisabled, so this is just being explicit.
RecreateSigninAndIdentityManager(
signin::AccountConsistencyMethod::kDisabled,
SigninManagerSetup::kWithAuthenticatedAccout);
RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction::kDefault,
RemoveTokenExpectation::kRemoveAll);
}
// Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kDefault
// and AccountConsistencyMethod::kMirror (notably != kDice) removes all
// tokens.
TEST_F(IdentityManagerTest, ClearPrimaryAccount_Default_MirrorConsistency) {
RecreateSigninAndIdentityManager(
signin::AccountConsistencyMethod::kMirror,
SigninManagerSetup::kWithAuthenticatedAccout);
RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction::kDefault,
RemoveTokenExpectation::kRemoveAll);
}
// Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kDefault
// and AccountConsistencyMethod::kDice keeps all accounts when the the primary
// account does not have an authentication error (see *_AuthError test).
TEST_F(IdentityManagerTest, ClearPrimaryAccount_Default_DiceConsistency) {
RecreateSigninAndIdentityManager(
signin::AccountConsistencyMethod::kDice,
SigninManagerSetup::kWithAuthenticatedAccout);
RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction::kDefault,
RemoveTokenExpectation::kKeepAll);
}
// Test that ClearPrimaryAccount(...) with ClearAccountTokensAction::kDefault
// and AccountConsistencyMethod::kDice removes *only* the primary account
// due to it authentication error.
TEST_F(IdentityManagerTest,
ClearPrimaryAccount_Default_DiceConsistency_AuthError) {
RecreateSigninAndIdentityManager(
signin::AccountConsistencyMethod::kDice,
SigninManagerSetup::kWithAuthenticatedAccout);
// Set primary account to have authentication error.
SetRefreshTokenForPrimaryAccount(token_service(), identity_manager());
token_service()->UpdateAuthErrorForTesting(
identity_manager()->GetPrimaryAccountInfo().account_id,
GoogleServiceAuthError(
GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
RunClearPrimaryAccountTest(
IdentityManager::ClearAccountTokensAction::kDefault,
RemoveTokenExpectation::kRemovePrimary);
}
// Test that ClearPrimaryAccount(...) with authentication in progress notifies
// Observers that sign-in is canceled and does not remove any tokens.
TEST_F(IdentityManagerTest, ClearPrimaryAccount_AuthInProgress) {
// Recreate components without setting an authenticated (primary) account.
RecreateSigninAndIdentityManager(signin::AccountConsistencyMethod::kDisabled,
SigninManagerSetup::kNoAuthenticatedAccount);
EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
// Simulate authentication in progress (id value not important, treated as
// potentially invalid until authentication completes).
signin_manager()->set_auth_in_progress("bogus_id");
EXPECT_TRUE(signin_manager()->AuthInProgress());
// Add a secondary account to verify that its refresh token survives the
// call to ClearPrimaryAccount(...) below.
AccountInfo secondary_account_info = MakeAccountAvailable(
account_tracker(), token_service(), identity_manager(), kTestEmail2);
EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
secondary_account_info.account_id));
// Observe that in-progress authentication is *canceled* and quit the RunLoop.
// TODO(https://crbug/869418): Determine if signin failed notifications should
// be part of the IdentityManager::Observer interface.
base::RunLoop run_loop;
GoogleServiceAuthError::State observed_error =
GoogleServiceAuthError::State::NONE;
TestSigninManagerObserver signin_manager_observer(signin_manager());
signin_manager_observer.set_identity_manager(identity_manager());
signin_manager_observer.set_on_google_signin_failed_callback(base::BindOnce(
[](TestSigninManagerObserver* observer,
GoogleServiceAuthError::State* error, base::OnceClosure callback) {
*error = observer->error_from_signin_failed_callback().state();
std::move(callback).Run();
},
&signin_manager_observer, &observed_error, run_loop.QuitClosure()));
// Observer should not be notified of any token removals.
identity_manager_observer()->set_on_refresh_token_removed_callback(
base::BindRepeating([](const AccountInfo&) { EXPECT_TRUE(false); }));
// No primary account to "clear", so no callback.
identity_manager_observer()->set_on_primary_account_cleared_callback(
base::BindOnce([] { EXPECT_TRUE(false); }));
identity_manager()->ClearPrimaryAccount(
IdentityManager::ClearAccountTokensAction::kRemoveAll,
signin_metrics::SIGNOUT_TEST,
signin_metrics::SignoutDelete::IGNORE_METRIC);
run_loop.Run();
// Verify in-progress authentication was canceled.
EXPECT_EQ(observed_error, GoogleServiceAuthError::State::REQUEST_CANCELED);
EXPECT_FALSE(signin_manager()->AuthInProgress());
// We didn't have a primary account to start with, we shouldn't have one now
// either.
EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
// Secondary account token still exists.
EXPECT_TRUE(identity_manager()->HasAccountWithRefreshToken(
secondary_account_info.account_id));
}
// Test that the user signing out results in firing of the IdentityManager
// observer callback and the IdentityManager's state being updated.
TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSigninAndSignout) {
......@@ -1185,9 +1465,16 @@ TEST_F(IdentityManagerTest,
TEST_F(IdentityManagerTest,
CallbackNotSentOnRefreshTokenRemovalOfUnknownAccount) {
// RemoveCredentials expects (and DCHECKS) that either the caller passes a
// known account ID, or the account is unknown because the token service is
// still loading credentials. Our common test setup actually completes this
// loading, so use the *for_testing() method below to simulate the race
// condition.
token_service()->set_all_credentials_loaded_for_testing(false);
base::RunLoop run_loop;
identity_manager_observer()->set_on_refresh_token_removed_callback(
base::BindOnce([] { EXPECT_TRUE(false); }));
base::BindRepeating([](const AccountInfo&) { EXPECT_TRUE(false); }));
token_service()->RevokeCredentials("dummy_account");
run_loop.RunUntilIdle();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment