| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.superviseduser; | 5 package org.chromium.chrome.browser.superviseduser; |
| 6 | 6 |
| 7 import static org.hamcrest.CoreMatchers.is; | 7 import static org.hamcrest.CoreMatchers.is; |
| 8 import static org.junit.Assert.assertThat; | 8 import static org.junit.Assert.assertThat; |
| 9 import static org.mockito.ArgumentMatchers.any; | 9 import static org.mockito.ArgumentMatchers.any; |
| 10 import static org.mockito.ArgumentMatchers.anyLong; | 10 import static org.mockito.ArgumentMatchers.anyLong; |
| 11 import static org.mockito.ArgumentMatchers.anyString; | 11 import static org.mockito.ArgumentMatchers.anyString; |
| 12 import static org.mockito.ArgumentMatchers.eq; | 12 import static org.mockito.ArgumentMatchers.eq; |
| 13 import static org.mockito.Mockito.doAnswer; | 13 import static org.mockito.Mockito.doAnswer; |
| 14 import static org.mockito.Mockito.times; | 14 import static org.mockito.Mockito.mock; |
| 15 import static org.mockito.Mockito.verify; | 15 import static org.mockito.Mockito.verify; |
| 16 import static org.mockito.Mockito.when; |
| 16 | 17 |
| 18 import android.accounts.Account; |
| 19 import android.content.Context; |
| 20 |
| 21 import org.junit.After; |
| 17 import org.junit.Before; | 22 import org.junit.Before; |
| 18 import org.junit.Rule; | 23 import org.junit.Rule; |
| 19 import org.junit.Test; | 24 import org.junit.Test; |
| 20 import org.junit.runner.RunWith; | 25 import org.junit.runner.RunWith; |
| 21 import org.mockito.Mockito; | 26 import org.mockito.Mockito; |
| 22 import org.mockito.invocation.InvocationOnMock; | 27 import org.mockito.invocation.InvocationOnMock; |
| 23 import org.mockito.stubbing.Answer; | 28 import org.mockito.stubbing.Answer; |
| 29 import org.robolectric.RuntimeEnvironment; |
| 24 import org.robolectric.annotation.Config; | 30 import org.robolectric.annotation.Config; |
| 25 | 31 |
| 32 import org.chromium.base.ContextUtils; |
| 33 import org.chromium.base.library_loader.ProcessInitException; |
| 26 import org.chromium.chrome.browser.DisableHistogramsRule; | 34 import org.chromium.chrome.browser.DisableHistogramsRule; |
| 35 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; |
| 36 import org.chromium.chrome.browser.superviseduser.SupervisedUserContentProvider.
SupervisedUserQueryReply; |
| 37 import org.chromium.components.signin.AccountManagerDelegate; |
| 38 import org.chromium.components.signin.AccountManagerHelper; |
| 39 import org.chromium.components.signin.ChromeSigninController; |
| 27 import org.chromium.components.webrestrictions.browser.WebRestrictionsContentPro
vider.WebRestrictionsResult; | 40 import org.chromium.components.webrestrictions.browser.WebRestrictionsContentPro
vider.WebRestrictionsResult; |
| 28 import org.chromium.testing.local.LocalRobolectricTestRunner; | 41 import org.chromium.testing.local.LocalRobolectricTestRunner; |
| 29 | 42 |
| 30 /** | 43 /** |
| 31 * Tests of SupervisedUserContentProvider. This is tested as a simple class, not
as a content | 44 * Tests of SupervisedUserContentProvider. This is tested as a simple class, not
as a content |
| 32 * provider. The content provider aspects are tested with WebRestrictionsContent
ProviderTest. | 45 * provider. The content provider aspects are tested with WebRestrictionsContent
ProviderTest. |
| 33 */ | 46 */ |
| 34 @RunWith(LocalRobolectricTestRunner.class) | 47 @RunWith(LocalRobolectricTestRunner.class) |
| 35 @Config(manifest = Config.NONE) | 48 @Config(manifest = Config.NONE) |
| 36 public class SupervisedUserContentProviderUnitTest { | 49 public class SupervisedUserContentProviderUnitTest { |
| 37 @Rule | 50 @Rule |
| 38 public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsR
ule(); | 51 public DisableHistogramsRule mDisableHistogramsRule = new DisableHistogramsR
ule(); |
| 39 | 52 |
| 40 private SupervisedUserContentProvider mSupervisedUserContentProvider; | 53 private SupervisedUserContentProvider mSupervisedUserContentProvider; |
| 41 | 54 |
| 42 @Before | 55 @Before |
| 43 public void setUp() { | 56 public void setUp() { |
| 44 mSupervisedUserContentProvider = Mockito.spy(new SupervisedUserContentPr
ovider()); | 57 // Ensure clean state (in particular not signed in). |
| 45 mSupervisedUserContentProvider.setNativeSupervisedUserContentProviderFor
Testing(1234L); | 58 ContextUtils.getAppSharedPreferences().edit().clear().apply(); |
| 59 |
| 60 // Spy on the content provider so that we can watch its calls. Override
methods that wrap |
| 61 // things that can't be mocked (including native calls). |
| 62 mSupervisedUserContentProvider = Mockito.spy(new SupervisedUserContentPr
ovider() { |
| 63 @Override |
| 64 void startForcedSigninProcessor(Context context, Runnable onComplete
) { |
| 65 ChromeSigninController.get(RuntimeEnvironment.application) |
| 66 .setSignedInAccountName("Dummy"); |
| 67 onComplete.run(); |
| 68 } |
| 69 |
| 70 @Override |
| 71 void listenForChildAccountStatusChange(Runnable callback) { |
| 72 callback.run(); |
| 73 } |
| 74 |
| 75 @Override |
| 76 void nativeShouldProceed(long l, SupervisedUserQueryReply reply, Str
ing url) { |
| 77 reply.onQueryComplete(); |
| 78 } |
| 79 |
| 80 @Override |
| 81 void nativeRequestInsert(long l, SupervisedUserInsertReply reply, St
ring url) { |
| 82 reply.onInsertRequestSendComplete(true); |
| 83 } |
| 84 |
| 85 @Override |
| 86 long nativeCreateSupervisedUserContentProvider() { |
| 87 return 5678L; |
| 88 } |
| 89 }); |
| 90 } |
| 91 |
| 92 @After |
| 93 public void shutDown() { |
| 94 ContextUtils.getAppSharedPreferences().edit().clear().apply(); |
| 95 ChromeBrowserInitializer.setForTesting(null); |
| 46 } | 96 } |
| 47 | 97 |
| 48 @Test | 98 @Test |
| 49 public void testShouldProceed() throws InterruptedException { | 99 public void testShouldProceed_PermittedUrl() { |
| 100 mSupervisedUserContentProvider.setNativeSupervisedUserContentProviderFor
Testing(1234L); |
| 50 // Mock the native call for a permitted URL | 101 // Mock the native call for a permitted URL |
| 51 doAnswer(new Answer<Void>() { | |
| 52 | |
| 53 @Override | |
| 54 public Void answer(InvocationOnMock invocation) throws Throwable { | |
| 55 Object args[] = invocation.getArguments(); | |
| 56 ((SupervisedUserContentProvider.SupervisedUserQueryReply) args[1
]) | |
| 57 .onQueryComplete(); | |
| 58 return null; | |
| 59 } | |
| 60 | |
| 61 }) | |
| 62 .when(mSupervisedUserContentProvider) | |
| 63 .nativeShouldProceed(anyLong(), | |
| 64 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), | |
| 65 anyString()); | |
| 66 WebRestrictionsResult result = mSupervisedUserContentProvider.shouldProc
eed("url"); | 102 WebRestrictionsResult result = mSupervisedUserContentProvider.shouldProc
eed("url"); |
| 67 assertThat(result.shouldProceed(), is(true)); | 103 assertThat(result.shouldProceed(), is(true)); |
| 68 verify(mSupervisedUserContentProvider) | 104 verify(mSupervisedUserContentProvider) |
| 69 .nativeShouldProceed(eq(1234L), | 105 .nativeShouldProceed(eq(1234L), |
| 70 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), | 106 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), |
| 71 eq("url")); | 107 eq("url")); |
| 72 // Mock the native call for a forbidden URL | 108 } |
| 109 |
| 110 @Test |
| 111 public void testShouldProceed_ForbiddenUrl() { |
| 112 mSupervisedUserContentProvider.setNativeSupervisedUserContentProviderFor
Testing(1234L); |
| 113 // Modify the result of the native call to make this a forbidden URL |
| 73 doAnswer(new Answer<Void>() { | 114 doAnswer(new Answer<Void>() { |
| 74 | 115 |
| 75 @Override | 116 @Override |
| 76 public Void answer(InvocationOnMock invocation) throws Throwable { | 117 public Void answer(InvocationOnMock invocation) throws Throwable { |
| 77 Object args[] = invocation.getArguments(); | 118 invocation.<SupervisedUserQueryReply>getArgument(1).onQueryFaile
d(1, 2, 3, "url1", |
| 78 ((SupervisedUserContentProvider.SupervisedUserQueryReply) args[1
]) | 119 "url2", "custodian", "custodianEmail", "secondCustodian"
, |
| 79 .onQueryFailed(1, 2, 3, "url1", "url2", "custodian", "cu
stodianEmail", | 120 "secondCustodianEmail"); |
| 80 "secondCustodian", "secondCustodianEmail"); | |
| 81 return null; | 121 return null; |
| 82 } | 122 } |
| 83 | 123 |
| 84 }) | 124 }) |
| 85 .when(mSupervisedUserContentProvider) | 125 .when(mSupervisedUserContentProvider) |
| 86 .nativeShouldProceed(anyLong(), | 126 .nativeShouldProceed(anyLong(), |
| 87 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), | 127 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), |
| 88 anyString()); | 128 anyString()); |
| 89 result = mSupervisedUserContentProvider.shouldProceed("url"); | 129 WebRestrictionsResult result = mSupervisedUserContentProvider.shouldProc
eed("url"); |
| 90 assertThat(result.shouldProceed(), is(false)); | 130 assertThat(result.shouldProceed(), is(false)); |
| 91 assertThat(result.errorIntCount(), is(3)); | 131 assertThat(result.errorIntCount(), is(3)); |
| 92 assertThat(result.getErrorInt(0), is(1)); | 132 assertThat(result.getErrorInt(0), is(1)); |
| 93 assertThat(result.getErrorInt(1), is(2)); | 133 assertThat(result.getErrorInt(1), is(2)); |
| 94 assertThat(result.getErrorInt(2), is(3)); | 134 assertThat(result.getErrorInt(2), is(3)); |
| 95 assertThat(result.errorStringCount(), is(6)); | 135 assertThat(result.errorStringCount(), is(6)); |
| 96 assertThat(result.getErrorString(0), is("url1")); | 136 assertThat(result.getErrorString(0), is("url1")); |
| 97 assertThat(result.getErrorString(1), is("url2")); | 137 assertThat(result.getErrorString(1), is("url2")); |
| 98 assertThat(result.getErrorString(2), is("custodian")); | 138 assertThat(result.getErrorString(2), is("custodian")); |
| 99 assertThat(result.getErrorString(3), is("custodianEmail")); | 139 assertThat(result.getErrorString(3), is("custodianEmail")); |
| 100 assertThat(result.getErrorString(4), is("secondCustodian")); | 140 assertThat(result.getErrorString(4), is("secondCustodian")); |
| 101 assertThat(result.getErrorString(5), is("secondCustodianEmail")); | 141 assertThat(result.getErrorString(5), is("secondCustodianEmail")); |
| 102 } | 142 } |
| 103 | 143 |
| 104 @Test | 144 @Test |
| 105 public void testRequestInsert() throws InterruptedException { | 145 public void testRequestInsert_ok() { |
| 106 // Mock native call. | 146 mSupervisedUserContentProvider.setNativeSupervisedUserContentProviderFor
Testing(1234L); |
| 107 doAnswer(new Answer<Void>() { | |
| 108 | 147 |
| 109 @Override | 148 assertThat(mSupervisedUserContentProvider.requestInsert("url"), is(true)
); |
| 110 public Void answer(InvocationOnMock invocation) throws Throwable { | |
| 111 Object args[] = invocation.getArguments(); | |
| 112 ((SupervisedUserContentProvider.SupervisedUserInsertReply) args[
1]) | |
| 113 .onInsertRequestSendComplete(true); | |
| 114 return null; | |
| 115 } | |
| 116 | 149 |
| 117 }) | |
| 118 .when(mSupervisedUserContentProvider) | |
| 119 .nativeRequestInsert(anyLong(), | |
| 120 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), | |
| 121 anyString()); | |
| 122 assertThat(mSupervisedUserContentProvider.requestInsert("url"), is(true)
); | |
| 123 verify(mSupervisedUserContentProvider) | 150 verify(mSupervisedUserContentProvider) |
| 124 .nativeRequestInsert(eq(1234L), | 151 .nativeRequestInsert(eq(1234L), |
| 125 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), | 152 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), |
| 126 eq("url")); | 153 eq("url")); |
| 154 } |
| 155 |
| 156 @Test |
| 157 public void testRequestInsert_failed() { |
| 158 mSupervisedUserContentProvider.setNativeSupervisedUserContentProviderFor
Testing(1234L); |
| 159 // Mock the native call to mock failure |
| 127 doAnswer(new Answer<Void>() { | 160 doAnswer(new Answer<Void>() { |
| 128 | |
| 129 @Override | 161 @Override |
| 130 public Void answer(InvocationOnMock invocation) throws Throwable { | 162 public Void answer(InvocationOnMock invocation) throws Throwable { |
| 131 Object args[] = invocation.getArguments(); | 163 Object args[] = invocation.getArguments(); |
| 132 ((SupervisedUserContentProvider.SupervisedUserInsertReply) args[
1]) | 164 ((SupervisedUserContentProvider.SupervisedUserInsertReply) args[
1]) |
| 133 .onInsertRequestSendComplete(false); | 165 .onInsertRequestSendComplete(false); |
| 134 return null; | 166 return null; |
| 135 } | 167 } |
| 136 | 168 |
| 137 }) | 169 }) |
| 138 .when(mSupervisedUserContentProvider) | 170 .when(mSupervisedUserContentProvider) |
| 139 .nativeRequestInsert(anyLong(), | 171 .nativeRequestInsert(anyLong(), |
| 140 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), | 172 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), |
| 141 anyString()); | 173 anyString()); |
| 142 assertThat(mSupervisedUserContentProvider.requestInsert("url"), is(false
)); | 174 assertThat(mSupervisedUserContentProvider.requestInsert("url"), is(false
)); |
| 143 verify(mSupervisedUserContentProvider, times(2)) | 175 verify(mSupervisedUserContentProvider) |
| 144 .nativeRequestInsert(eq(1234L), | 176 .nativeRequestInsert(eq(1234L), |
| 145 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), | 177 any(SupervisedUserContentProvider.SupervisedUserInsertRe
ply.class), |
| 146 eq("url")); | 178 eq("url")); |
| 147 } | 179 } |
| 180 |
| 181 @Test |
| 182 public void testShouldProceed_withStartupSignedIn() throws ProcessInitExcept
ion { |
| 183 // Set up a signed in user |
| 184 ChromeSigninController.get(RuntimeEnvironment.application).setSignedInAc
countName("Dummy"); |
| 185 // Mock things called during startup |
| 186 ChromeBrowserInitializer mockBrowserInitializer = mock(ChromeBrowserInit
ializer.class); |
| 187 ChromeBrowserInitializer.setForTesting(mockBrowserInitializer); |
| 188 |
| 189 WebRestrictionsResult result = mSupervisedUserContentProvider.shouldProc
eed("url"); |
| 190 |
| 191 assertThat(result.shouldProceed(), is(true)); |
| 192 verify(mockBrowserInitializer).handleSynchronousStartup(); |
| 193 verify(mSupervisedUserContentProvider) |
| 194 .nativeShouldProceed(eq(5678L), |
| 195 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), |
| 196 eq("url")); |
| 197 } |
| 198 |
| 199 @Test |
| 200 public void testShouldProceed_notSignedIn() throws ProcessInitException { |
| 201 // Mock things called during startup |
| 202 ChromeBrowserInitializer mockBrowserInitializer = mock(ChromeBrowserInit
ializer.class); |
| 203 ChromeBrowserInitializer.setForTesting(mockBrowserInitializer); |
| 204 AccountManagerDelegate mockDelegate = mock(AccountManagerDelegate.class)
; |
| 205 AccountManagerHelper.overrideAccountManagerHelperForTests( |
| 206 RuntimeEnvironment.application, mockDelegate); |
| 207 Account account = new Account("Google", "Dummy"); |
| 208 when(mockDelegate.getAccountsByType("Google")).thenReturn(new Account[]
{account}); |
| 209 |
| 210 WebRestrictionsResult result = mSupervisedUserContentProvider.shouldProc
eed("url"); |
| 211 |
| 212 assertThat(result.shouldProceed(), is(true)); |
| 213 verify(mockBrowserInitializer).handleSynchronousStartup(); |
| 214 verify(mSupervisedUserContentProvider) |
| 215 .startForcedSigninProcessor(any(Context.class), any(Runnable.cla
ss)); |
| 216 verify(mSupervisedUserContentProvider) |
| 217 .listenForChildAccountStatusChange(any(Runnable.class)); |
| 218 verify(mSupervisedUserContentProvider) |
| 219 .nativeShouldProceed(eq(5678L), |
| 220 any(SupervisedUserContentProvider.SupervisedUserQueryRep
ly.class), |
| 221 eq("url")); |
| 222 } |
| 223 |
| 224 @Test |
| 225 public void testShouldProceed_cannotSignIn() throws ProcessInitException { |
| 226 // Mock things called during startup |
| 227 ChromeBrowserInitializer mockBrowserInitializer = mock(ChromeBrowserInit
ializer.class); |
| 228 ChromeBrowserInitializer.setForTesting(mockBrowserInitializer); |
| 229 AccountManagerDelegate mockDelegate = mock(AccountManagerDelegate.class)
; |
| 230 AccountManagerHelper.overrideAccountManagerHelperForTests( |
| 231 RuntimeEnvironment.application, mockDelegate); |
| 232 Account account = new Account("Google", "Dummy"); |
| 233 when(mockDelegate.getAccountsByType("Google")).thenReturn(new Account[]
{account}); |
| 234 |
| 235 // Change the behavior of the forced sign-in processor to not sign in. |
| 236 doAnswer(new Answer<Void>() { |
| 237 @Override |
| 238 public Void answer(InvocationOnMock invocation) throws Throwable { |
| 239 invocation.<Runnable>getArgument(1).run(); |
| 240 return null; |
| 241 } |
| 242 }) |
| 243 .when(mSupervisedUserContentProvider) |
| 244 .startForcedSigninProcessor(any(Context.class), any(Runnable.cla
ss)); |
| 245 |
| 246 WebRestrictionsResult result = mSupervisedUserContentProvider.shouldProc
eed("url"); |
| 247 |
| 248 assertThat(result.shouldProceed(), is(false)); |
| 249 assertThat(result.getErrorInt(0), is(5)); |
| 250 } |
| 148 } | 251 } |
| OLD | NEW |