package com.zegoggles.smssync.auth; import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountManagerCallback; import android.accounts.AccountManagerFuture; import android.accounts.AuthenticatorException; import android.os.Bundle; import android.os.Handler; import com.zegoggles.smssync.preferences.AuthPreferences; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.robolectric.RobolectricTestRunner; import static com.zegoggles.smssync.activity.auth.AccountManagerAuthActivity.AUTH_TOKEN_TYPE; import static com.zegoggles.smssync.activity.auth.AccountManagerAuthActivity.GOOGLE_TYPE; import static org.fest.assertions.api.Assertions.assertThat; import static org.fest.assertions.api.Assertions.fail; import static org.mockito.Mockito.*; import static org.mockito.MockitoAnnotations.initMocks; @RunWith(RobolectricTestRunner.class) public class TokenRefresherTest { @Mock AccountManager accountManager; @Mock AuthPreferences authPreferences; @Mock OAuth2Client oauth2Client; TokenRefresher refresher; @Before public void before() { initMocks(this); refresher = new TokenRefresher(accountManager, oauth2Client, authPreferences); } @Test public void shouldInvalidateTokenManually() throws Exception { assertThat(refresher.invalidateToken("token")).isTrue(); verify(accountManager).invalidateAuthToken(GOOGLE_TYPE, "token"); } @Test public void shouldHandleSecurityExceptionWhenInvalidatingToken() throws Exception { doThrow(new SecurityException()).when(accountManager).invalidateAuthToken(GOOGLE_TYPE, "token"); assertThat(refresher.invalidateToken("token")).isFalse(); } @Test public void shouldInvalidateTokenOnRefresh() throws Exception { when(authPreferences.getOauth2Token()).thenReturn("token"); when(authPreferences.getUsername()).thenReturn("username"); when(accountManager.getAuthToken(notNull(Account.class), anyString(), anyBoolean(), any(AccountManagerCallback.class), any(Handler.class))).thenReturn(mock(AccountManagerFuture.class)); try { refresher.refreshOAuth2Token(); fail("expected error "); } catch (TokenRefreshException e) { assertThat(e.getMessage()).isEqualTo("no bundle received from accountmanager"); } verify(accountManager).invalidateAuthToken(GOOGLE_TYPE, "token"); } @Test public void shouldHandleExceptionsThrownByFuture() throws Exception { when(authPreferences.getOauth2Token()).thenReturn("token"); when(authPreferences.getUsername()).thenReturn("username"); AccountManagerFuture<Bundle> future = mock(AccountManagerFuture.class); when(accountManager.getAuthToken(notNull(Account.class), anyString(), anyBoolean(), any(AccountManagerCallback.class), any(Handler.class))).thenReturn(future); AuthenticatorException exception = new AuthenticatorException(); when(future.getResult()).thenThrow(exception); try { refresher.refreshOAuth2Token(); fail("expected exception"); } catch (TokenRefreshException e) { assertThat(e.getCause()).isSameAs(exception); } verify(accountManager).invalidateAuthToken(GOOGLE_TYPE, "token"); } @Test public void shouldSetNewTokenAfterRefresh() throws Exception { when(authPreferences.getOauth2Token()).thenReturn("token"); when(authPreferences.getUsername()).thenReturn("username"); AccountManagerFuture<Bundle> future = mock(AccountManagerFuture.class); when(accountManager.getAuthToken( new Account("username", GOOGLE_TYPE), AUTH_TOKEN_TYPE, true, null, null) ).thenReturn(future); Bundle bundle = new Bundle(); bundle.putString(AccountManager.KEY_AUTHTOKEN, "newToken"); when(future.getResult()).thenReturn(bundle); refresher.refreshOAuth2Token(); verify(authPreferences).setOauth2Token("username", "newToken", null); } @Test public void shouldUseOAuth2ClientWhenRefreshTokenIsPresent() throws Exception { when(authPreferences.getOauth2Token()).thenReturn("token"); when(authPreferences.getOauth2RefreshToken()).thenReturn("refresh"); when(authPreferences.getUsername()).thenReturn("username"); when(oauth2Client.refreshToken("refresh")).thenReturn(new OAuth2Token("newToken", "type", null, 0, null)); refresher.refreshOAuth2Token(); verify(authPreferences).setOauth2Token("username", "newToken", "refresh"); } @Test public void shouldUpdateRefreshTokenIfPresentInResponse() throws Exception { when(authPreferences.getOauth2Token()).thenReturn("token"); when(authPreferences.getOauth2RefreshToken()).thenReturn("refresh"); when(authPreferences.getUsername()).thenReturn("username"); when(oauth2Client.refreshToken("refresh")).thenReturn(new OAuth2Token("newToken", "type", "newRefresh", 0, null)); refresher.refreshOAuth2Token(); verify(authPreferences).setOauth2Token("username", "newToken", "newRefresh"); } }