Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Unified Diff: net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java

Issue 1422693002: Make Android HttpNegotiateAuthenticator work without an activity (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@AppStatusWebview
Patch Set: Fix destroyForJUnitTests Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
diff --git a/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java b/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
index 0044420ca1fb9e5108251a6b5313048dce179eda..b0d76c47ec9e18cc3246616579709b67055ea66f 100644
--- a/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
+++ b/net/android/junit/src/org/chromium/net/HttpNegotiateAuthenticatorTest.java
@@ -9,38 +9,61 @@
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNull;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.app.Activity;
+import android.app.Application;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
+import junit.framework.Assert;
+
+import org.chromium.base.ApplicationStatus;
import org.chromium.base.BaseChromiumApplication;
+import org.chromium.base.ContextUtils;
import org.chromium.base.test.shadows.ShadowMultiDex;
+import org.chromium.net.HttpNegotiateAuthenticator.GetAccountsCallback;
+import org.chromium.net.HttpNegotiateAuthenticator.RequestData;
import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowAccountManager;
+import org.robolectric.shadows.ShadowApplication;
import java.io.IOException;
+import java.util.List;
/**
* Robolectric tests for HttpNegotiateAuthenticator
@@ -50,59 +73,36 @@
shadows = {HttpNegotiateAuthenticatorTest.ExtendedShadowAccountManager.class,
ShadowMultiDex.class})
public class HttpNegotiateAuthenticatorTest {
- private static class GetAuthTokenByFeaturesInvocation {
- // Since the account manager is an SDK singleton (it is fetched using AccountManager.get()),
- // we can't validate its method calls with Mockito, so do so using our shadow method.
- int mCallCount;
- String mAccountTypeReceived;
- String mAuthTokenTypeReceived;
- String mFeaturesReceived[];
- Bundle mAddAccountOptionsReceived;
- Bundle mAuthTokenOptionsReceived;
- AccountManagerCallback<Bundle> mCallbackReceived;
- Handler mHandlerReceived;
-
- public AccountManagerFuture<Bundle> getAuthTokenByFeatures(String accountType,
- String authTokenType, String[] features, Activity activity,
- Bundle addAccountOptions, Bundle getAuthTokenOptions,
- AccountManagerCallback<Bundle> callback, Handler handler) {
- mCallCount++;
- mAccountTypeReceived = accountType;
- mAuthTokenTypeReceived = authTokenType;
- mFeaturesReceived = features;
- mAddAccountOptionsReceived = addAccountOptions;
- mAuthTokenOptionsReceived = getAuthTokenOptions;
- mCallbackReceived = callback;
- mHandlerReceived = handler;
-
- return null;
- }
- }
-
- private static GetAuthTokenByFeaturesInvocation sInvocation;
-
/**
- * Robolectic's ShadowAccountManager doesn't implement getAccountsByTypeAndFeature so extend it.
- * We simply check the call is correct, and don't try to emulate it. This also allows us to do
- * more checking than we could using a vanilla shadow.
- *
+ * User the AccountManager to inject a mock instance.
* Note: Shadow classes need to be public and static.
*/
@Implements(AccountManager.class)
public static class ExtendedShadowAccountManager extends ShadowAccountManager {
@Implementation
- public AccountManagerFuture<Bundle> getAuthTokenByFeatures(String accountType,
- String authTokenType, String[] features, Activity activity,
- Bundle addAccountOptions, Bundle getAuthTokenOptions,
- AccountManagerCallback<Bundle> callback, Handler handler) {
- return sInvocation.getAuthTokenByFeatures(accountType, authTokenType, features,
- activity, addAccountOptions, getAuthTokenOptions, callback, handler);
+ public static AccountManager get(Context context) {
+ return sMockAccountManager;
}
}
+ @Mock
+ private static AccountManager sMockAccountManager;
+ @Captor
+ private ArgumentCaptor<AccountManagerCallback<Bundle>> mBundleCallbackCaptor;
+ @Captor
+ private ArgumentCaptor<AccountManagerCallback<Account[]>> mAccountCallbackCaptor;
+ @Captor
+ private ArgumentCaptor<Bundle> mBundleCaptor;
+
@Before
public void setUp() {
- sInvocation = new GetAuthTokenByFeaturesInvocation();
+ MockitoAnnotations.initMocks(this);
+ ContextUtils.initApplicationContextForJUnitTests(Robolectric.application);
+ }
+
+ @After
+ public void tearDown() {
+ ApplicationStatus.destroyForJUnitTests();
}
/**
@@ -110,35 +110,150 @@ public void setUp() {
*/
@Test
public void testGetNextAuthToken() {
- HttpNegotiateAuthenticator authenticator =
- HttpNegotiateAuthenticator.create("Dummy_Account");
+ final String accountType = "Dummy_Account";
+ HttpNegotiateAuthenticator authenticator = createWithoutNative(accountType);
Robolectric.buildActivity(Activity.class).create().start().resume().visible();
+
authenticator.getNextAuthToken(0, "test_principal", "", true);
- assertThat(
- "getAuthTokenByFeatures called precisely once", sInvocation.mCallCount, equalTo(1));
- assertThat("Received account type matches input", sInvocation.mAccountTypeReceived,
- equalTo("Dummy_Account"));
- assertThat("AuthTokenType is \"SPNEGO:HOSTBASED:test_principal\"",
- sInvocation.mAuthTokenTypeReceived, equalTo("SPNEGO:HOSTBASED:test_principal"));
- assertThat("Features are precisely {\"SPNEGO\"}", sInvocation.mFeaturesReceived,
- equalTo(new String[] {"SPNEGO"}));
- assertThat("No account options requested", sInvocation.mAddAccountOptionsReceived,
- nullValue());
+
+ verify(sMockAccountManager).getAuthTokenByFeatures(
+ eq(accountType),
+ eq("SPNEGO:HOSTBASED:test_principal"),
+ eq(new String[] {"SPNEGO"}),
+ any(Activity.class),
+ isNull(Bundle.class),
+ mBundleCaptor.capture(),
+ mBundleCallbackCaptor.capture(),
+ any(Handler.class));
+
assertThat("There is no existing context",
- sInvocation.mAuthTokenOptionsReceived.get(
- HttpNegotiateConstants.KEY_SPNEGO_CONTEXT),
+ mBundleCaptor.getValue().get(HttpNegotiateConstants.KEY_SPNEGO_CONTEXT),
nullValue());
assertThat("The existing token is empty",
- sInvocation.mAuthTokenOptionsReceived.getString(
- HttpNegotiateConstants.KEY_INCOMING_AUTH_TOKEN),
+ mBundleCaptor.getValue().getString(HttpNegotiateConstants.KEY_INCOMING_AUTH_TOKEN),
equalTo(""));
- assertThat("Delegation is allowed", sInvocation.mAuthTokenOptionsReceived.getBoolean(
- HttpNegotiateConstants.KEY_CAN_DELEGATE),
+ assertThat("Delegation is allowed",
+ mBundleCaptor.getValue().getBoolean(HttpNegotiateConstants.KEY_CAN_DELEGATE),
equalTo(true));
assertThat("getAuthTokenByFeatures was called with a callback",
- sInvocation.mCallbackReceived, notNullValue());
- assertThat("getAuthTokenByFeatures was called with a handler", sInvocation.mHandlerReceived,
- notNullValue());
+ mBundleCallbackCaptor.getValue(), notNullValue());
+ }
+
+ /**
+ * Test of {@link HttpNegotiateAuthenticator#getNextAuthToken} without a visible activity.
+ * This emulates the behavior with WebView, where the application is a generic one and doesn't
+ * set up the ApplicationStatus the same way.
+ */
+ @Test
+ @Config(application = Application.class)
+ public void testGetNextAuthTokenWithoutActivity() {
+ final String accountType = "Dummy_Account";
+ final Account[] returnedAccount = {new Account("name", accountType)};
+ HttpNegotiateAuthenticator authenticator = createWithoutNative(accountType);
+
+ authenticator.getNextAuthToken(1234, "test_principal", "", true);
+
+ Assert.assertNull(ApplicationStatus.getLastTrackedFocusedActivity());
+ verify(sMockAccountManager).getAccountsByTypeAndFeatures(
+ eq(accountType),
+ eq(new String[]{"SPNEGO"}),
+ mAccountCallbackCaptor.capture(),
+ any(Handler.class));
+
+ mAccountCallbackCaptor.getValue().run(makeFuture(returnedAccount));
+
+ verify(sMockAccountManager).getAuthToken(
+ any(Account.class),
+ eq("SPNEGO:HOSTBASED:test_principal"),
+ mBundleCaptor.capture(),
+ eq(true),
+ any(HttpNegotiateAuthenticator.GetTokenCallback.class),
+ any(Handler.class));
+
+ assertThat("There is no existing context",
+ mBundleCaptor.getValue().get(HttpNegotiateConstants.KEY_SPNEGO_CONTEXT),
+ nullValue());
+ assertThat("The existing token is empty",
+ mBundleCaptor.getValue().getString(HttpNegotiateConstants.KEY_INCOMING_AUTH_TOKEN),
+ equalTo(""));
+ assertThat("Delegation is allowed",
+ mBundleCaptor.getValue().getBoolean(HttpNegotiateConstants.KEY_CAN_DELEGATE),
+ equalTo(true));
+ }
+
+ /** Tests the behavior of {@link HttpNegotiateAuthenticator.GetAccountsCallback} */
+ @Test
+ public void testGetAccountCallback() {
+ String type = "Dummy_Account";
+ HttpNegotiateAuthenticator authenticator = createWithoutNative(type);
+ RequestData requestData = new RequestData();
+ requestData.nativeResultObject = 42;
+ requestData.accountManager = sMockAccountManager;
+ GetAccountsCallback callback = authenticator.new GetAccountsCallback(requestData);
+
+ // Should fail because there are no accounts
+ callback.run(makeFuture(new Account[]{}));
+ verify(authenticator).nativeSetResult(
+ eq(42L),
+ eq(NetError.ERR_INVALID_AUTH_CREDENTIALS),
+ isNull(String.class));
+
+ // Should succeed, for a single account we use it for the AccountManager#getAuthToken call.
+ Account testAccount = new Account("a", type);
+ callback.run(makeFuture(new Account[]{testAccount}));
+ verify(sMockAccountManager).getAuthToken(
+ eq(testAccount),
+ anyString(),
+ any(Bundle.class),
+ eq(true),
+ any(HttpNegotiateAuthenticator.GetTokenCallback.class),
+ any(Handler.class));
+
+ // Should fail because there is more than one account
+ callback.run(makeFuture(new Account[]{new Account("a", type), new Account("b", type)}));
+ verify(authenticator, times(2)).nativeSetResult(
+ eq(42L),
+ eq(NetError.ERR_INVALID_AUTH_CREDENTIALS),
+ isNull(String.class));
+ }
+
+ /**
+ * Tests the behavior of {@link HttpNegotiateAuthenticator.GetTokenCallback} when the result it
+ * receives contains an intent rather than a token directly.
+ */
+ @Test
+ public void testGetTokenCallbackWithIntent() {
+ String type = "Dummy_Account";
+ HttpNegotiateAuthenticator authenticator = createWithoutNative(type);
+ RequestData requestData = new RequestData();
+ requestData.nativeResultObject = 42;
+ requestData.authTokenType = "foo";
+ requestData.account = new Account("a", type);
+ requestData.accountManager = sMockAccountManager;
+ Bundle b = new Bundle();
+ b.putParcelable(AccountManager.KEY_INTENT, new Intent());
+
+ authenticator.new GetTokenCallback(requestData).run(makeFuture(b));
+ verifyZeroInteractions(sMockAccountManager);
+
+ // Verify that the broadcast receiver is registered
+ Intent intent = new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION);
+ ShadowApplication shadowApplication = Robolectric.getShadowApplication();
+ List<BroadcastReceiver> receivers = shadowApplication.getReceiversForIntent(intent);
+ assertThat("There is one registered broadcast receiver", receivers.size(), equalTo(1));
+
+ // Send the intent to the receiver.
+ BroadcastReceiver receiver = receivers.get(0);
+ receiver.onReceive(Robolectric.getShadowApplication().getApplicationContext(), intent);
+
+ // Verify that the auth token is properly requested from the account manager.
+ verify(sMockAccountManager).getAuthToken(
+ eq(new Account("a", type)),
+ eq("foo"),
+ isNull(Bundle.class),
+ eq(true),
+ any(HttpNegotiateAuthenticator.GetTokenCallback.class),
+ any(Handler.class));
}
/**
@@ -146,105 +261,198 @@ public void testGetNextAuthToken() {
*/
@Test
public void testAccountManagerCallbackRun() {
- // Spy on the authenticator so that we can override and intercept the native method call.
- HttpNegotiateAuthenticator authenticator =
- spy(HttpNegotiateAuthenticator.create("Dummy_Account"));
- doNothing().when(authenticator).nativeSetResult(anyLong(), anyInt(), anyString());
+ HttpNegotiateAuthenticator authenticator = createWithoutNative("Dummy_Account");
Robolectric.buildActivity(Activity.class).create().start().resume().visible();
// Call getNextAuthToken to get the callback
authenticator.getNextAuthToken(1234, "test_principal", "", true);
+ verify(sMockAccountManager)
+ .getAuthTokenByFeatures(anyString(), anyString(), any(String[].class),
+ any(Activity.class), any(Bundle.class), any(Bundle.class),
+ mBundleCallbackCaptor.capture(), any(Handler.class));
- // Avoid warning when creating mock accountManagerFuture, can't take .class of an
- // instantiated generic type, yet compiler complains if I leave it uninstantiated.
- @SuppressWarnings("unchecked")
- AccountManagerFuture<Bundle> accountManagerFuture = mock(AccountManagerFuture.class);
Bundle resultBundle = new Bundle();
Bundle context = new Bundle();
context.putString("String", "test_context");
resultBundle.putInt(HttpNegotiateConstants.KEY_SPNEGO_RESULT, HttpNegotiateConstants.OK);
resultBundle.putBundle(HttpNegotiateConstants.KEY_SPNEGO_CONTEXT, context);
resultBundle.putString(AccountManager.KEY_AUTHTOKEN, "output_token");
- try {
- when(accountManagerFuture.getResult()).thenReturn(resultBundle);
- } catch (OperationCanceledException | AuthenticatorException | IOException e) {
- // Can never happen - artifact of Mockito.
- fail();
- }
- sInvocation.mCallbackReceived.run(accountManagerFuture);
+ mBundleCallbackCaptor.getValue().run(makeFuture(resultBundle));
verify(authenticator).nativeSetResult(1234, 0, "output_token");
// Check that the next call to getNextAuthToken uses the correct context
authenticator.getNextAuthToken(5678, "test_principal", "", true);
+ verify(sMockAccountManager, times(2))
+ .getAuthTokenByFeatures(anyString(), anyString(), any(String[].class),
+ any(Activity.class), any(Bundle.class), mBundleCaptor.capture(),
+ mBundleCallbackCaptor.capture(), any(Handler.class));
+
assertThat("The spnego context is preserved between calls",
- sInvocation.mAuthTokenOptionsReceived.getBundle(
- HttpNegotiateConstants.KEY_SPNEGO_CONTEXT),
+ mBundleCaptor.getValue().getBundle(HttpNegotiateConstants.KEY_SPNEGO_CONTEXT),
equalTo(context));
// Test exception path
- try {
- when(accountManagerFuture.getResult()).thenThrow(new OperationCanceledException());
- } catch (OperationCanceledException | AuthenticatorException | IOException e) {
- // Can never happen - artifact of Mockito.
- fail();
- }
- sInvocation.mCallbackReceived.run(accountManagerFuture);
- verify(authenticator).nativeSetResult(5678, NetError.ERR_ABORTED, null);
+ mBundleCallbackCaptor.getValue().run(
+ this.<Bundle>makeFuture(new OperationCanceledException()));
+ verify(authenticator).nativeSetResult(5678, NetError.ERR_UNEXPECTED, null);
}
- private void checkErrorReturn(Integer spnegoError, int expectedError) {
- // Spy on the authenticator so that we can override and intercept the native method call.
- HttpNegotiateAuthenticator authenticator =
- spy(HttpNegotiateAuthenticator.create("Dummy_Account"));
- doNothing().when(authenticator).nativeSetResult(anyLong(), anyInt(), anyString());
-
+ @Test
+ public void testPermissionDenied() {
Robolectric.buildActivity(Activity.class).create().start().resume().visible();
+ HttpNegotiateAuthenticator authenticator = createWithoutNative("Dummy_Account");
- // Call getNextAuthToken to get the callback
- authenticator.getNextAuthToken(1234, "test_principal", "", true);
+ doReturn(false).when(authenticator).hasPermission(any(Context.class), anyString());
- // Avoid warning when creating mock accountManagerFuture, can't take .class of an
- // instantiated generic type, yet compiler complains if I leave it uninstantiated.
- @SuppressWarnings("unchecked")
- AccountManagerFuture<Bundle> accountManagerFuture = mock(AccountManagerFuture.class);
- Bundle resultBundle = new Bundle();
- if (spnegoError != null) {
- resultBundle.putInt(HttpNegotiateConstants.KEY_SPNEGO_RESULT, spnegoError);
- }
- try {
- when(accountManagerFuture.getResult()).thenReturn(resultBundle);
- } catch (OperationCanceledException | AuthenticatorException | IOException e) {
- // Can never happen - artifact of Mockito.
- fail();
- }
- sInvocation.mCallbackReceived.run(accountManagerFuture);
- verify(authenticator).nativeSetResult(anyLong(), eq(expectedError), anyString());
+ authenticator.getNextAuthToken(1234, "test_principal", "", true);
+ verify(authenticator)
+ .nativeSetResult(anyLong(), eq(NetError.ERR_MISCONFIGURED_AUTH_ENVIRONMENT),
+ isNull(String.class));
}
- /**
- * Test of callback error returns when getting the auth token completes.
- */
@Test
- public void testAccountManagerCallbackErrorReturns() {
+ public void testAccountManagerCallbackNullErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(null, NetError.ERR_UNEXPECTED);
+ }
+
+ @Test
+ public void testAccountManagerCallbackUnexpectedErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_UNEXPECTED, NetError.ERR_UNEXPECTED);
+ }
+
+ @Test
+ public void testAccountManagerCallbackAbortedErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_ABORTED, NetError.ERR_ABORTED);
+ }
+
+ @Test
+ public void testAccountManagerCallbackSecLibErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS,
NetError.ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS);
+ }
+
+ @Test
+ public void testAccountManagerCallbackInvalidResponseErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(
HttpNegotiateConstants.ERR_INVALID_RESPONSE, NetError.ERR_INVALID_RESPONSE);
+ }
+
+ @Test
+ public void testAccountManagerCallbackInvalidAuthCredsErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_INVALID_AUTH_CREDENTIALS,
NetError.ERR_INVALID_AUTH_CREDENTIALS);
+ }
+
+ @Test
+ public void testAccountManagerCallbackUnsuppAutchSchemeErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_UNSUPPORTED_AUTH_SCHEME,
NetError.ERR_UNSUPPORTED_AUTH_SCHEME);
+ }
+
+ @Test
+ public void testAccountManagerCallbackMissingAuthCredsErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_MISSING_AUTH_CREDENTIALS,
NetError.ERR_MISSING_AUTH_CREDENTIALS);
+ }
+
+ @Test
+ public void testAccountManagerCallbackUndocSecLibErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(HttpNegotiateConstants.ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS,
NetError.ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS);
+ }
+
+ @Test
+ public void testAccountManagerCallbackMalformedIdentityErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
checkErrorReturn(
HttpNegotiateConstants.ERR_MALFORMED_IDENTITY, NetError.ERR_MALFORMED_IDENTITY);
+ }
+
+ @Test
+ public void testAccountManagerCallbackInvalidErrorReturns() {
+ Robolectric.buildActivity(Activity.class).create().start().resume().visible();
// 9999 is not a valid return value
checkErrorReturn(9999, NetError.ERR_UNEXPECTED);
}
+
+ private void checkErrorReturn(Integer spnegoError, int expectedError) {
+ HttpNegotiateAuthenticator authenticator = createWithoutNative("Dummy_Account");
+
+ // Call getNextAuthToken to get the callback
+ authenticator.getNextAuthToken(1234, "test_principal", "", true);
+ verify(sMockAccountManager).getAuthTokenByFeatures(
+ anyString(),
+ anyString(),
+ any(String[].class),
+ any(Activity.class),
+ any(Bundle.class),
+ any(Bundle.class),
+ mBundleCallbackCaptor.capture(),
+ any(Handler.class));
+
+ Bundle resultBundle = new Bundle();
+ if (spnegoError != null) {
+ resultBundle.putInt(HttpNegotiateConstants.KEY_SPNEGO_RESULT, spnegoError);
+ }
+ mBundleCallbackCaptor.getValue().run(makeFuture(resultBundle));
+ verify(authenticator).nativeSetResult(anyLong(), eq(expectedError), anyString());
+ }
+
+ /**
+ * Returns a future that successfully returns the provided result.
+ * Hides mocking related annoyances: compiler warnings and irrelevant catch clauses.
+ */
+ private <T> AccountManagerFuture<T> makeFuture(T result) {
+ // Avoid warning when creating mock accountManagerFuture, can't take .class of an
+ // instantiated generic type, yet compiler complains if I leave it uninstantiated.
+ @SuppressWarnings("unchecked")
+ AccountManagerFuture<T> accountManagerFuture = mock(AccountManagerFuture.class);
+ try {
+ when(accountManagerFuture.getResult()).thenReturn(result);
+ } catch (OperationCanceledException | AuthenticatorException | IOException e) {
+ // Can never happen - artifact of Mockito.
+ fail();
+ }
+ return accountManagerFuture;
+ }
+
+ /**
+ * Returns a future that fails with the provided exception when trying to get its result.
+ * Hides mocking related annoyances: compiler warnings and irrelevant catch clauses.
+ */
+ private <T> AccountManagerFuture<T> makeFuture(Exception ex) {
+ // Avoid warning when creating mock accountManagerFuture, can't take .class of an
+ // instantiated generic type, yet compiler complains if I leave it uninstantiated.
+ @SuppressWarnings("unchecked")
+ AccountManagerFuture<T> accountManagerFuture = mock(AccountManagerFuture.class);
+ try {
+ when(accountManagerFuture.getResult()).thenThrow(ex);
+ } catch (OperationCanceledException | AuthenticatorException | IOException e) {
+ // Can never happen - artifact of Mockito.
+ fail();
+ }
+ return accountManagerFuture;
+ }
+
+ /**
+ * Returns a new authenticator as a spy so that we can override and intercept the native method
+ * calls.
+ */
+ private HttpNegotiateAuthenticator createWithoutNative(String accountType) {
+ HttpNegotiateAuthenticator authenticator =
+ spy(HttpNegotiateAuthenticator.create(accountType));
+ doNothing().when(authenticator).nativeSetResult(anyLong(), anyInt(), anyString());
+ doReturn(true).when(authenticator).hasPermission(any(Context.class), anyString());
+ return authenticator;
+ }
}
« no previous file with comments | « net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698