1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.credentials; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.junit.Assert.assertThrows; 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.ArgumentMatchers.eq; 24 import static org.mockito.ArgumentMatchers.same; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.never; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.app.Activity; 31 import android.app.slice.Slice; 32 import android.content.Context; 33 import android.content.pm.ServiceInfo; 34 import android.net.Uri; 35 import android.os.Bundle; 36 import android.os.CancellationSignal; 37 import android.os.ICancellationSignal; 38 import android.os.OutcomeReceiver; 39 import android.os.RemoteException; 40 import android.service.credentials.CredentialEntry; 41 42 import androidx.test.platform.app.InstrumentationRegistry; 43 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Mock; 49 import org.mockito.junit.MockitoJUnitRunner; 50 51 import java.util.Arrays; 52 import java.util.HashSet; 53 import java.util.List; 54 import java.util.Objects; 55 import java.util.concurrent.Executor; 56 57 @RunWith(MockitoJUnitRunner.class) 58 public class CredentialManagerTest { 59 @Mock private ICredentialManager mMockCredentialManagerService; 60 61 @Mock private Activity mMockActivity; 62 63 private static final int TEST_USER_ID = 1; 64 private static final CredentialProviderInfo TEST_CREDENTIAL_PROVIDER_INFO = 65 new CredentialProviderInfo.Builder(new ServiceInfo()) 66 .setSystemProvider(true) 67 .setOverrideLabel("test") 68 .addCapabilities(Arrays.asList("passkey")) 69 .setEnabled(true) 70 .build(); 71 private static final List<CredentialProviderInfo> TEST_CREDENTIAL_PROVIDER_INFO_LIST = 72 Arrays.asList(TEST_CREDENTIAL_PROVIDER_INFO); 73 74 private GetCredentialRequest mGetRequest; 75 private CreateCredentialRequest mCreateRequest; 76 77 private ClearCredentialStateRequest mClearRequest; 78 private RegisterCredentialDescriptionRequest mRegisterRequest; 79 private UnregisterCredentialDescriptionRequest mUnregisterRequest; 80 81 private CredentialManager mCredentialManager; 82 private Executor mExecutor; 83 private String mPackageName; 84 bundleEquals(Bundle a, Bundle b)85 private static boolean bundleEquals(Bundle a, Bundle b) { 86 if (a == null && b == null) { 87 return true; 88 } 89 if (a == null || b == null) { 90 return false; 91 } 92 for (String aKey : a.keySet()) { 93 if (!Objects.equals(a.get(aKey), b.get(aKey))) { 94 return false; 95 } 96 } 97 98 for (String bKey : b.keySet()) { 99 if (!Objects.equals(b.get(bKey), a.get(bKey))) { 100 return false; 101 } 102 } 103 104 return true; 105 } 106 assertBundleEquals(Bundle a, Bundle b)107 private static void assertBundleEquals(Bundle a, Bundle b) { 108 assertThat(bundleEquals(a, b)).isTrue(); 109 } 110 111 @Before setup()112 public void setup() { 113 mGetRequest = 114 new GetCredentialRequest.Builder(Bundle.EMPTY) 115 .addCredentialOption( 116 new CredentialOption( 117 Credential.TYPE_PASSWORD_CREDENTIAL, 118 Bundle.EMPTY, 119 Bundle.EMPTY, 120 false)) 121 .build(); 122 mCreateRequest = 123 new CreateCredentialRequest.Builder( 124 Credential.TYPE_PASSWORD_CREDENTIAL, Bundle.EMPTY, Bundle.EMPTY) 125 .setIsSystemProviderRequired(false) 126 .setAlwaysSendAppInfoToProvider(false) 127 .build(); 128 mClearRequest = new ClearCredentialStateRequest(Bundle.EMPTY); 129 130 final Slice slice = 131 new Slice.Builder(Uri.parse("foo://bar"), null) 132 .addText("some text", null, List.of(Slice.HINT_TITLE)) 133 .build(); 134 mRegisterRequest = 135 new RegisterCredentialDescriptionRequest( 136 new CredentialDescription( 137 Credential.TYPE_PASSWORD_CREDENTIAL, 138 new HashSet<>(List.of("{ \"foo\": \"bar\" }")), 139 List.of( 140 new CredentialEntry( 141 Credential.TYPE_PASSWORD_CREDENTIAL, slice)))); 142 mUnregisterRequest = 143 new UnregisterCredentialDescriptionRequest( 144 new CredentialDescription( 145 Credential.TYPE_PASSWORD_CREDENTIAL, 146 new HashSet<>(List.of("{ \"foo\": \"bar\" }")), 147 List.of( 148 new CredentialEntry( 149 Credential.TYPE_PASSWORD_CREDENTIAL, slice)))); 150 151 final Context context = InstrumentationRegistry.getInstrumentation().getContext(); 152 mCredentialManager = new CredentialManager(context, mMockCredentialManagerService); 153 mExecutor = Runnable::run; 154 mPackageName = context.getOpPackageName(); 155 } 156 157 @Test testGetCredential_nullRequest()158 public void testGetCredential_nullRequest() { 159 GetCredentialRequest nullRequest = null; 160 assertThrows( 161 NullPointerException.class, 162 () -> 163 mCredentialManager.getCredential( 164 mMockActivity, nullRequest, null, mExecutor, result -> {})); 165 } 166 167 @Test testGetCredential_nullActivity()168 public void testGetCredential_nullActivity() { 169 assertThrows( 170 NullPointerException.class, 171 () -> 172 mCredentialManager.getCredential( 173 null, mGetRequest, null, mExecutor, result -> {})); 174 } 175 176 @Test testGetCredential_nullExecutor()177 public void testGetCredential_nullExecutor() { 178 assertThrows( 179 NullPointerException.class, 180 () -> 181 mCredentialManager.getCredential( 182 mMockActivity, mGetRequest, null, null, result -> {})); 183 } 184 185 @Test testGetCredential_nullCallback()186 public void testGetCredential_nullCallback() { 187 assertThrows( 188 NullPointerException.class, 189 () -> 190 mCredentialManager.getCredential( 191 mMockActivity, mGetRequest, null, null, null)); 192 } 193 194 @Test testGetCredential_noCredential()195 public void testGetCredential_noCredential() throws RemoteException { 196 ArgumentCaptor<IGetCredentialCallback> callbackCaptor = 197 ArgumentCaptor.forClass(IGetCredentialCallback.class); 198 ArgumentCaptor<GetCredentialException> errorCaptor = 199 ArgumentCaptor.forClass(GetCredentialException.class); 200 201 OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback = 202 mock(OutcomeReceiver.class); 203 204 when(mMockCredentialManagerService.executeGetCredential( 205 any(), callbackCaptor.capture(), any())) 206 .thenReturn(mock(ICancellationSignal.class)); 207 mCredentialManager.getCredential(mMockActivity, mGetRequest, null, mExecutor, callback); 208 verify(mMockCredentialManagerService).executeGetCredential(any(), any(), eq(mPackageName)); 209 210 callbackCaptor 211 .getValue() 212 .onError(GetCredentialException.TYPE_NO_CREDENTIAL, "no credential found"); 213 verify(callback).onError(errorCaptor.capture()); 214 215 assertThat(errorCaptor.getValue().getType()) 216 .isEqualTo(GetCredentialException.TYPE_NO_CREDENTIAL); 217 } 218 219 @Test testGetCredential_alreadyCancelled()220 public void testGetCredential_alreadyCancelled() throws RemoteException { 221 final CancellationSignal cancellation = new CancellationSignal(); 222 cancellation.cancel(); 223 224 mCredentialManager.getCredential( 225 mMockActivity, mGetRequest, cancellation, mExecutor, result -> {}); 226 227 verify(mMockCredentialManagerService, never()).executeGetCredential(any(), any(), any()); 228 } 229 230 @Test testGetCredential_cancel()231 public void testGetCredential_cancel() throws RemoteException { 232 final ICancellationSignal serviceSignal = mock(ICancellationSignal.class); 233 final CancellationSignal cancellation = new CancellationSignal(); 234 235 OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback = 236 mock(OutcomeReceiver.class); 237 238 when(mMockCredentialManagerService.executeGetCredential(any(), any(), any())) 239 .thenReturn(serviceSignal); 240 241 mCredentialManager.getCredential( 242 mMockActivity, mGetRequest, cancellation, mExecutor, callback); 243 244 verify(mMockCredentialManagerService).executeGetCredential(any(), any(), eq(mPackageName)); 245 246 cancellation.cancel(); 247 verify(serviceSignal).cancel(); 248 } 249 250 @Test testGetCredential_success()251 public void testGetCredential_success() throws RemoteException { 252 final Credential cred = new Credential(Credential.TYPE_PASSWORD_CREDENTIAL, Bundle.EMPTY); 253 254 ArgumentCaptor<IGetCredentialCallback> callbackCaptor = 255 ArgumentCaptor.forClass(IGetCredentialCallback.class); 256 ArgumentCaptor<GetCredentialResponse> responseCaptor = 257 ArgumentCaptor.forClass(GetCredentialResponse.class); 258 259 OutcomeReceiver<GetCredentialResponse, GetCredentialException> callback = 260 mock(OutcomeReceiver.class); 261 262 when(mMockCredentialManagerService.executeGetCredential( 263 any(), callbackCaptor.capture(), any())) 264 .thenReturn(mock(ICancellationSignal.class)); 265 mCredentialManager.getCredential(mMockActivity, mGetRequest, null, mExecutor, callback); 266 verify(mMockCredentialManagerService).executeGetCredential(any(), any(), eq(mPackageName)); 267 268 callbackCaptor.getValue().onResponse(new GetCredentialResponse(cred)); 269 verify(callback).onResult(responseCaptor.capture()); 270 271 assertThat(responseCaptor.getValue().getCredential().getType()).isEqualTo(cred.getType()); 272 } 273 274 @Test testCreateCredential_nullRequest()275 public void testCreateCredential_nullRequest() { 276 assertThrows( 277 NullPointerException.class, 278 () -> 279 mCredentialManager.createCredential( 280 mMockActivity, null, null, mExecutor, result -> {})); 281 } 282 283 @Test testCreateCredential_nullActivity()284 public void testCreateCredential_nullActivity() { 285 assertThrows( 286 NullPointerException.class, 287 () -> 288 mCredentialManager.createCredential( 289 null, mCreateRequest, null, mExecutor, result -> {})); 290 } 291 292 @Test testCreateCredential_nullExecutor()293 public void testCreateCredential_nullExecutor() { 294 assertThrows( 295 NullPointerException.class, 296 () -> 297 mCredentialManager.createCredential( 298 mMockActivity, mCreateRequest, null, null, result -> {})); 299 } 300 301 @Test testCreateCredential_nullCallback()302 public void testCreateCredential_nullCallback() { 303 assertThrows( 304 NullPointerException.class, 305 () -> 306 mCredentialManager.createCredential( 307 mMockActivity, mCreateRequest, null, mExecutor, null)); 308 } 309 310 @Test testCreateCredential_alreadyCancelled()311 public void testCreateCredential_alreadyCancelled() throws RemoteException { 312 final CancellationSignal cancellation = new CancellationSignal(); 313 cancellation.cancel(); 314 315 mCredentialManager.createCredential( 316 mMockActivity, mCreateRequest, cancellation, mExecutor, result -> {}); 317 318 verify(mMockCredentialManagerService, never()).executeCreateCredential(any(), any(), any()); 319 } 320 321 @Test testCreateCredential_cancel()322 public void testCreateCredential_cancel() throws RemoteException { 323 final ICancellationSignal serviceSignal = mock(ICancellationSignal.class); 324 final CancellationSignal cancellation = new CancellationSignal(); 325 326 OutcomeReceiver<CreateCredentialResponse, CreateCredentialException> callback = 327 mock(OutcomeReceiver.class); 328 329 when(mMockCredentialManagerService.executeCreateCredential(any(), any(), any())) 330 .thenReturn(serviceSignal); 331 332 mCredentialManager.createCredential( 333 mMockActivity, mCreateRequest, cancellation, mExecutor, callback); 334 335 verify(mMockCredentialManagerService) 336 .executeCreateCredential(any(), any(), eq(mPackageName)); 337 338 cancellation.cancel(); 339 verify(serviceSignal).cancel(); 340 } 341 342 @Test testCreateCredential_failed()343 public void testCreateCredential_failed() throws RemoteException { 344 ArgumentCaptor<ICreateCredentialCallback> callbackCaptor = 345 ArgumentCaptor.forClass(ICreateCredentialCallback.class); 346 ArgumentCaptor<CreateCredentialException> errorCaptor = 347 ArgumentCaptor.forClass(CreateCredentialException.class); 348 349 OutcomeReceiver<CreateCredentialResponse, CreateCredentialException> callback = 350 mock(OutcomeReceiver.class); 351 352 when(mMockCredentialManagerService.executeCreateCredential( 353 any(), callbackCaptor.capture(), any())) 354 .thenReturn(mock(ICancellationSignal.class)); 355 mCredentialManager.createCredential( 356 mMockActivity, mCreateRequest, null, mExecutor, callback); 357 verify(mMockCredentialManagerService) 358 .executeCreateCredential(any(), any(), eq(mPackageName)); 359 360 callbackCaptor.getValue().onError(CreateCredentialException.TYPE_UNKNOWN, "unknown error"); 361 verify(callback).onError(errorCaptor.capture()); 362 363 assertThat(errorCaptor.getValue().getType()) 364 .isEqualTo(CreateCredentialException.TYPE_UNKNOWN); 365 } 366 367 @Test testCreateCredential_success()368 public void testCreateCredential_success() throws RemoteException { 369 final Bundle responseData = new Bundle(); 370 responseData.putString("foo", "bar"); 371 372 ArgumentCaptor<ICreateCredentialCallback> callbackCaptor = 373 ArgumentCaptor.forClass(ICreateCredentialCallback.class); 374 ArgumentCaptor<CreateCredentialResponse> responseCaptor = 375 ArgumentCaptor.forClass(CreateCredentialResponse.class); 376 377 OutcomeReceiver<CreateCredentialResponse, CreateCredentialException> callback = 378 mock(OutcomeReceiver.class); 379 380 when(mMockCredentialManagerService.executeCreateCredential( 381 any(), callbackCaptor.capture(), any())) 382 .thenReturn(mock(ICancellationSignal.class)); 383 mCredentialManager.createCredential( 384 mMockActivity, mCreateRequest, null, mExecutor, callback); 385 verify(mMockCredentialManagerService) 386 .executeCreateCredential(any(), any(), eq(mPackageName)); 387 388 callbackCaptor.getValue().onResponse(new CreateCredentialResponse(responseData)); 389 verify(callback).onResult(responseCaptor.capture()); 390 391 assertBundleEquals(responseCaptor.getValue().getData(), responseData); 392 } 393 394 @Test testClearCredentialState_nullRequest()395 public void testClearCredentialState_nullRequest() { 396 assertThrows( 397 NullPointerException.class, 398 () -> mCredentialManager.clearCredentialState(null, null, mExecutor, result -> {})); 399 } 400 401 @Test testClearCredentialState_nullExecutor()402 public void testClearCredentialState_nullExecutor() { 403 assertThrows( 404 NullPointerException.class, 405 () -> 406 mCredentialManager.clearCredentialState( 407 mClearRequest, null, null, result -> {})); 408 } 409 410 @Test testClearCredentialState_nullCallback()411 public void testClearCredentialState_nullCallback() { 412 assertThrows( 413 NullPointerException.class, 414 () -> 415 mCredentialManager.clearCredentialState( 416 mClearRequest, null, mExecutor, null)); 417 } 418 419 @Test testClearCredential_alreadyCancelled()420 public void testClearCredential_alreadyCancelled() throws RemoteException { 421 final CancellationSignal cancellation = new CancellationSignal(); 422 cancellation.cancel(); 423 424 mCredentialManager.clearCredentialState( 425 mClearRequest, cancellation, mExecutor, result -> {}); 426 427 verify(mMockCredentialManagerService, never()).clearCredentialState(any(), any(), any()); 428 } 429 430 @Test testClearCredential_cancel()431 public void testClearCredential_cancel() throws RemoteException { 432 final ICancellationSignal serviceSignal = mock(ICancellationSignal.class); 433 final CancellationSignal cancellation = new CancellationSignal(); 434 435 OutcomeReceiver<Void, ClearCredentialStateException> callback = mock(OutcomeReceiver.class); 436 437 when(mMockCredentialManagerService.clearCredentialState(any(), any(), any())) 438 .thenReturn(serviceSignal); 439 440 mCredentialManager.clearCredentialState(mClearRequest, cancellation, mExecutor, callback); 441 442 verify(mMockCredentialManagerService).clearCredentialState(any(), any(), eq(mPackageName)); 443 444 cancellation.cancel(); 445 verify(serviceSignal).cancel(); 446 } 447 448 @Test testClearCredential_failed()449 public void testClearCredential_failed() throws RemoteException { 450 ArgumentCaptor<IClearCredentialStateCallback> callbackCaptor = 451 ArgumentCaptor.forClass(IClearCredentialStateCallback.class); 452 ArgumentCaptor<ClearCredentialStateException> errorCaptor = 453 ArgumentCaptor.forClass(ClearCredentialStateException.class); 454 455 OutcomeReceiver<Void, ClearCredentialStateException> callback = mock(OutcomeReceiver.class); 456 457 when(mMockCredentialManagerService.clearCredentialState( 458 any(), callbackCaptor.capture(), any())) 459 .thenReturn(mock(ICancellationSignal.class)); 460 mCredentialManager.clearCredentialState(mClearRequest, null, mExecutor, callback); 461 verify(mMockCredentialManagerService).clearCredentialState(any(), any(), eq(mPackageName)); 462 463 callbackCaptor 464 .getValue() 465 .onError(ClearCredentialStateException.TYPE_UNKNOWN, "unknown error"); 466 verify(callback).onError(errorCaptor.capture()); 467 468 assertThat(errorCaptor.getValue().getType()) 469 .isEqualTo(ClearCredentialStateException.TYPE_UNKNOWN); 470 } 471 472 @Test testClearCredential_success()473 public void testClearCredential_success() throws RemoteException { 474 ArgumentCaptor<IClearCredentialStateCallback> callbackCaptor = 475 ArgumentCaptor.forClass(IClearCredentialStateCallback.class); 476 477 OutcomeReceiver<Void, ClearCredentialStateException> callback = mock(OutcomeReceiver.class); 478 479 when(mMockCredentialManagerService.clearCredentialState( 480 any(), callbackCaptor.capture(), any())) 481 .thenReturn(mock(ICancellationSignal.class)); 482 mCredentialManager.clearCredentialState(mClearRequest, null, mExecutor, callback); 483 verify(mMockCredentialManagerService).clearCredentialState(any(), any(), eq(mPackageName)); 484 485 callbackCaptor.getValue().onSuccess(); 486 verify(callback).onResult(any()); 487 } 488 489 @Test testGetCredentialProviderServices_allProviders()490 public void testGetCredentialProviderServices_allProviders() throws RemoteException { 491 verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS); 492 } 493 494 @Test testGetCredentialProviderServices_userProviders()495 public void testGetCredentialProviderServices_userProviders() throws RemoteException { 496 verifyGetCredentialProviderServices(CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY); 497 } 498 499 @Test testGetCredentialProviderServices_systemProviders()500 public void testGetCredentialProviderServices_systemProviders() throws RemoteException { 501 verifyGetCredentialProviderServices( 502 CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY); 503 } 504 505 @Test testGetCredentialProviderServicesForTesting_allProviders()506 public void testGetCredentialProviderServicesForTesting_allProviders() throws RemoteException { 507 verifyGetCredentialProviderServicesForTesting( 508 CredentialManager.PROVIDER_FILTER_ALL_PROVIDERS); 509 } 510 511 @Test testGetCredentialProviderServicesForTesting_userProviders()512 public void testGetCredentialProviderServicesForTesting_userProviders() throws RemoteException { 513 verifyGetCredentialProviderServicesForTesting( 514 CredentialManager.PROVIDER_FILTER_USER_PROVIDERS_ONLY); 515 } 516 517 @Test testGetCredentialProviderServicesForTesting_systemProviders()518 public void testGetCredentialProviderServicesForTesting_systemProviders() 519 throws RemoteException { 520 verifyGetCredentialProviderServicesForTesting( 521 CredentialManager.PROVIDER_FILTER_SYSTEM_PROVIDERS_ONLY); 522 } 523 verifyGetCredentialProviderServices(int testFilter)524 private void verifyGetCredentialProviderServices(int testFilter) throws RemoteException { 525 when(mMockCredentialManagerService.getCredentialProviderServices(TEST_USER_ID, testFilter)) 526 .thenReturn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); 527 528 List<CredentialProviderInfo> output = 529 mCredentialManager.getCredentialProviderServices(TEST_USER_ID, testFilter); 530 531 assertThat(output).containsExactlyElementsIn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); 532 } 533 verifyGetCredentialProviderServicesForTesting(int testFilter)534 private void verifyGetCredentialProviderServicesForTesting(int testFilter) 535 throws RemoteException { 536 when(mMockCredentialManagerService.getCredentialProviderServicesForTesting(testFilter)) 537 .thenReturn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); 538 539 List<CredentialProviderInfo> output = 540 mCredentialManager.getCredentialProviderServicesForTesting(testFilter); 541 542 assertThat(output).containsExactlyElementsIn(TEST_CREDENTIAL_PROVIDER_INFO_LIST); 543 } 544 545 @Test testSetEnabledProviders_nullProviders()546 public void testSetEnabledProviders_nullProviders() { 547 assertThrows( 548 NullPointerException.class, 549 () -> 550 mCredentialManager.setEnabledProviders( 551 null, null, 0, mExecutor, response -> {})); 552 } 553 554 @Test testSetEnabledProviders_nullExecutor()555 public void testSetEnabledProviders_nullExecutor() { 556 assertThrows( 557 NullPointerException.class, 558 () -> 559 mCredentialManager.setEnabledProviders( 560 List.of("foo"), List.of("foo"), 0, null, response -> {})); 561 } 562 563 @Test testSetEnabledProviders_nullCallback()564 public void testSetEnabledProviders_nullCallback() { 565 assertThrows( 566 NullPointerException.class, 567 () -> 568 mCredentialManager.setEnabledProviders( 569 List.of("foo"), List.of("foo"), 0, mExecutor, null)); 570 } 571 572 @Test testSetEnabledProviders_failed()573 public void testSetEnabledProviders_failed() throws RemoteException { 574 OutcomeReceiver<Void, SetEnabledProvidersException> callback = mock(OutcomeReceiver.class); 575 576 ArgumentCaptor<ISetEnabledProvidersCallback> callbackCaptor = 577 ArgumentCaptor.forClass(ISetEnabledProvidersCallback.class); 578 ArgumentCaptor<SetEnabledProvidersException> errorCaptor = 579 ArgumentCaptor.forClass(SetEnabledProvidersException.class); 580 581 final List<String> providers = List.of("foo", "bar"); 582 final int userId = 0; 583 mCredentialManager.setEnabledProviders(providers, providers, userId, mExecutor, callback); 584 verify(mMockCredentialManagerService) 585 .setEnabledProviders(eq(providers), eq(providers), eq(0), callbackCaptor.capture()); 586 587 final String errorType = "unknown"; 588 final String errorMessage = "Unknown error"; 589 callbackCaptor.getValue().onError(errorType, errorMessage); 590 verify(callback).onError(errorCaptor.capture()); 591 592 assertThat(errorCaptor.getValue().getType()).isEqualTo(errorType); 593 assertThat(errorCaptor.getValue().getMessage()).isEqualTo(errorMessage); 594 } 595 596 @Test testSetEnabledProviders_success()597 public void testSetEnabledProviders_success() throws RemoteException { 598 OutcomeReceiver<Void, SetEnabledProvidersException> callback = mock(OutcomeReceiver.class); 599 600 ArgumentCaptor<ISetEnabledProvidersCallback> callbackCaptor = 601 ArgumentCaptor.forClass(ISetEnabledProvidersCallback.class); 602 603 final List<String> providers = List.of("foo", "bar"); 604 final List<String> primaryProviders = List.of("foo"); 605 final int userId = 0; 606 mCredentialManager.setEnabledProviders( 607 primaryProviders, providers, userId, mExecutor, callback); 608 609 verify(mMockCredentialManagerService) 610 .setEnabledProviders( 611 eq(primaryProviders), eq(providers), eq(0), callbackCaptor.capture()); 612 613 callbackCaptor.getValue().onResponse(); 614 verify(callback).onResult(any()); 615 } 616 617 @Test testRegisterCredentialDescription_nullRequest()618 public void testRegisterCredentialDescription_nullRequest() { 619 assertThrows( 620 NullPointerException.class, 621 () -> mCredentialManager.registerCredentialDescription(null)); 622 } 623 624 @Test testRegisterCredentialDescription_success()625 public void testRegisterCredentialDescription_success() throws RemoteException { 626 mCredentialManager.registerCredentialDescription(mRegisterRequest); 627 verify(mMockCredentialManagerService) 628 .registerCredentialDescription(same(mRegisterRequest), eq(mPackageName)); 629 } 630 631 @Test testUnregisterCredentialDescription_nullRequest()632 public void testUnregisterCredentialDescription_nullRequest() { 633 assertThrows( 634 NullPointerException.class, 635 () -> mCredentialManager.unregisterCredentialDescription(null)); 636 } 637 638 @Test testUnregisterCredentialDescription_success()639 public void testUnregisterCredentialDescription_success() throws RemoteException { 640 mCredentialManager.unregisterCredentialDescription(mUnregisterRequest); 641 verify(mMockCredentialManagerService) 642 .unregisterCredentialDescription(same(mUnregisterRequest), eq(mPackageName)); 643 } 644 } 645