OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 package org.chromium.net; | |
6 | |
7 import static org.hamcrest.CoreMatchers.equalTo; | |
8 import static org.hamcrest.CoreMatchers.notNullValue; | |
9 import static org.hamcrest.CoreMatchers.nullValue; | |
10 import static org.junit.Assert.assertThat; | |
11 import static org.junit.Assert.fail; | |
12 import static org.mockito.Matchers.anyBoolean; | |
13 import static org.mockito.Matchers.anyLong; | |
14 import static org.mockito.Matchers.anyString; | |
15 import static org.mockito.Mockito.doNothing; | |
16 import static org.mockito.Mockito.mock; | |
17 import static org.mockito.Mockito.spy; | |
18 import static org.mockito.Mockito.verify; | |
19 import static org.mockito.Mockito.when; | |
20 | |
21 import android.accounts.AccountManager; | |
22 import android.accounts.AccountManagerCallback; | |
23 import android.accounts.AccountManagerFuture; | |
24 import android.accounts.AuthenticatorException; | |
25 import android.accounts.OperationCanceledException; | |
26 import android.app.Activity; | |
27 import android.os.Bundle; | |
28 import android.os.Handler; | |
29 | |
30 import org.chromium.base.BaseChromiumApplication; | |
31 import org.chromium.testing.local.LocalRobolectricTestRunner; | |
32 import org.junit.Test; | |
33 import org.junit.runner.RunWith; | |
34 import org.robolectric.Robolectric; | |
35 import org.robolectric.annotation.Config; | |
36 import org.robolectric.annotation.Implementation; | |
37 import org.robolectric.annotation.Implements; | |
38 import org.robolectric.shadows.ShadowAccountManager; | |
39 | |
40 import java.io.IOException; | |
41 | |
42 /** | |
43 * Robolectic tests for HttpNegotiateAuthenticator | |
44 */ | |
45 @RunWith(LocalRobolectricTestRunner.class) | |
46 @Config(manifest = Config.NONE, | |
47 shadows = HttpNegotiateAuthenticatorTest.ExtendedShadowAccountManager.cl ass, | |
48 application = BaseChromiumApplication.class) | |
49 public class HttpNegotiateAuthenticatorTest { | |
50 static final String KEY_INCOMING_AUTH_TOKEN = "incomingAuthToken"; | |
51 static final String KEY_SPNEGO_CONTEXT = "spnegoContext"; | |
52 static final String KEY_CAN_DELEGATE = "canDelegate"; | |
53 | |
54 static final String SPNEGO_FEATURE = "SPNEGO"; | |
55 static final String SPNEGO_TOKEN_TYPE_BASE = "SPNEGO:HOSTBASED:"; | |
56 | |
57 static int sCallCount = 0; | |
58 static String sAccountTypeReceived; | |
59 static String sAuthTokenTypeReceived; | |
60 static String sFeaturesReceived[]; | |
61 static Bundle sAddAccountOptionsReceived; | |
62 static Bundle sAuthTokenOptionsReceived; | |
63 static AccountManagerCallback<Bundle> sCallbackReceived; | |
64 static Handler sHandlerReceived; | |
65 | |
66 /** | |
67 * Robolectic's ShadowAccountManager doesn't implement getAccountsByTypeAndF eature so extend it. | |
68 * We simply check the call is correct, and don't try to emulate it | |
69 * Note: Shadow classes need to be public and static. | |
70 */ | |
71 @Implements(AccountManager.class) | |
72 public static class ExtendedShadowAccountManager extends ShadowAccountManage r { | |
73 @Implementation | |
74 public AccountManagerFuture<Bundle> getAuthTokenByFeatures(String accoun tType, | |
75 String authTokenType, String[] features, Activity activity, | |
76 Bundle addAccountOptions, Bundle getAuthTokenOptions, | |
77 AccountManagerCallback<Bundle> callback, Handler handler) { | |
78 sCallCount++; | |
79 sAccountTypeReceived = accountType; | |
80 sAuthTokenTypeReceived = authTokenType; | |
81 sFeaturesReceived = features; | |
82 sAddAccountOptionsReceived = addAccountOptions; | |
83 sAuthTokenOptionsReceived = getAuthTokenOptions; | |
84 sCallbackReceived = callback; | |
85 sHandlerReceived = handler; | |
86 | |
87 return null; | |
88 } | |
89 } | |
90 | |
91 /** | |
92 * Test of {@link HttpNegotiateAuthenticator#getNextAuthToken} | |
93 */ | |
94 @Test | |
95 public void testGetNextAuthToken() { | |
96 HttpNegotiateAuthenticator authenticator = | |
97 HttpNegotiateAuthenticator.create(0, "Dummy_Account"); | |
98 assertThat("Can't get auth token without activity", | |
99 authenticator.getNextAuthToken("principal", "", true), equalTo(f alse)); | |
100 Robolectric.buildActivity(Activity.class).create().start().resume().visi ble(); | |
101 assertThat("Can start getting token with activity", | |
102 authenticator.getNextAuthToken("test_principal", "", true), equa lTo(true)); | |
103 assertThat("getAuthTokenByFeatures called precisely once", sCallCount, e qualTo(1)); | |
104 assertThat("Received account type matches input", sAccountTypeReceived, | |
105 equalTo("Dummy_Account")); | |
106 assertThat("AuthTokenType is \"SPNEGO:HOSTBASED:test_principal\"", sAuth TokenTypeReceived, | |
107 equalTo("SPNEGO:HOSTBASED:test_principal")); | |
108 assertThat("Features are precisly {\"SPNEGO\"}", sFeaturesReceived, | |
Bernhard Bauer
2015/06/10 17:11:03
Nit: "precisely"
aberent
2015/06/15 15:52:19
Done.
| |
109 equalTo(new String[] {"SPNEGO"})); | |
110 assertThat("No account options requested", sAddAccountOptionsReceived, n ullValue()); | |
111 assertThat("There is no existing context", | |
112 sAuthTokenOptionsReceived.get(KEY_SPNEGO_CONTEXT), nullValue()); | |
113 assertThat("The existing token is empty", | |
114 sAuthTokenOptionsReceived.getString(KEY_INCOMING_AUTH_TOKEN), eq ualTo("")); | |
115 assertThat("Delegation is allowed", sAuthTokenOptionsReceived.getBoolean (KEY_CAN_DELEGATE), | |
116 equalTo(true)); | |
117 assertThat("getAuthTokenByFeatures was called with a callback", sCallbac kReceived, | |
118 notNullValue()); | |
119 assertThat("getAuthTokenByFeatures was called with a handler", sHandlerR eceived, | |
120 notNullValue()); | |
121 } | |
122 | |
123 /** | |
124 * Test of callback called when getting the auth token completes. | |
125 */ | |
126 @Test | |
127 public void testAccountManagerCallbackRun() { | |
128 // Spy on the authenticator so that we can override and intercept the na tive method call. | |
129 HttpNegotiateAuthenticator authenticator = | |
130 spy(HttpNegotiateAuthenticator.create(1234, "Dummy_Account")); | |
131 doNothing().when(authenticator).nativeSetResult(anyLong(), anyBoolean(), anyString()); | |
132 | |
133 Robolectric.buildActivity(Activity.class).create().start().resume().visi ble(); | |
134 | |
135 // Call getNextAuthToken to get the callback | |
136 authenticator.getNextAuthToken("test_principal", "", true); | |
137 | |
138 // Avoid warning when creating mock accountManagerFuture, can't take .cl ass of an | |
139 // instantiated generic type, yet complier complains if I leave it unins tantiated. | |
Bernhard Bauer
2015/06/10 17:11:03
Nit: "compiler"
aberent
2015/06/15 15:52:19
Done.
| |
140 @SuppressWarnings("unchecked") | |
141 AccountManagerFuture<Bundle> accountManagerFuture = mock(AccountManagerF uture.class); | |
142 Bundle resultBundle = new Bundle(); | |
143 resultBundle.putString(KEY_SPNEGO_CONTEXT, "test_context"); | |
144 resultBundle.putString(AccountManager.KEY_AUTHTOKEN, "output_token"); | |
145 try { | |
146 when(accountManagerFuture.getResult()).thenReturn(resultBundle); | |
147 } catch (OperationCanceledException | AuthenticatorException | IOExcepti on e) { | |
148 // Can never happen - artifact of Mockito. | |
149 fail(); | |
150 } | |
151 sCallbackReceived.run(accountManagerFuture); | |
152 verify(authenticator).nativeSetResult(1234, true, "output_token"); | |
153 | |
154 // Check that the next call to getNextAuthToken uses the correct context | |
155 authenticator.getNextAuthToken("test_principal", "", true); | |
156 assertThat("The spnego context is preserved between calls", | |
157 sAuthTokenOptionsReceived.getString(KEY_SPNEGO_CONTEXT), equalTo ("test_context")); | |
158 | |
159 // Test exception path | |
160 try { | |
161 when(accountManagerFuture.getResult()).thenThrow(new OperationCancel edException()); | |
162 } catch (OperationCanceledException | AuthenticatorException | IOExcepti on e) { | |
163 // Can never happen - artifact of Mockito. | |
164 fail(); | |
165 } | |
166 sCallbackReceived.run(accountManagerFuture); | |
167 verify(authenticator).nativeSetResult(1234, false, null); | |
168 } | |
169 } | |
OLD | NEW |