1 // Copyright 2015 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.
5 #include "components/signin/ios/browser/profile_oauth2_token_service_ios_delegate.h"
7 #include "base/prefs/pref_registry_simple.h"
8 #include "base/prefs/testing_pref_service.h"
9 #include "base/run_loop.h"
10 #include "components/signin/core/browser/account_tracker_service.h"
11 #include "components/signin/core/browser/profile_oauth2_token_service.h"
12 #include "components/signin/core/browser/test_signin_client.h"
13 #include "components/signin/core/common/signin_pref_names.h"
14 #include "components/signin/ios/browser/fake_profile_oauth2_token_service_ios_provider.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "google_apis/gaia/oauth2_access_token_consumer.h"
17 #include "google_apis/gaia/oauth2_token_service_test_util.h"
18 #include "net/url_request/test_url_fetcher_factory.h"
19 #include "testing/gtest/include/gtest/gtest.h"
21 typedef ProfileOAuth2TokenServiceIOSProvider::AccountInfo ProviderAccount;
23 class ProfileOAuth2TokenServiceIOSDelegateTest
24 : public testing::Test,
25 public OAuth2AccessTokenConsumer,
26 public OAuth2TokenService::Observer,
27 public SigninErrorController::Observer {
29 ProfileOAuth2TokenServiceIOSDelegateTest()
32 token_available_count_(0),
33 token_revoked_count_(0),
34 tokens_loaded_count_(0),
35 access_token_success_(0),
36 access_token_failure_(0),
37 last_access_token_error_(GoogleServiceAuthError::NONE) {}
39 void SetUp() override {
40 prefs_.registry()->RegisterListPref(
41 AccountTrackerService::kAccountInfoPref);
42 prefs_.registry()->RegisterIntegerPref(
43 prefs::kAccountIdMigrationState,
44 AccountTrackerService::MIGRATION_NOT_STARTED);
45 account_tracker_.Initialize(&client_);
47 prefs_.registry()->RegisterBooleanPref(
48 prefs::kTokenServiceExcludeAllSecondaryAccounts, false);
49 prefs_.registry()->RegisterListPref(
50 prefs::kTokenServiceExcludedSecondaryAccounts);
52 factory_.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_revoke_url(), "",
53 net::HTTP_OK, net::URLRequestStatus::SUCCESS);
54 oauth2_delegate_.reset(new ProfileOAuth2TokenServiceIOSDelegate(
55 &client_, &fake_provider_, &account_tracker_,
56 &signin_error_controller_));
57 oauth2_delegate_->AddObserver(this);
58 signin_error_controller_.AddObserver(this);
61 void TearDown() override {
62 signin_error_controller_.RemoveObserver(this);
63 oauth2_delegate_->RemoveObserver(this);
64 oauth2_delegate_->Shutdown();
67 // OAuth2AccessTokenConsumer implementation.
68 void OnGetTokenSuccess(const std::string& access_token,
69 const base::Time& expiration_time) override {
70 ++access_token_success_;
73 void OnGetTokenFailure(const GoogleServiceAuthError& error) override {
74 ++access_token_failure_;
75 last_access_token_error_ = error;
78 // OAuth2TokenService::Observer implementation.
79 void OnRefreshTokenAvailable(const std::string& account_id) override {
80 ++token_available_count_;
82 void OnRefreshTokenRevoked(const std::string& account_id) override {
83 ++token_revoked_count_;
85 void OnRefreshTokensLoaded() override { ++tokens_loaded_count_; }
87 void OnErrorChanged() override { ++error_changed_count_; }
89 void ResetObserverCounts() {
90 token_available_count_ = 0;
91 token_revoked_count_ = 0;
92 tokens_loaded_count_ = 0;
93 token_available_count_ = 0;
94 access_token_failure_ = 0;
95 error_changed_count_ = 0;
98 std::string GetAccountId(const ProviderAccount& provider_account) {
99 return account_tracker_.PickAccountIdForAccount(provider_account.gaia,
100 provider_account.email);
104 base::MessageLoop message_loop_;
105 net::FakeURLFetcherFactory factory_;
106 TestingPrefServiceSimple prefs_;
107 TestSigninClient client_;
108 AccountTrackerService account_tracker_;
109 SigninErrorController signin_error_controller_;
110 FakeProfileOAuth2TokenServiceIOSProvider fake_provider_;
111 scoped_ptr<ProfileOAuth2TokenServiceIOSDelegate> oauth2_delegate_;
112 TestingOAuth2TokenServiceConsumer consumer_;
113 int token_available_count_;
114 int token_revoked_count_;
115 int tokens_loaded_count_;
116 int access_token_success_;
117 int access_token_failure_;
118 int error_changed_count_;
119 GoogleServiceAuthError last_access_token_error_;
122 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
123 LoadRevokeCredentialsOneAccount) {
124 ProviderAccount account = fake_provider_.AddAccount("gaia_1", "email_1@x");
125 oauth2_delegate_->LoadCredentials(GetAccountId(account));
126 base::RunLoop().RunUntilIdle();
127 EXPECT_EQ(1, token_available_count_);
128 EXPECT_EQ(1, tokens_loaded_count_);
129 EXPECT_EQ(0, token_revoked_count_);
130 EXPECT_EQ(1U, oauth2_delegate_->GetAccounts().size());
131 EXPECT_TRUE(oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account)));
133 ResetObserverCounts();
134 oauth2_delegate_->RevokeAllCredentials();
135 EXPECT_EQ(0, token_available_count_);
136 EXPECT_EQ(0, tokens_loaded_count_);
137 EXPECT_EQ(1, token_revoked_count_);
138 EXPECT_EQ(0U, oauth2_delegate_->GetAccounts().size());
139 EXPECT_FALSE(oauth2_delegate_->RefreshTokenIsAvailable("another_account"));
142 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
143 LoadRevokeCredentialsMultipleAccounts) {
144 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
145 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
146 ProviderAccount account3 = fake_provider_.AddAccount("gaia_3", "email_3@x");
147 oauth2_delegate_->LoadCredentials(GetAccountId(account1));
148 base::RunLoop().RunUntilIdle();
149 EXPECT_EQ(3, token_available_count_);
150 EXPECT_EQ(1, tokens_loaded_count_);
151 EXPECT_EQ(0, token_revoked_count_);
152 EXPECT_EQ(3U, oauth2_delegate_->GetAccounts().size());
154 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
156 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
158 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account3)));
160 ResetObserverCounts();
161 oauth2_delegate_->RevokeAllCredentials();
162 EXPECT_EQ(0, token_available_count_);
163 EXPECT_EQ(0, tokens_loaded_count_);
164 EXPECT_EQ(3, token_revoked_count_);
165 EXPECT_EQ(0U, oauth2_delegate_->GetAccounts().size());
167 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
169 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
171 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account3)));
174 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, ReloadCredentials) {
175 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
176 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
177 ProviderAccount account3 = fake_provider_.AddAccount("gaia_3", "email_3@x");
178 oauth2_delegate_->LoadCredentials(GetAccountId(account1));
179 base::RunLoop().RunUntilIdle();
181 // Change the accounts.
182 ResetObserverCounts();
183 fake_provider_.ClearAccounts();
184 fake_provider_.AddAccount(account1.gaia, account1.email);
185 ProviderAccount account4 = fake_provider_.AddAccount("gaia_4", "email_4@x");
186 oauth2_delegate_->ReloadCredentials();
188 EXPECT_EQ(1, token_available_count_);
189 EXPECT_EQ(0, tokens_loaded_count_);
190 EXPECT_EQ(2, token_revoked_count_);
191 EXPECT_EQ(2U, oauth2_delegate_->GetAccounts().size());
193 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
195 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
197 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account3)));
199 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account4)));
202 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
203 ReloadCredentialsIgnoredIfNoPrimaryAccountId) {
204 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
205 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
206 oauth2_delegate_->ReloadCredentials();
208 EXPECT_EQ(0, token_available_count_);
209 EXPECT_EQ(0, tokens_loaded_count_);
210 EXPECT_EQ(0, token_revoked_count_);
211 EXPECT_EQ(0U, oauth2_delegate_->GetAccounts().size());
213 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
215 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
218 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
219 ReloadCredentialsWithPrimaryAccountId) {
220 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
221 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
222 oauth2_delegate_->ReloadCredentials(GetAccountId(account1));
224 EXPECT_EQ(2, token_available_count_);
225 EXPECT_EQ(0, tokens_loaded_count_);
226 EXPECT_EQ(0, token_revoked_count_);
227 EXPECT_EQ(2U, oauth2_delegate_->GetAccounts().size());
229 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
231 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
234 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, ExcludeAllSecondaryAccounts) {
235 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
236 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
237 oauth2_delegate_->ExcludeAllSecondaryAccounts();
238 oauth2_delegate_->ReloadCredentials(GetAccountId(account1));
240 EXPECT_EQ(1, token_available_count_);
241 EXPECT_EQ(0, tokens_loaded_count_);
242 EXPECT_EQ(0, token_revoked_count_);
243 EXPECT_EQ(1U, oauth2_delegate_->GetAccounts().size());
245 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
247 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
250 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, StartRequestSuccess) {
251 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
252 oauth2_delegate_->LoadCredentials(GetAccountId(account1));
253 base::RunLoop().RunUntilIdle();
255 // Fetch access tokens.
256 ResetObserverCounts();
257 std::vector<std::string> scopes;
258 scopes.push_back("scope");
259 scoped_ptr<OAuth2AccessTokenFetcher> fetcher1(
260 oauth2_delegate_->CreateAccessTokenFetcher(
261 GetAccountId(account1), oauth2_delegate_->GetRequestContext(), this));
262 fetcher1->Start("foo", "bar", scopes);
263 EXPECT_EQ(0, access_token_success_);
264 EXPECT_EQ(0, access_token_failure_);
266 ResetObserverCounts();
267 fake_provider_.IssueAccessTokenForAllRequests();
268 base::RunLoop().RunUntilIdle();
269 EXPECT_EQ(1, access_token_success_);
270 EXPECT_EQ(0, access_token_failure_);
273 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, StartRequestFailure) {
274 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
275 oauth2_delegate_->LoadCredentials(GetAccountId(account1));
276 base::RunLoop().RunUntilIdle();
278 // Fetch access tokens.
279 ResetObserverCounts();
280 std::vector<std::string> scopes;
281 scopes.push_back("scope");
282 scoped_ptr<OAuth2AccessTokenFetcher> fetcher1(
283 oauth2_delegate_->CreateAccessTokenFetcher(
284 GetAccountId(account1), oauth2_delegate_->GetRequestContext(), this));
285 fetcher1->Start("foo", "bar", scopes);
286 EXPECT_EQ(0, access_token_success_);
287 EXPECT_EQ(0, access_token_failure_);
289 ResetObserverCounts();
290 fake_provider_.IssueAccessTokenErrorForAllRequests();
291 base::RunLoop().RunUntilIdle();
292 EXPECT_EQ(0, access_token_success_);
293 EXPECT_EQ(1, access_token_failure_);
296 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, ExcludeSecondaryAccounts) {
297 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
298 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
299 ProviderAccount account3 = fake_provider_.AddAccount("gaia_3", "email_3@x");
300 oauth2_delegate_->LoadCredentials(GetAccountId(account1));
301 base::RunLoop().RunUntilIdle();
303 // Ignore one account should remove it from the list of accounts.
304 ResetObserverCounts();
305 oauth2_delegate_->ExcludeSecondaryAccount(GetAccountId(account2));
306 oauth2_delegate_->ReloadCredentials();
308 EXPECT_EQ(0, token_available_count_);
309 EXPECT_EQ(0, tokens_loaded_count_);
310 EXPECT_EQ(1, token_revoked_count_);
311 EXPECT_EQ(2U, oauth2_delegate_->GetAccounts().size());
313 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
315 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
317 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account3)));
319 // Clear ignored account and the refresh token should be available again.
320 ResetObserverCounts();
321 oauth2_delegate_->IncludeSecondaryAccount(GetAccountId(account2));
322 oauth2_delegate_->ReloadCredentials();
324 EXPECT_EQ(1, token_available_count_);
325 EXPECT_EQ(0, tokens_loaded_count_);
326 EXPECT_EQ(0, token_revoked_count_);
327 EXPECT_EQ(3U, oauth2_delegate_->GetAccounts().size());
329 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
331 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
333 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account3)));
336 // Unit test for for http://crbug.com/453470 .
337 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, ExcludeSecondaryAccountTwice) {
338 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
339 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
340 oauth2_delegate_->LoadCredentials(GetAccountId(account1));
341 base::RunLoop().RunUntilIdle();
343 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
345 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
347 // Ignore |account_id_2| twice.
348 oauth2_delegate_->ExcludeSecondaryAccount(GetAccountId(account2));
349 oauth2_delegate_->ExcludeSecondaryAccount(GetAccountId(account2));
350 oauth2_delegate_->ReloadCredentials();
352 // Include |account_id_2| once should add the account back.
353 ResetObserverCounts();
354 oauth2_delegate_->IncludeSecondaryAccount(GetAccountId(account2));
355 oauth2_delegate_->ReloadCredentials();
357 EXPECT_EQ(1, token_available_count_);
358 EXPECT_EQ(0, tokens_loaded_count_);
359 EXPECT_EQ(0, token_revoked_count_);
360 EXPECT_EQ(2U, oauth2_delegate_->GetAccounts().size());
362 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
364 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
367 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
368 LoadRevokeCredentialsClearsExcludedAccounts) {
369 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
370 ProviderAccount account2 = fake_provider_.AddAccount("gaia_2", "email_2@x");
371 ProviderAccount account3 = fake_provider_.AddAccount("gaia_3", "email_3@x");
373 std::vector<std::string> excluded_accounts;
374 excluded_accounts.push_back(GetAccountId(account2));
375 oauth2_delegate_->ExcludeSecondaryAccounts(excluded_accounts);
376 oauth2_delegate_->ReloadCredentials(GetAccountId(account1));
377 base::RunLoop().RunUntilIdle();
378 EXPECT_EQ(2, token_available_count_);
379 EXPECT_EQ(0, tokens_loaded_count_);
380 EXPECT_EQ(0, token_revoked_count_);
381 EXPECT_EQ(2U, oauth2_delegate_->GetAccounts().size());
383 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account1)));
385 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account2)));
387 oauth2_delegate_->RefreshTokenIsAvailable(GetAccountId(account3)));
389 ResetObserverCounts();
390 oauth2_delegate_->RevokeAllCredentials();
391 EXPECT_TRUE(oauth2_delegate_->GetExcludedSecondaryAccounts().empty());
394 // Verifies that UpdateAuthError does nothing after the credentials have been
396 TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest,
397 UpdateAuthErrorAfterRevokeCredentials) {
398 ProviderAccount account1 = fake_provider_.AddAccount("gaia_1", "email_1@x");
399 oauth2_delegate_->ReloadCredentials(GetAccountId(account1));
400 base::RunLoop().RunUntilIdle();
402 ResetObserverCounts();
403 GoogleServiceAuthError cancelled_error(
404 GoogleServiceAuthError::REQUEST_CANCELED);
405 oauth2_delegate_->UpdateAuthError(GetAccountId(account1), cancelled_error);
406 EXPECT_EQ(1, error_changed_count_);
408 oauth2_delegate_->RevokeAllCredentials();
409 ResetObserverCounts();
410 oauth2_delegate_->UpdateAuthError(GetAccountId(account1), cancelled_error);
411 EXPECT_EQ(0, error_changed_count_);