1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "web_signin_bridge.h"
6
7 #include <memory>
8 #include <set>
9
10 #include "base/test/mock_callback.h"
11 #include "base/test/task_environment.h"
12 #include "components/signin/core/browser/account_reconcilor.h"
13 #include "components/signin/public/base/account_consistency_method.h"
14 #include "components/signin/public/base/test_signin_client.h"
15 #include "components/signin/public/identity_manager/identity_test_environment.h"
16 #include "components/sync_preferences/testing_pref_service_syncable.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 using ::testing::_;
21
22 class StubAccountReconcilorDelegate : public signin::AccountReconcilorDelegate {
23 public:
24 StubAccountReconcilorDelegate() = default;
25 ~StubAccountReconcilorDelegate() override = default;
26
IsReconcileEnabled() const27 bool IsReconcileEnabled() const override { return true; }
ShouldAbortReconcileIfPrimaryHasError() const28 bool ShouldAbortReconcileIfPrimaryHasError() const override { return true; }
29 };
30
31 class WebSigninBridgeTest : public ::testing::Test {
32 public:
WebSigninBridgeTest()33 WebSigninBridgeTest()
34 : signin_client_(&prefs_),
35 identity_test_env_(nullptr,
36 &prefs_,
37 signin::AccountConsistencyMethod::kDisabled,
38 &signin_client_) {
39 account_reconcilor_ = std::make_unique<AccountReconcilor>(
40 identity_test_env_.identity_manager(), &signin_client_,
41 std::make_unique<StubAccountReconcilorDelegate>());
42 }
43
~WebSigninBridgeTest()44 ~WebSigninBridgeTest() override { account_reconcilor_->Shutdown(); }
45
CreateWebSigninBridge(CoreAccountInfo account,WebSigninBridge::OnSigninCompletedCallback callback)46 std::unique_ptr<WebSigninBridge> CreateWebSigninBridge(
47 CoreAccountInfo account,
48 WebSigninBridge::OnSigninCompletedCallback callback) {
49 return std::make_unique<WebSigninBridge>(
50 identity_test_env_.identity_manager(), account_reconcilor_.get(),
51 account, std::move(callback));
52 }
53
54 protected:
55 base::test::SingleThreadTaskEnvironment task_environment_;
56 sync_preferences::TestingPrefServiceSyncable prefs_;
57 TestSigninClient signin_client_;
58 signin::IdentityTestEnvironment identity_test_env_;
59 std::unique_ptr<AccountReconcilor> account_reconcilor_;
60
61 DISALLOW_COPY_AND_ASSIGN(WebSigninBridgeTest);
62 };
63
TEST_F(WebSigninBridgeTest,CookiesWithSigninAccountShouldTriggerOnSigninSucceeded)64 TEST_F(WebSigninBridgeTest,
65 CookiesWithSigninAccountShouldTriggerOnSigninSucceeded) {
66 AccountInfo account =
67 identity_test_env_.MakeAccountAvailable("test@gmail.com");
68 base::MockCallback<WebSigninBridge::OnSigninCompletedCallback> callback;
69 std::unique_ptr<WebSigninBridge> web_signin_bridge =
70 CreateWebSigninBridge(account, callback.Get());
71 EXPECT_CALL(callback, Run(GoogleServiceAuthError()));
72
73 identity_test_env_.SetPrimaryAccount(account.email);
74 signin::CookieParamsForTest cookie_params{account.email, account.gaia};
75 identity_test_env_.SetCookieAccounts({cookie_params});
76 }
77
TEST_F(WebSigninBridgeTest,CookiesWithSigninAccountShouldTriggerOnSigninSucceededAfterSigninFailed)78 TEST_F(
79 WebSigninBridgeTest,
80 CookiesWithSigninAccountShouldTriggerOnSigninSucceededAfterSigninFailed) {
81 AccountInfo account =
82 identity_test_env_.MakeAccountAvailable("test@gmail.com");
83 base::MockCallback<WebSigninBridge::OnSigninCompletedCallback> callback;
84 std::unique_ptr<WebSigninBridge> web_signin_bridge =
85 CreateWebSigninBridge(account, callback.Get());
86
87 EXPECT_CALL(callback,
88 Run(GoogleServiceAuthError(
89 GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS)));
90 identity_test_env_.SetPrimaryAccount(account.email);
91 identity_test_env_.SetInvalidRefreshTokenForAccount(account.account_id);
92 identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
93 account.account_id,
94 GoogleServiceAuthError(
95 GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
96 account_reconcilor_->EnableReconcile();
97 EXPECT_EQ(signin_metrics::AccountReconcilorState::ACCOUNT_RECONCILOR_ERROR,
98 account_reconcilor_->GetState());
99
100 EXPECT_CALL(callback, Run(GoogleServiceAuthError()));
101 identity_test_env_.SetRefreshTokenForAccount(account.account_id);
102 signin::CookieParamsForTest cookie_params{account.email, account.gaia};
103 identity_test_env_.SetCookieAccounts({cookie_params});
104 }
105
TEST_F(WebSigninBridgeTest,CookiesWithoutSigninAccountDontTriggerOnSigninSucceeded)106 TEST_F(WebSigninBridgeTest,
107 CookiesWithoutSigninAccountDontTriggerOnSigninSucceeded) {
108 AccountInfo signin_account =
109 identity_test_env_.MakeAccountAvailable("test1@gmail.com");
110 AccountInfo non_signin_account =
111 identity_test_env_.MakeAccountAvailable("test2@gmail.com");
112 base::MockCallback<WebSigninBridge::OnSigninCompletedCallback> callback;
113 std::unique_ptr<WebSigninBridge> web_signin_bridge =
114 CreateWebSigninBridge(signin_account, callback.Get());
115 EXPECT_CALL(callback, Run(_)).Times(0);
116
117 identity_test_env_.SetPrimaryAccount(non_signin_account.email);
118 signin::CookieParamsForTest cookie_params{non_signin_account.email,
119 non_signin_account.gaia};
120 identity_test_env_.SetCookieAccounts({cookie_params});
121 }
122
TEST_F(WebSigninBridgeTest,ReconcilorErrorShouldTriggerOnSigninFailed)123 TEST_F(WebSigninBridgeTest, ReconcilorErrorShouldTriggerOnSigninFailed) {
124 AccountInfo account =
125 identity_test_env_.MakeAccountAvailable("test@gmail.com");
126 base::MockCallback<WebSigninBridge::OnSigninCompletedCallback> callback;
127 std::unique_ptr<WebSigninBridge> web_signin_bridge =
128 CreateWebSigninBridge(account, callback.Get());
129 EXPECT_CALL(callback,
130 Run(GoogleServiceAuthError(
131 GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS)));
132
133 identity_test_env_.SetPrimaryAccount(account.email);
134 identity_test_env_.SetInvalidRefreshTokenForAccount(account.account_id);
135 identity_test_env_.UpdatePersistentErrorOfRefreshTokenForAccount(
136 account.account_id,
137 GoogleServiceAuthError(
138 GoogleServiceAuthError::State::INVALID_GAIA_CREDENTIALS));
139 CoreAccountId account_id1 =
140 identity_test_env_.identity_manager()->GetPrimaryAccountId();
141 EXPECT_TRUE(
142 identity_test_env_.identity_manager()
143 ->HasAccountWithRefreshTokenInPersistentErrorState(account_id1));
144 account_reconcilor_->EnableReconcile();
145 EXPECT_EQ(signin_metrics::AccountReconcilorState::ACCOUNT_RECONCILOR_ERROR,
146 account_reconcilor_->GetState());
147 CoreAccountId account_id2 =
148 identity_test_env_.identity_manager()->GetPrimaryAccountId();
149 EXPECT_TRUE(
150 identity_test_env_.identity_manager()
151 ->HasAccountWithRefreshTokenInPersistentErrorState(account_id2));
152 }
153