blob: 3828b05eef076f58263a4ac5993b2dd6ecfd5877 [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.
#include "include/local_auth_windows/local_auth_plugin.h"
#include <flutter/method_call.h>
#include <flutter/method_result_functions.h>
#include <flutter/standard_method_codec.h>
#include <flutter/texture_registrar.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <windows.h>
#include <functional>
#include <memory>
#include <string>
#include "mocks.h"
namespace local_auth_windows {
namespace test {
using flutter::EncodableList;
using flutter::EncodableMap;
using flutter::EncodableValue;
using ::testing::_;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::Eq;
using ::testing::Pointee;
using ::testing::Return;
TEST(LocalAuthPlugin, IsDeviceSupportedHandlerSuccessIfVerifierAvailable) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
EXPECT_CALL(*mockConsentVerifier, CheckAvailabilityAsync)
.Times(1)
.WillOnce([]() -> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability> {
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability::Available;
});
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(0);
EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(true))));
plugin.HandleMethodCall(
flutter::MethodCall("isDeviceSupported",
std::make_unique<EncodableValue>()),
std::move(result));
}
TEST(LocalAuthPlugin, IsDeviceSupportedHandlerSuccessIfVerifierNotAvailable) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
EXPECT_CALL(*mockConsentVerifier, CheckAvailabilityAsync)
.Times(1)
.WillOnce([]() -> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability> {
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability::DeviceNotPresent;
});
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(0);
EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(false))));
plugin.HandleMethodCall(
flutter::MethodCall("isDeviceSupported",
std::make_unique<EncodableValue>()),
std::move(result));
}
TEST(LocalAuthPlugin,
GetEnrolledBiometricsHandlerReturnEmptyListIfVerifierNotAvailable) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
EXPECT_CALL(*mockConsentVerifier, CheckAvailabilityAsync)
.Times(1)
.WillOnce([]() -> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability> {
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability::DeviceNotPresent;
});
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(0);
EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableList())));
plugin.HandleMethodCall(
flutter::MethodCall("getEnrolledBiometrics",
std::make_unique<EncodableValue>()),
std::move(result));
}
TEST(LocalAuthPlugin,
GetEnrolledBiometricsHandlerReturnNonEmptyListIfVerifierAvailable) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
EXPECT_CALL(*mockConsentVerifier, CheckAvailabilityAsync)
.Times(1)
.WillOnce([]() -> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability> {
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability::Available;
});
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(0);
EXPECT_CALL(*result,
SuccessInternal(Pointee(EncodableList(
{EncodableValue("weak"), EncodableValue("strong")}))));
plugin.HandleMethodCall(
flutter::MethodCall("getEnrolledBiometrics",
std::make_unique<EncodableValue>()),
std::move(result));
}
TEST(LocalAuthPlugin, AuthenticateHandlerDoesNotSupportBiometricOnly) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(1);
EXPECT_CALL(*result, SuccessInternal).Times(0);
std::unique_ptr<EncodableValue> args =
std::make_unique<EncodableValue>(EncodableMap({
{"localizedReason", EncodableValue("My Reason")},
{"biometricOnly", EncodableValue(true)},
}));
plugin.HandleMethodCall(flutter::MethodCall("authenticate", std::move(args)),
std::move(result));
}
TEST(LocalAuthPlugin, AuthenticateHandlerWorksWhenAuthorized) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
EXPECT_CALL(*mockConsentVerifier, CheckAvailabilityAsync)
.Times(1)
.WillOnce([]() -> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability> {
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability::Available;
});
EXPECT_CALL(*mockConsentVerifier, RequestVerificationForWindowAsync)
.Times(1)
.WillOnce([](std::wstring localizedReason)
-> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerificationResult> {
EXPECT_EQ(localizedReason, L"My Reason");
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerificationResult::Verified;
});
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(0);
EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(true))));
std::unique_ptr<EncodableValue> args =
std::make_unique<EncodableValue>(EncodableMap({
{"localizedReason", EncodableValue("My Reason")},
{"biometricOnly", EncodableValue(false)},
}));
plugin.HandleMethodCall(flutter::MethodCall("authenticate", std::move(args)),
std::move(result));
}
TEST(LocalAuthPlugin, AuthenticateHandlerWorksWhenNotAuthorized) {
std::unique_ptr<MockMethodResult> result =
std::make_unique<MockMethodResult>();
std::unique_ptr<MockUserConsentVerifier> mockConsentVerifier =
std::make_unique<MockUserConsentVerifier>();
EXPECT_CALL(*mockConsentVerifier, CheckAvailabilityAsync)
.Times(1)
.WillOnce([]() -> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability> {
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerifierAvailability::Available;
});
EXPECT_CALL(*mockConsentVerifier, RequestVerificationForWindowAsync)
.Times(1)
.WillOnce([](std::wstring localizedReason)
-> winrt::Windows::Foundation::IAsyncOperation<
winrt::Windows::Security::Credentials::UI::
UserConsentVerificationResult> {
EXPECT_EQ(localizedReason, L"My Reason");
co_return winrt::Windows::Security::Credentials::UI::
UserConsentVerificationResult::Canceled;
});
LocalAuthPlugin plugin(std::move(mockConsentVerifier));
EXPECT_CALL(*result, ErrorInternal).Times(0);
EXPECT_CALL(*result, SuccessInternal(Pointee(EncodableValue(false))));
std::unique_ptr<EncodableValue> args =
std::make_unique<EncodableValue>(EncodableMap({
{"localizedReason", EncodableValue("My Reason")},
{"biometricOnly", EncodableValue(false)},
}));
plugin.HandleMethodCall(flutter::MethodCall("authenticate", std::move(args)),
std::move(result));
}
} // namespace test
} // namespace local_auth_windows