Commit 4db92291 authored by Balazs Engedy's avatar Balazs Engedy Committed by Commit Bot

Add helper method to set expectations on devices for Ctap2 tests.

Otherwise, EXPECT_CALL macros tend to get ugly quickly.

Bug: None
Change-Id: I24584a7ea0d4ec324b84c7c55cf313a4407da419
Reviewed-on: https://chromium-review.googlesource.com/980533
Commit-Queue: Balazs Engedy <engedy@chromium.org>
Reviewed-by: default avatarKim Paulhamus <kpaulhamus@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545848}
parent 8cd7ca7e
......@@ -13,6 +13,7 @@
#include "device/fido/authenticator_make_credential_response.h"
#include "device/fido/ctap_make_credential_request.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_response_test_data.h"
#include "device/fido/make_credential_task.h"
#include "device/fido/mock_fido_device.h"
#include "device/fido/test_callback_receiver.h"
......@@ -76,22 +77,12 @@ MATCHER_P(IndicatesDeviceTransactWithCommand, expected, "") {
TEST_F(FidoMakeCredentialTaskTest, TestMakeCredentialSuccess) {
auto device = std::make_unique<MockFidoDevice>();
EXPECT_CALL(*device, TryWinkRef(_))
.WillRepeatedly(testing::Invoke(MockFidoDevice::WinkDoNothing));
EXPECT_CALL(*device,
DeviceTransactPtr(
IndicatesDeviceTransactWithCommand(base::strict_cast<uint8_t>(
CtapRequestCommand::kAuthenticatorGetInfo)),
_))
.WillOnce(testing::Invoke(MockFidoDevice::NoErrorGetInfo));
EXPECT_CALL(*device,
DeviceTransactPtr(
IndicatesDeviceTransactWithCommand(base::strict_cast<uint8_t>(
CtapRequestCommand::kAuthenticatorMakeCredential)),
_))
.WillOnce(testing::Invoke(MockFidoDevice::NoErrorMakeCredential));
device->ExpectCtap2CommandAndRespondWith(
CtapRequestCommand::kAuthenticatorGetInfo,
test_data::kTestAuthenticatorGetInfoResponse);
device->ExpectCtap2CommandAndRespondWith(
CtapRequestCommand::kAuthenticatorMakeCredential,
test_data::kTestMakeCredentialResponse);
const auto task = CreateMakeCredentialTask(device.get());
make_credential_callback_receiver().WaitForCallback();
......@@ -106,14 +97,8 @@ TEST_F(FidoMakeCredentialTaskTest, TestMakeCredentialSuccess) {
TEST_F(FidoMakeCredentialTaskTest, TestIncorrectAuthenticatorGetInfoResponse) {
auto device = std::make_unique<MockFidoDevice>();
EXPECT_CALL(*device, TryWinkRef(_))
.WillRepeatedly(testing::Invoke(MockFidoDevice::WinkDoNothing));
EXPECT_CALL(*device,
DeviceTransactPtr(
IndicatesDeviceTransactWithCommand(base::strict_cast<uint8_t>(
CtapRequestCommand::kAuthenticatorGetInfo)),
_))
.WillOnce(testing::Invoke(MockFidoDevice::CtapDeviceError));
device->ExpectCtap2CommandAndRespondWith(
CtapRequestCommand::kAuthenticatorGetInfo, base::nullopt);
const auto task = CreateMakeCredentialTask(device.get());
make_credential_callback_receiver().WaitForCallback();
......
......@@ -6,12 +6,20 @@
#include <utility>
#include "base/bind.h"
#include "base/location.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/apdu/apdu_response.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_response_test_data.h"
#include "device/fido/u2f_parsing_utils.h"
namespace device {
MATCHER_P(IsCtap2Command, expected_command, "") {
return !arg.empty() && (arg[0] == static_cast<uint8_t>(expected_command));
}
MockFidoDevice::MockFidoDevice() : weak_factory_(this) {}
MockFidoDevice::~MockFidoDevice() = default;
......@@ -114,6 +122,23 @@ void MockFidoDevice::WinkDoNothing(WinkCallback& cb) {
std::move(cb).Run();
}
void MockFidoDevice::ExpectWinkedAtLeastOnce() {
EXPECT_CALL(*this, TryWinkRef(::testing::_)).Times(::testing::AtLeast(1));
}
void MockFidoDevice::ExpectCtap2CommandAndRespondWith(
CtapRequestCommand command,
base::Optional<base::span<const uint8_t>> response,
base::TimeDelta delay) {
auto data = u2f_parsing_utils::MaterializeOrNull(response);
auto send_response = [ data(std::move(data)), delay ](DeviceCallback & cb) {
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, base::BindOnce(std::move(cb), std::move(data)), delay);
};
EXPECT_CALL(*this, DeviceTransactPtr(IsCtap2Command(command), ::testing::_))
.WillOnce(::testing::WithArg<1>(::testing::Invoke(send_response)));
}
base::WeakPtr<FidoDevice> MockFidoDevice::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
......
......@@ -11,7 +11,11 @@
#include <vector>
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "device/fido/fido_constants.h"
#include "device/fido/fido_device.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -22,7 +26,6 @@ class MockFidoDevice : public FidoDevice {
MockFidoDevice();
~MockFidoDevice() override;
// GMock cannot mock a method taking a move-only type.
// TODO(crbug.com/729950): Remove these workarounds once support for move-only
// types is added to GMock.
MOCK_METHOD1(TryWinkRef, void(WinkCallback& cb));
......@@ -36,7 +39,8 @@ class MockFidoDevice : public FidoDevice {
void(const std::vector<uint8_t>& command, DeviceCallback& cb));
void DeviceTransact(std::vector<uint8_t> command, DeviceCallback cb) override;
base::WeakPtr<FidoDevice> GetWeakPtr() override;
// Old interface ------------------------------------------------------------
static void NotSatisfied(const std::vector<uint8_t>& command,
DeviceCallback& cb);
static void WrongData(const std::vector<uint8_t>& command,
......@@ -57,6 +61,16 @@ class MockFidoDevice : public FidoDevice {
DeviceCallback& cb);
static void WinkDoNothing(WinkCallback& cb);
// New interface ------------------------------------------------------------
void ExpectWinkedAtLeastOnce();
void ExpectCtap2CommandAndRespondWith(
CtapRequestCommand command,
base::Optional<base::span<const uint8_t>> response,
base::TimeDelta delay = base::TimeDelta());
base::WeakPtr<FidoDevice> GetWeakPtr() override;
private:
base::WeakPtrFactory<FidoDevice> weak_factory_;
......
......@@ -17,6 +17,13 @@ std::vector<uint8_t> Materialize(base::span<const uint8_t> span) {
return std::vector<uint8_t>(span.begin(), span.end());
}
base::Optional<std::vector<uint8_t>> MaterializeOrNull(
base::Optional<base::span<const uint8_t>> span) {
if (span)
return Materialize(*span);
return base::nullopt;
}
void Append(std::vector<uint8_t>* target, base::span<const uint8_t> in_values) {
target->insert(target->end(), in_values.begin(), in_values.end());
}
......
......@@ -11,6 +11,7 @@
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/optional.h"
namespace device {
namespace u2f_parsing_utils {
......@@ -23,9 +24,13 @@ COMPONENT_EXPORT(DEVICE_FIDO)
extern const uint32_t kU2fResponseKeyHandleStartPos;
COMPONENT_EXPORT(DEVICE_FIDO) extern const char kEs256[];
// Returns copy of |span|, that is, a vector with the same elements.
// Returns a materialized copy of |span|, that is, a vector with the same
// elements.
COMPONENT_EXPORT(DEVICE_FIDO)
std::vector<uint8_t> Materialize(base::span<const uint8_t> span);
COMPONENT_EXPORT(DEVICE_FIDO)
base::Optional<std::vector<uint8_t>> MaterializeOrNull(
base::Optional<base::span<const uint8_t>> span);
// Appends |in_values| to the end of |target|. The underlying container for
// |in_values| should *not* be |target|.
......
......@@ -27,6 +27,14 @@ TEST(U2fParsingUtils, Materialize) {
::testing::ElementsAreArray(kOneTwoThree));
}
TEST(U2fParsingUtils, MaterializeOrNull) {
auto result = MaterializeOrNull(kOneTwoThree);
ASSERT_TRUE(result.has_value());
EXPECT_THAT(*result, ::testing::ElementsAreArray(kOneTwoThree));
EXPECT_EQ(MaterializeOrNull(base::nullopt), base::nullopt);
}
TEST(U2fParsingUtils, Append) {
std::vector<uint8_t> target;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment