#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <utility>
#include <vector>
#include "base/check.h"
#include "base/containers/flat_set.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/test/task_environment.h"
#include "base/test/test_future.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/test/mock_bluetooth_adapter.h"
#include "device/fido/fake_fido_discovery.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_device.h"
#include "device/fido/fido_device_authenticator.h"
#include "device/fido/fido_request_handler_base.h"
#include "device/fido/fido_task.h"
#include "device/fido/fido_test_data.h"
#include "device/fido/fido_transport_protocol.h"
#include "device/fido/fido_types.h"
#include "device/fido/mock_fido_device.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_WIN)
#include "device/fido/win/fake_webauthn_api.h"
#include "device/fido/win/webauthn_api.h"
#endif
_;
namespace device {
namespace {
FakeTaskCallback;
FakeHandlerFuture;
enum class FakeTaskResponse : uint8_t { … };
class EmptyRequestHandler : public FidoRequestHandlerBase { … };
class TestObserver : public FidoRequestHandlerBase::Observer { … };
class FakeFidoTask : public FidoTask { … };
class FakeFidoRequestHandler : public FidoRequestHandlerBase { … };
std::vector<uint8_t> CreateFakeSuccessDeviceResponse() { … }
std::vector<uint8_t> CreateFakeUserPresenceVerifiedError() { … }
std::vector<uint8_t> CreateFakeDeviceProcesssingError() { … }
std::vector<uint8_t> CreateFakeOperationDeniedError() { … }
}
class FidoRequestHandlerTest : public ::testing::Test { … };
TEST_F(FidoRequestHandlerTest, TestSingleDeviceSuccess) { … }
TEST_F(FidoRequestHandlerTest, TestAuthenticatorHandlerReset) { … }
TEST_F(FidoRequestHandlerTest, TestRequestWithMultipleDevices) { … }
TEST_F(FidoRequestHandlerTest, TestRequestWithMultipleSuccessResponses) { … }
TEST_F(FidoRequestHandlerTest, TestRequestWithMultipleFailureResponses) { … }
TEST_F(FidoRequestHandlerTest,
TestRequestWithOperationDeniedErrorInternalTransport) { … }
TEST_F(FidoRequestHandlerTest,
TestRequestWithOperationDeniedErrorCrossPlatform) { … }
TEST_F(FidoRequestHandlerTest, TestWithPlatformAuthenticator) { … }
TEST_F(FidoRequestHandlerTest, InternalTransportDisallowedIfMarkedUnavailable) { … }
TEST_F(FidoRequestHandlerTest,
TransportAvailabilityNotificationOnObserverSetLate) { … }
TEST_F(FidoRequestHandlerTest, TestWithMultiplePlatformAuthenticators) { … }
#if BUILDFLAG(IS_WIN)
TEST_F(FidoRequestHandlerTest, TransportAvailabilityOfWindowsAuthenticator) {
static const struct {
bool api_available = false;
bool is_uvpaa = false;
} kTestCases[] = {
{true, true},
{true, false},
{false, false},
};
FakeWinWebAuthnApi api;
device::WinWebAuthnApi::ScopedOverride win_webauthn_api_override(&api);
for (const auto& test_case : kTestCases) {
SCOPED_TRACE(::testing::Message()
<< "api_available=" << test_case.api_available);
SCOPED_TRACE(::testing::Message() << "is_uvpaa=" << test_case.is_uvpaa);
api.set_available(test_case.api_available);
api.set_is_uvpaa(test_case.is_uvpaa);
TestObserver observer;
ForgeNextHidDiscovery();
fake_discovery_factory_.set_discover_win_webauthn_api_authenticator(true);
EmptyRequestHandler request_handler(
{FidoTransportProtocol::kUsbHumanInterfaceDevice},
&fake_discovery_factory_);
request_handler.set_observer(&observer);
if (!test_case.api_available) {
discovery()->WaitForCallToStartAndSimulateSuccess();
}
auto transport_availability_info =
observer.WaitForTransportAvailabilityInfo();
EXPECT_EQ(transport_availability_info.available_transports.empty(),
test_case.api_available);
EXPECT_EQ(transport_availability_info.has_win_native_api_authenticator,
test_case.api_available);
EXPECT_EQ(transport_availability_info.win_is_uvpaa, test_case.is_uvpaa);
}
}
#endif
}