blob: 5fbda46b984fe5610a5daeba93441503f39b0081 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.localauth;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Activity;
import android.content.Context;
import androidx.biometric.BiometricManager;
import androidx.lifecycle.Lifecycle;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.dart.DartExecutor;
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import java.util.ArrayList;
import java.util.Collections;
import org.junit.Test;
public class LocalAuthTest {
@Test
public void isDeviceSupportedReturnsFalse() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
plugin.onMethodCall(new MethodCall("isDeviceSupported", null), mockResult);
verify(mockResult).success(false);
}
@Test
public void deviceSupportsBiometrics_returnsTrueForPresentNonEnrolledBiometrics() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate())
.thenReturn(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("deviceSupportsBiometrics", null), mockResult);
verify(mockResult).success(true);
}
@Test
public void deviceSupportsBiometrics_returnsTrueForPresentEnrolledBiometrics() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate()).thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("deviceSupportsBiometrics", null), mockResult);
verify(mockResult).success(true);
}
@Test
public void deviceSupportsBiometrics_returnsFalseForNoBiometricHardware() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate())
.thenReturn(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("deviceSupportsBiometrics", null), mockResult);
verify(mockResult).success(false);
}
@Test
public void deviceSupportsBiometrics_returnsFalseForNullBiometricManager() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
plugin.setBiometricManager(null);
plugin.onMethodCall(new MethodCall("deviceSupportsBiometrics", null), mockResult);
verify(mockResult).success(false);
}
@Test
public void onDetachedFromActivity_ShouldReleaseActivity() {
final Activity mockActivity = mock(Activity.class);
final ActivityPluginBinding mockActivityBinding = mock(ActivityPluginBinding.class);
when(mockActivityBinding.getActivity()).thenReturn(mockActivity);
Context mockContext = mock(Context.class);
when(mockActivity.getBaseContext()).thenReturn(mockContext);
final HiddenLifecycleReference mockLifecycleReference = mock(HiddenLifecycleReference.class);
when(mockActivityBinding.getLifecycle()).thenReturn(mockLifecycleReference);
final Lifecycle mockLifecycle = mock(Lifecycle.class);
when(mockLifecycleReference.getLifecycle()).thenReturn(mockLifecycle);
final FlutterPluginBinding mockPluginBinding = mock(FlutterPluginBinding.class);
final FlutterEngine mockFlutterEngine = mock(FlutterEngine.class);
when(mockPluginBinding.getFlutterEngine()).thenReturn(mockFlutterEngine);
DartExecutor mockDartExecutor = mock(DartExecutor.class);
when(mockFlutterEngine.getDartExecutor()).thenReturn(mockDartExecutor);
final LocalAuthPlugin plugin = new LocalAuthPlugin();
plugin.onAttachedToEngine(mockPluginBinding);
plugin.onAttachedToActivity(mockActivityBinding);
assertNotNull(plugin.getActivity());
plugin.onDetachedFromActivity();
assertNull(plugin.getActivity());
}
@Test
public void getEnrolledBiometrics_shouldReturnError_whenNoActivity() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
plugin.onMethodCall(new MethodCall("getEnrolledBiometrics", null), mockResult);
verify(mockResult)
.error("no_activity", "local_auth plugin requires a foreground activity", null);
}
@Test
public void getEnrolledBiometrics_shouldReturnError_whenFinishingActivity() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final Activity mockActivity = buildMockActivity();
when(mockActivity.isFinishing()).thenReturn(true);
setPluginActivity(plugin, mockActivity);
plugin.onMethodCall(new MethodCall("getEnrolledBiometrics", null), mockResult);
verify(mockResult)
.error("no_activity", "local_auth plugin requires a foreground activity", null);
}
@Test
public void getEnrolledBiometrics_shouldReturnEmptyList_withoutHardwarePresent() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
setPluginActivity(plugin, buildMockActivity());
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate(anyInt()))
.thenReturn(BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("getEnrolledBiometrics", null), mockResult);
verify(mockResult).success(Collections.emptyList());
}
@Test
public void getEnrolledBiometrics_shouldReturnEmptyList_withNoMethodsEnrolled() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
setPluginActivity(plugin, buildMockActivity());
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate(anyInt()))
.thenReturn(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("getEnrolledBiometrics", null), mockResult);
verify(mockResult).success(Collections.emptyList());
}
@Test
public void getEnrolledBiometrics_shouldOnlyAddEnrolledBiometrics() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
setPluginActivity(plugin, buildMockActivity());
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK))
.thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG))
.thenReturn(BiometricManager.BIOMETRIC_ERROR_NONE_ENROLLED);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("getEnrolledBiometrics", null), mockResult);
verify(mockResult)
.success(
new ArrayList<String>() {
{
add("weak");
}
});
}
@Test
public void getEnrolledBiometrics_shouldAddStrongBiometrics() {
final LocalAuthPlugin plugin = new LocalAuthPlugin();
setPluginActivity(plugin, buildMockActivity());
final MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
final BiometricManager mockBiometricManager = mock(BiometricManager.class);
when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK))
.thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
when(mockBiometricManager.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_STRONG))
.thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
plugin.setBiometricManager(mockBiometricManager);
plugin.onMethodCall(new MethodCall("getEnrolledBiometrics", null), mockResult);
verify(mockResult)
.success(
new ArrayList<String>() {
{
add("weak");
add("strong");
}
});
}
private Activity buildMockActivity() {
final Activity mockActivity = mock(Activity.class);
final Context mockContext = mock(Context.class);
when(mockActivity.getBaseContext()).thenReturn(mockContext);
when(mockActivity.getApplicationContext()).thenReturn(mockContext);
return mockActivity;
}
private void setPluginActivity(LocalAuthPlugin plugin, Activity activity) {
final HiddenLifecycleReference mockLifecycleReference = mock(HiddenLifecycleReference.class);
final FlutterPluginBinding mockPluginBinding = mock(FlutterPluginBinding.class);
final ActivityPluginBinding mockActivityBinding = mock(ActivityPluginBinding.class);
final FlutterEngine mockFlutterEngine = mock(FlutterEngine.class);
final DartExecutor mockDartExecutor = mock(DartExecutor.class);
when(mockPluginBinding.getFlutterEngine()).thenReturn(mockFlutterEngine);
when(mockFlutterEngine.getDartExecutor()).thenReturn(mockDartExecutor);
when(mockActivityBinding.getActivity()).thenReturn(activity);
when(mockActivityBinding.getLifecycle()).thenReturn(mockLifecycleReference);
plugin.onAttachedToEngine(mockPluginBinding);
plugin.onAttachedToActivity(mockActivityBinding);
}
}