Commit 4f493205 authored by David Roger's avatar David Roger Committed by Commit Bot

[Signin] Add unittest for AccountReconcilor revoking tokens

Bug: 767004
Change-Id: I23298bfcc294f2aeca35bba572246d0bdbf97b70
Reviewed-on: https://chromium-review.googlesource.com/684895Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Commit-Queue: David Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#505378}
parent db32bb00
...@@ -325,6 +325,7 @@ struct AccountReconcilorTestDiceParam { ...@@ -325,6 +325,7 @@ struct AccountReconcilorTestDiceParam {
const char* cookies; const char* cookies;
bool is_first_reconcile; bool is_first_reconcile;
const char* gaia_api_calls; const char* gaia_api_calls;
const char* tokens_after_reconcile;
const char* cookies_after_reconcile; const char* cookies_after_reconcile;
}; };
...@@ -348,123 +349,123 @@ const AccountReconcilorTestDiceParam kDiceParams[] = { ...@@ -348,123 +349,123 @@ const AccountReconcilorTestDiceParam kDiceParams[] = {
// - API calls: // - API calls:
// X: Logout all accounts. // X: Logout all accounts.
// A, B, C: Merge account. // A, B, C: Merge account.
// ------------------------------------------------------------------- // -------------------------------------------------------------------------
// Tokens | Cookies | First Run | Gaia calls | Cookies after reconcile // Tokens | Cookies | First Run | Gaia calls | Tokens after | Cookies after
// ------------------------------------------------------------------- // -------------------------------------------------------------------------
// First reconcile (Chrome restart): Rebuild the Gaia cookie to match the // First reconcile (Chrome restart): Rebuild the Gaia cookie to match the
// tokens. Make the Sync account the default account in the Gaia cookie. // tokens. Make the Sync account the default account in the Gaia cookie.
// Sync enabled. // Sync enabled.
{ "*AB", "AB", true, "", "AB"}, { "*AB", "AB", true, "", "*AB", "AB"},
{ "*AB", "BA", true, "XAB", "AB"}, { "*AB", "BA", true, "XAB", "*AB", "AB"},
{ "*AB", "A", true, "B", "AB"}, { "*AB", "A", true, "B", "*AB", "AB"},
{ "*AB", "B", true, "XAB", "AB"}, { "*AB", "B", true, "XAB", "*AB", "AB"},
{ "*AB", "", true, "AB", "AB"}, { "*AB", "", true, "AB", "*AB", "AB"},
// Sync enabled, token error on primary. // Sync enabled, token error on primary.
{ "*xAB", "AB", true, "X", ""}, { "*xAB", "AB", true, "X", "*xA", ""},
{ "*xAB", "BA", true, "XB", "B"}, { "*xAB", "BA", true, "XB", "*xAB", "B"},
{ "*xAB", "A", true, "X", ""}, { "*xAB", "A", true, "X", "*xA", ""},
{ "*xAB", "B", true, "", "B"}, { "*xAB", "B", true, "", "*xAB", "B"},
{ "*xAB", "", true, "B", "B"}, { "*xAB", "", true, "B", "*xAB", "B"},
// Sync enabled, token error on secondary. // Sync enabled, token error on secondary.
{ "*AxB", "AB", true, "XA", "A"}, { "*AxB", "AB", true, "XA", "*AxB", "A"},
{ "*AxB", "BA", true, "XA", "A"}, { "*AxB", "BA", true, "XA", "*AxB", "A"},
{ "*AxB", "A", true, "", "A"}, { "*AxB", "A", true, "", "*AxB", "A"},
{ "*AxB", "B", true, "XA", "A"}, { "*AxB", "B", true, "XA", "*AxB", "A"},
{ "*AxB", "", true, "A", "A"}, { "*AxB", "", true, "A", "*AxB", "A"},
// Sync enabled, token error on both accounts. // Sync enabled, token error on both accounts.
{ "*xAxB", "AB", true, "X", ""}, { "*xAxB", "AB", true, "X", "*xAxB", ""},
{ "*xAxB", "BA", true, "X", ""}, { "*xAxB", "BA", true, "X", "*xAxB", ""},
{ "*xAxB", "A", true, "X", ""}, { "*xAxB", "A", true, "X", "*xAxB", ""},
{ "*xAxB", "B", true, "X", ""}, { "*xAxB", "B", true, "X", "*xAxB", ""},
{ "*xAxB", "", true, "", ""}, { "*xAxB", "", true, "", "*xAxB", ""},
// Sync disabled. // Sync disabled.
{ "AB", "AB", true, "", "AB"}, { "AB", "AB", true, "", "AB", "AB"},
{ "AB", "BA", true, "", "BA"}, { "AB", "BA", true, "", "AB", "BA"},
{ "AB", "A", true, "B", "AB"}, { "AB", "A", true, "B", "AB", "AB"},
{ "AB", "B", true, "A", "BA"}, { "AB", "B", true, "A", "AB", "BA"},
{ "AB", "", true, "AB", "AB"}, { "AB", "", true, "AB", "AB", "AB"},
// Sync disabled, token error on first account. // Sync disabled, token error on first account.
{ "xAB", "AB", true, "XB", "B"}, { "xAB", "AB", true, "XB", "xAB", "B"},
{ "xAB", "BA", true, "XB", "B"}, { "xAB", "BA", true, "XB", "xAB", "B"},
{ "xAB", "A", true, "XB", "B"}, { "xAB", "A", true, "XB", "xAB", "B"},
{ "xAB", "B", true, "", "B"}, { "xAB", "B", true, "", "xAB", "B"},
{ "xAB", "", true, "B", "B"}, { "xAB", "", true, "B", "xAB", "B"},
// Sync disabled, token error on second account. // Sync disabled, token error on second account .
{ "AxB", "AB", true, "XA", "A"}, { "AxB", "AB", true, "XA", "AxB", "A"},
{ "AxB", "BA", true, "XA", "A"}, { "AxB", "BA", true, "XA", "AxB", "A"},
{ "AxB", "A", true, "", "A"}, { "AxB", "A", true, "", "AxB", "A"},
{ "AxB", "B", true, "XA", "A"}, { "AxB", "B", true, "XA", "AxB", "A"},
{ "AxB", "", true, "A", "A"}, { "AxB", "", true, "A", "AxB", "A"},
// Sync disabled, token error on both accounts. // Sync disabled, token error on both accounts.
{ "xAxB", "AB", true, "X", ""}, { "xAxB", "AB", true, "X", "xAxB", ""},
{ "xAxB", "BA", true, "X", ""}, { "xAxB", "BA", true, "X", "xAxB", ""},
{ "xAxB", "A", true, "X", ""}, { "xAxB", "A", true, "X", "xAxB", ""},
{ "xAxB", "B", true, "X", ""}, { "xAxB", "B", true, "X", "xAxB", ""},
{ "xAxB", "", true, "", ""}, { "xAxB", "", true, "", "xAxB", ""},
// Chrome is running: Do not change the order of accounts already present in // Chrome is running: Do not change the order of accounts already present in
// the Gaia cookies. // the Gaia cookies.
// Sync enabled. // Sync enabled.
{ "*AB", "AB", false, "", "AB"}, { "*AB", "AB", false, "", "*AB", "AB"},
{ "*AB", "BA", false, "", "BA"}, { "*AB", "BA", false, "", "*AB", "BA"},
{ "*AB", "A", false, "B", "AB"}, { "*AB", "A", false, "B", "*AB", "AB"},
{ "*AB", "B", false, "A", "BA"}, { "*AB", "B", false, "A", "*AB", "BA"},
{ "*AB", "", false, "AB", "AB"}, { "*AB", "", false, "AB", "*AB", "AB"},
// Sync enabled, token error on primary. // Sync enabled, token error on primary.
{ "*xAB", "AB", false, "X", ""}, { "*xAB", "AB", false, "X", "*xA", ""},
{ "*xAB", "BA", false, "XB", "B"}, { "*xAB", "BA", false, "XB", "*xAB", "B"},
{ "*xAB", "A", false, "X", ""}, { "*xAB", "A", false, "X", "*xA", ""},
{ "*xAB", "B", false, "", "B"}, { "*xAB", "B", false, "", "*xAB", "B"},
{ "*xAB", "", false, "B", "B"}, { "*xAB", "", false, "B", "*xAB", "B"},
// Sync enabled, token error on secondary. // Sync enabled, token error on secondary.
{ "*AxB", "AB", false, "XA", "A"}, { "*AxB", "AB", false, "XA", "*AxB", "A"},
// TODO(droger): consider doing XA: // TODO(droger): consider doing XA:
{ "*AxB", "BA", false, "X", ""}, { "*AxB", "BA", false, "X", "*AxB", ""},
{ "*AxB", "A", false, "", "A"}, { "*AxB", "A", false, "", "*AxB", "A"},
// TODO(droger): consider doing XA: // TODO(droger): consider doing XA:
{ "*AxB", "B", false, "X", ""}, { "*AxB", "B", false, "X", "*AxB", ""},
{ "*AxB", "", false, "A", "A"}, { "*AxB", "", false, "A", "*AxB", "A"},
// Sync enabled, token error on both accounts. // Sync enabled, token error on both accounts.
{ "*xAxB", "AB", false, "X", ""}, { "*xAxB", "AB", false, "X", "*xAxB", ""},
{ "*xAxB", "BA", false, "X", ""}, { "*xAxB", "BA", false, "X", "*xAxB", ""},
{ "*xAxB", "A", false, "X", ""}, { "*xAxB", "A", false, "X", "*xAxB", ""},
{ "*xAxB", "B", false, "X", ""}, { "*xAxB", "B", false, "X", "*xAxB", ""},
{ "*xAxB", "", false, "", ""}, { "*xAxB", "", false, "", "*xAxB", ""},
// Sync disabled. // Sync disabled.
{ "AB", "AB", false, "", "AB"}, { "AB", "AB", false, "", "AB", "AB"},
{ "AB", "BA", false, "", "BA"}, { "AB", "BA", false, "", "AB", "BA"},
{ "AB", "A", false, "B", "AB"}, { "AB", "A", false, "B", "AB", "AB"},
{ "AB", "B", false, "A", "BA"}, { "AB", "B", false, "A", "AB", "BA"},
{ "AB", "", false, "AB", "AB"}, { "AB", "", false, "AB", "AB", "AB"},
// Sync disabled, token error on first account. // Sync disabled, token error on first account.
{ "xAB", "AB", false, "X", ""}, { "xAB", "AB", false, "X", "xA", ""},
{ "xAB", "BA", false, "XB", "B"}, { "xAB", "BA", false, "XB", "xAB", "B"},
{ "xAB", "A", false, "X", ""}, { "xAB", "A", false, "X", "xA", ""},
{ "xAB", "B", false, "", "B"}, { "xAB", "B", false, "", "xAB", "B"},
{ "xAB", "", false, "B", "B"}, { "xAB", "", false, "B", "xAB", "B"},
// Sync disabled, token error on second account. // Sync disabled, token error on second account.
{ "AxB", "AB", false, "XA", "A"}, { "AxB", "AB", false, "XA", "AxB", "A"},
{ "AxB", "BA", false, "X", ""}, { "AxB", "BA", false, "X", "xB", ""},
{ "AxB", "A", false, "", "A"}, { "AxB", "A", false, "", "AxB", "A"},
{ "AxB", "B", false, "X", ""}, { "AxB", "B", false, "X", "xB", ""},
{ "AxB", "", false, "A", "A"}, { "AxB", "", false, "A", "AxB", "A"},
// Sync disabled, token error on both accounts. // Sync disabled, token error on both accounts.
{ "xAxB", "AB", false, "X", ""}, { "xAxB", "AB", false, "X", "xAxB", ""},
{ "xAxB", "BA", false, "X", ""}, { "xAxB", "BA", false, "X", "xAxB", ""},
{ "xAxB", "A", false, "X", ""}, { "xAxB", "A", false, "X", "xAxB", ""},
{ "xAxB", "B", false, "X", ""}, { "xAxB", "B", false, "X", "xAxB", ""},
{ "xAxB", "", false, "", ""}, { "xAxB", "", false, "", "xAxB", ""},
// Miscellaneous cases. // Miscellaneous cases.
// Check that unknown Gaia accounts are signed out. // Check that unknown Gaia accounts are signed out.
{ "", "A", true, "X", ""}, { "", "A", true, "X", "", ""},
{ "", "A", false, "X", ""}, { "", "A", false, "X", "", ""},
{ "*A", "AB", true, "XA", "A"}, { "*A", "AB", true, "XA", "*A", "A"},
{ "*A", "AB", false, "XA", "A"}, { "*A", "AB", false, "XA", "*A", "A"},
// Check that Gaia default account is kept in first position. // Check that Gaia default account is kept in first position.
{ "AB", "BC", true, "XBA", "BA"}, { "AB", "BC", true, "XBA", "AB", "BA"},
{ "AB", "BC", false, "XBA", "BA"}, { "AB", "BC", false, "XBA", "AB", "BA"},
}; };
// clang-format on // clang-format on
...@@ -478,12 +479,63 @@ class AccountReconcilorTestDice ...@@ -478,12 +479,63 @@ class AccountReconcilorTestDice
std::string gaia_id; std::string gaia_id;
}; };
struct Token {
std::string gaia_id;
std::string email;
bool is_authenticated;
bool has_error;
};
AccountReconcilorTestDice() { AccountReconcilorTestDice() {
accounts_['A'] = {"a@gmail.com", "A"}; accounts_['A'] = {"a@gmail.com", "A"};
accounts_['B'] = {"b@gmail.com", "B"}; accounts_['B'] = {"b@gmail.com", "B"};
accounts_['C'] = {"c@gmail.com", "C"}; accounts_['C'] = {"c@gmail.com", "C"};
} }
// Build Tokens from string.
std::vector<Token> ParseTokenString(const char* token_string) {
std::vector<Token> parsed_tokens;
bool is_authenticated = false;
bool has_error = false;
for (int i = 0; token_string[i] != '\0'; ++i) {
char token_code = token_string[i];
if (token_code == '*') {
is_authenticated = true;
continue;
}
if (token_code == 'x') {
has_error = true;
continue;
}
parsed_tokens.push_back({accounts_[token_code].gaia_id,
accounts_[token_code].email, is_authenticated,
has_error});
is_authenticated = false;
has_error = false;
}
return parsed_tokens;
}
// Checks that the tokens in the TokenService match the tokens.
void VerifyCurrentTokens(const std::vector<Token>& tokens) {
EXPECT_EQ(token_service()->GetAccounts().size(), tokens.size());
bool authenticated_account_found = false;
for (const Token& token : tokens) {
std::string account_id =
PickAccountIdForAccount(token.gaia_id, token.email);
EXPECT_TRUE(token_service()->RefreshTokenIsAvailable(account_id));
EXPECT_EQ(
token.has_error,
token_service()->GetDelegate()->RefreshTokenHasError(account_id));
if (token.is_authenticated) {
EXPECT_EQ(account_id, signin_manager()->GetAuthenticatedAccountId());
authenticated_account_found = true;
}
}
if (!authenticated_account_found)
EXPECT_EQ("", signin_manager()->GetAuthenticatedAccountId());
}
std::map<char, Account> accounts_; std::map<char, Account> accounts_;
}; };
...@@ -493,35 +545,22 @@ TEST_P(AccountReconcilorTestDice, TableRowTest) { ...@@ -493,35 +545,22 @@ TEST_P(AccountReconcilorTestDice, TableRowTest) {
signin::ScopedAccountConsistencyDice scoped_dice; signin::ScopedAccountConsistencyDice scoped_dice;
// Setup tokens. // Setup tokens.
bool signin = false; std::vector<Token> tokens_before_reconcile =
bool token_error = false; ParseTokenString(GetParam().tokens);
for (int i = 0; GetParam().tokens[i] != '\0'; ++i) { for (const Token& token : tokens_before_reconcile) {
char token_code = GetParam().tokens[i]; std::string account_id =
if (token_code == '*') { PickAccountIdForAccount(token.gaia_id, token.email);
signin = true; if (token.is_authenticated)
continue; ConnectProfileToAccount(token.gaia_id, token.email);
} else
if (token_code == 'x') {
token_error = true;
continue;
}
std::string account_id = PickAccountIdForAccount(
accounts_[token_code].gaia_id, accounts_[token_code].email);
if (signin) {
ConnectProfileToAccount(accounts_[token_code].gaia_id,
accounts_[token_code].email);
signin = false;
} else {
token_service()->UpdateCredentials(account_id, "refresh_token"); token_service()->UpdateCredentials(account_id, "refresh_token");
} if (token.has_error) {
if (token_error) {
token_service_delegate()->SetLastErrorForAccount( token_service_delegate()->SetLastErrorForAccount(
account_id, GoogleServiceAuthError( account_id, GoogleServiceAuthError(
GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)); GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
token_error = false;
} }
} }
VerifyCurrentTokens(tokens_before_reconcile);
// Setup cookies. // Setup cookies.
std::string cookies(GetParam().cookies); std::string cookies(GetParam().cookies);
...@@ -583,6 +622,7 @@ TEST_P(AccountReconcilorTestDice, TableRowTest) { ...@@ -583,6 +622,7 @@ TEST_P(AccountReconcilorTestDice, TableRowTest) {
} }
ASSERT_FALSE(reconcilor->is_reconcile_started_); ASSERT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState()); ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
VerifyCurrentTokens(ParseTokenString(GetParam().tokens_after_reconcile));
// Another reconcile is sometimes triggered if Chrome accounts have changed. // Another reconcile is sometimes triggered if Chrome accounts have changed.
// Allow it to finish. // Allow it to finish.
cookie_manager_service()->SetListAccountsResponseNoAccounts(); cookie_manager_service()->SetListAccountsResponseNoAccounts();
......
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