RealWhorlwind extends Whorlwind { @Override public Observable<ReadResult> read(@NonNull String name) { return Observable.create(new FingerprintAuthOnSubscribe(fingerprintManager, storage, name, readerScanning, dataLock, this)); } RealWhorlwind(Context context, FingerprintManager fingerprintManager, Storage storage,
      String keyAlias, KeyStore keyStore, KeyPairGenerator keyGenerator, KeyFactory keyFactory); @Override boolean canStoreSecurely(); @Override Completable write(@NonNull final String name, @Nullable final ByteString value); @Override Observable<ReadResult> read(@NonNull String name);  }
@Test public void readThrowsOnSubscribeWhenCannotStoreSecurely() { shadowContext.grantPermissions(USE_FINGERPRINT); when(fingerprintManager.isHardwareDetected()).thenReturn(true); when(fingerprintManager.hasEnrolledFingerprints()).thenReturn(true); Observable<ReadResult> read = whorlwind.read("a"); shadowContext.denyPermissions(USE_FINGERPRINT); try { read.blockingForEach(new Consumer<ReadResult>() { @Override public void accept(ReadResult readResult) throws Exception { fail(); } }); fail(); } catch (IllegalStateException expected) { assertThat(expected).hasMessage( "Can't store securely. Check canStoreSecurely() before attempting to read/write."); } verifyZeroInteractions(storage); }
@Ignore @Test public void immediateUnsubscribeShouldntCallAuthenticate() throws UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException, IOException { Key key = mock(Key.class); shadowContext.grantPermissions(USE_FINGERPRINT); when(fingerprintManager.isHardwareDetected()).thenReturn(true); when(fingerprintManager.hasEnrolledFingerprints()).thenReturn(true); when(keyStore.getKey("test", null)).thenReturn(key); Observable<ReadResult> read = whorlwind.read("test").take(1); ReadResult readResult = read.blockingSingle(); assertEquals(ReadResult.ReadState.NEEDS_AUTH, readResult.readState); verify(fingerprintManager, never()).authenticate(any(FingerprintManager.CryptoObject.class), any(CancellationSignal.class), anyInt(), any(FingerprintManager.AuthenticationCallback.class), any(Handler.class)); }