1 // Copyright 2013 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 package org.chromium.chrome.browser.signin;
7 import android.accounts.Account;
8 import android.test.UiThreadTest;
9 import android.test.suitebuilder.annotation.MediumTest;
11 import org.chromium.base.ThreadUtils;
12 import org.chromium.base.test.util.AdvancedMockContext;
13 import org.chromium.base.test.util.Feature;
14 import org.chromium.chrome.browser.profiles.Profile;
15 import org.chromium.chrome.shell.ChromeShellTestBase;
16 import org.chromium.sync.signin.AccountManagerHelper;
17 import org.chromium.sync.signin.ChromeSigninController;
18 import org.chromium.sync.test.util.AccountHolder;
19 import org.chromium.sync.test.util.MockAccountManager;
21 import java.util.concurrent.atomic.AtomicReference;
24 * Integration test for the OAuth2TokenService.
26 * These tests initialize the native part of the service.
28 public class OAuth2TokenServiceIntegrationTest extends ChromeShellTestBase {
30 private static final Account TEST_ACCOUNT1 =
31 AccountManagerHelper.createAccountFromName("foo@gmail.com");
32 private static final Account TEST_ACCOUNT2 =
33 AccountManagerHelper.createAccountFromName("bar@gmail.com");
34 private static final AccountHolder TEST_ACCOUNT_HOLDER_1 =
35 AccountHolder.create().account(TEST_ACCOUNT1).alwaysAccept(true).build();
36 private static final AccountHolder TEST_ACCOUNT_HOLDER_2 =
37 AccountHolder.create().account(TEST_ACCOUNT2).alwaysAccept(true).build();
39 private AdvancedMockContext mContext;
40 private OAuth2TokenService mOAuth2TokenService;
41 private MockAccountManager mAccountManager;
42 private TestObserver mObserver;
43 private ChromeSigninController mChromeSigninController;
46 protected void setUp() throws Exception {
49 startChromeBrowserProcessSync(getInstrumentation().getTargetContext());
51 // Set up AccountManager.
52 mContext = new AdvancedMockContext(getInstrumentation().getTargetContext());
53 mAccountManager = new MockAccountManager(mContext, getInstrumentation().getContext());
54 AccountManagerHelper.overrideAccountManagerHelperForTests(mContext, mAccountManager);
56 // Make sure there is no account signed in yet.
57 mChromeSigninController = ChromeSigninController.get(mContext);
58 mChromeSigninController.setSignedInAccountName(null);
60 // Get a reference to the service.
61 mOAuth2TokenService = getOAuth2TokenServiceOnUiThread();
64 mObserver = new TestObserver();
65 addObserver(mObserver);
69 * The {@link OAuth2TokenService} and the {@link Profile} can only be accessed from the UI
70 * thread, so this helper method is a convenience method to retrieve it.
72 * @return the OAuth2TokenService.
74 private static OAuth2TokenService getOAuth2TokenServiceOnUiThread() {
75 final AtomicReference<OAuth2TokenService> service =
76 new AtomicReference<OAuth2TokenService>();
77 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
80 service.set(OAuth2TokenService.getForProfile(Profile.getLastUsedProfile()));
86 private void addObserver(final TestObserver observer) {
87 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
90 mOAuth2TokenService.addObserver(observer);
98 public void testFireRefreshTokenAvailableNotifiesJavaObservers() {
99 // Adding an observer should not lead to a callback.
100 assertEquals(0, mObserver.getAvailableCallCount());
102 // An observer should be called with the correct account.
103 mOAuth2TokenService.fireRefreshTokenAvailable(TEST_ACCOUNT1);
104 assertEquals(1, mObserver.getAvailableCallCount());
105 assertEquals(TEST_ACCOUNT1, mObserver.getLastAccount());
107 // When mOAuth2TokenService, an observer should not be called.
108 mOAuth2TokenService.removeObserver(mObserver);
109 mOAuth2TokenService.fireRefreshTokenAvailable(TEST_ACCOUNT1);
110 assertEquals(1, mObserver.getAvailableCallCount());
112 // No other observer interface method should ever have been called.
113 assertEquals(0, mObserver.getRevokedCallCount());
114 assertEquals(0, mObserver.getLoadedCallCount());
120 public void testFireRefreshTokenRevokedNotifiesJavaObservers() {
121 // Adding an observer should not lead to a callback.
122 assertEquals(0, mObserver.getRevokedCallCount());
124 // An observer should be called with the correct account.
125 mOAuth2TokenService.fireRefreshTokenRevoked(TEST_ACCOUNT1);
126 assertEquals(1, mObserver.getRevokedCallCount());
127 assertEquals(TEST_ACCOUNT1, mObserver.getLastAccount());
129 // When removed, an observer should not be called.
130 mOAuth2TokenService.removeObserver(mObserver);
131 mOAuth2TokenService.fireRefreshTokenRevoked(TEST_ACCOUNT1);
132 assertEquals(1, mObserver.getRevokedCallCount());
134 // No other observer interface method should ever have been called.
135 assertEquals(0, mObserver.getAvailableCallCount());
136 assertEquals(0, mObserver.getLoadedCallCount());
142 public void testFireRefreshTokensLoadedNotifiesJavaObservers() {
143 // Adding an observer should not lead to a callback.
144 assertEquals(0, mObserver.getLoadedCallCount());
146 // An observer should be called with the correct account.
147 mOAuth2TokenService.fireRefreshTokensLoaded();
148 assertEquals(1, mObserver.getLoadedCallCount());
150 // When removed, an observer should not be called.
151 mOAuth2TokenService.removeObserver(mObserver);
152 mOAuth2TokenService.fireRefreshTokensLoaded();
153 assertEquals(1, mObserver.getLoadedCallCount());
155 // No other observer interface method should ever have been called.
156 assertEquals(0, mObserver.getAvailableCallCount());
157 assertEquals(0, mObserver.getRevokedCallCount());
162 public void testValidateAccountsNoAccountsRegisteredAndNoSignedInUser() {
164 mOAuth2TokenService.validateAccounts(mContext, false);
166 // Ensure no calls have been made to the observer.
167 assertEquals(0, mObserver.getAvailableCallCount());
168 assertEquals(0, mObserver.getRevokedCallCount());
169 assertEquals(0, mObserver.getLoadedCallCount());
174 public void testValidateAccountsOneAccountsRegisteredAndNoSignedInUser() {
176 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
179 mOAuth2TokenService.validateAccounts(mContext, false);
181 // Ensure no calls have been made to the observer.
182 assertEquals(0, mObserver.getAvailableCallCount());
183 assertEquals(0, mObserver.getRevokedCallCount());
184 assertEquals(0, mObserver.getLoadedCallCount());
189 public void testValidateAccountsOneAccountsRegisteredSignedIn() {
191 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
193 // Mark user as signed in.
194 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
197 mOAuth2TokenService.validateAccounts(mContext, false);
199 // Ensure one call for the signed in account.
200 assertEquals(1, mObserver.getAvailableCallCount());
201 assertEquals(0, mObserver.getRevokedCallCount());
202 assertEquals(0, mObserver.getLoadedCallCount());
204 // Validate again and make sure no new calls are made.
205 mOAuth2TokenService.validateAccounts(mContext, false);
206 assertEquals(1, mObserver.getAvailableCallCount());
207 assertEquals(0, mObserver.getRevokedCallCount());
208 assertEquals(0, mObserver.getLoadedCallCount());
210 // Validate again with force notifications and make sure one new calls is made.
211 mOAuth2TokenService.validateAccounts(mContext, true);
212 assertEquals(2, mObserver.getAvailableCallCount());
213 assertEquals(0, mObserver.getRevokedCallCount());
214 assertEquals(0, mObserver.getLoadedCallCount());
219 public void testValidateAccountsSingleAccountWithoutChanges() {
221 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
223 // Mark user as signed in.
224 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
226 // Run one validation.
227 mOAuth2TokenService.validateAccounts(mContext, false);
228 assertEquals(1, mObserver.getAvailableCallCount());
229 assertEquals(0, mObserver.getRevokedCallCount());
230 assertEquals(0, mObserver.getLoadedCallCount());
232 // Re-run validation.
233 mOAuth2TokenService.validateAccounts(mContext, false);
234 assertEquals(1, mObserver.getAvailableCallCount());
235 assertEquals(0, mObserver.getRevokedCallCount());
236 assertEquals(0, mObserver.getLoadedCallCount());
241 public void testValidateAccountsSingleAccountThenAddOne() {
243 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
245 // Mark user as signed in.
246 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
248 // Run one validation.
249 mOAuth2TokenService.validateAccounts(mContext, false);
250 assertEquals(1, mObserver.getAvailableCallCount());
251 assertEquals(0, mObserver.getRevokedCallCount());
252 assertEquals(0, mObserver.getLoadedCallCount());
254 // Add another account.
255 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
257 // Re-run validation.
258 mOAuth2TokenService.validateAccounts(mContext, false);
259 assertEquals(2, mObserver.getAvailableCallCount());
260 assertEquals(0, mObserver.getRevokedCallCount());
261 assertEquals(0, mObserver.getLoadedCallCount());
266 public void testValidateAccountsTwoAccountsThenRemoveOne() {
268 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
269 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
271 // Mark user as signed in.
272 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
274 // Run one validation.
275 mOAuth2TokenService.validateAccounts(mContext, false);
276 assertEquals(2, mObserver.getAvailableCallCount());
278 mAccountManager.removeAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
279 mOAuth2TokenService.validateAccounts(mContext, false);
281 assertEquals(2, mObserver.getAvailableCallCount());
282 assertEquals(1, mObserver.getRevokedCallCount());
283 assertEquals(0, mObserver.getLoadedCallCount());
288 public void testValidateAccountsTwoAccountsThenRemoveAll() {
290 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
291 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
293 // Mark user as signed in.
294 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
296 mOAuth2TokenService.validateAccounts(mContext, false);
297 assertEquals(2, mObserver.getAvailableCallCount());
300 mAccountManager.removeAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
301 mAccountManager.removeAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
303 // Re-validate and run checks.
304 mOAuth2TokenService.validateAccounts(mContext, false);
305 assertEquals(2, mObserver.getRevokedCallCount());
306 assertEquals(0, mObserver.getLoadedCallCount());
311 public void testValidateAccountsTwoAccountsThenRemoveAllSignOut() {
313 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
314 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
316 // Mark user as signed in.
317 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
319 mOAuth2TokenService.validateAccounts(mContext, false);
320 assertEquals(2, mObserver.getAvailableCallCount());
323 mChromeSigninController.clearSignedInUser();
324 mAccountManager.removeAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
325 mAccountManager.removeAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
327 // Re-validate and run checks.
328 mOAuth2TokenService.validateAccounts(mContext, false);
329 assertEquals(2, mObserver.getRevokedCallCount());
330 assertEquals(0, mObserver.getLoadedCallCount());
335 public void testValidateAccountsTwoAccountsRegisteredAndOneSignedIn() {
337 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_1);
338 mAccountManager.addAccountHolderExplicitly(TEST_ACCOUNT_HOLDER_2);
340 // Mark user as signed in.
341 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
344 mOAuth2TokenService.validateAccounts(mContext, false);
346 // All accounts will be notified. It is up to the observer
347 // to design if any action is needed.
348 assertEquals(2, mObserver.getAvailableCallCount());
349 assertEquals(0, mObserver.getRevokedCallCount());
350 assertEquals(0, mObserver.getLoadedCallCount());
355 public void testValidateAccountsNoAccountsRegisteredButSignedIn() {
356 // Mark user as signed in without setting up the account.
357 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
360 mOAuth2TokenService.validateAccounts(mContext, false);
362 // Ensure no calls have been made to the observer.
363 assertEquals(0, mObserver.getAvailableCallCount());
364 assertEquals(0, mObserver.getRevokedCallCount());
365 assertEquals(0, mObserver.getLoadedCallCount());
370 public void testValidateAccountsFiresEventAtTheEnd() {
371 // Mark user as signed in without setting up the account.
372 mChromeSigninController.setSignedInAccountName(TEST_ACCOUNT1.name);
373 TestObserver ob = new TestObserver() {
375 public void onRefreshTokenAvailable(Account account) {
376 super.onRefreshTokenAvailable(account);
377 assertEquals(1, OAuth2TokenService.getAccounts(mContext).length);
382 mOAuth2TokenService.validateAccounts(mContext, false);
385 private static class TestObserver implements OAuth2TokenService.OAuth2TokenServiceObserver {
386 private int mAvailableCallCount;
387 private int mRevokedCallCount;
388 private int mLoadedCallCount;
389 private Account mLastAccount;
392 public void onRefreshTokenAvailable(Account account) {
393 mAvailableCallCount++;
394 mLastAccount = account;
398 public void onRefreshTokenRevoked(Account account) {
400 mLastAccount = account;
404 public void onRefreshTokensLoaded() {
408 public int getAvailableCallCount() {
409 return mAvailableCallCount;
412 public int getRevokedCallCount() {
413 return mRevokedCallCount;
416 public int getLoadedCallCount() {
417 return mLoadedCallCount;
420 public Account getLastAccount() {