| // Copyright 2020 The Chromium OS 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 <functional> |
| #include <memory> |
| #include <utility> |
| |
| #include <base/test/bind.h> |
| #include <chromeos/dbus/service_constants.h> |
| #include <dbus/bus.h> |
| #include <dbus/mock_bus.h> |
| #include <dbus/mock_object_proxy.h> |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "biod/biod_proxy/biometrics_manager_proxy_base.h" |
| |
| namespace biod { |
| |
| using testing::_; |
| using testing::ByMove; |
| using testing::Return; |
| |
| class BiometricsManagerProxyBaseTest : public testing::Test { |
| public: |
| BiometricsManagerProxyBaseTest() { |
| dbus::Bus::Options options; |
| options.bus_type = dbus::Bus::SYSTEM; |
| mock_bus_ = base::MakeRefCounted<dbus::MockBus>(options); |
| |
| mock_object_proxy_ = base::MakeRefCounted<dbus::MockObjectProxy>( |
| mock_bus_.get(), kBiodServiceName, dbus::ObjectPath(kBiodServicePath)); |
| |
| // Set an expectation so that the MockBus will return our mock proxy. |
| EXPECT_CALL(*mock_bus_, GetObjectProxy(kBiodServiceName, |
| dbus::ObjectPath(kBiodServicePath))) |
| .WillOnce(Return(mock_object_proxy_.get())); |
| |
| proxy_base_ = BiometricsManagerProxyBase::Create( |
| mock_bus_.get(), dbus::ObjectPath(kBiodServicePath)); |
| } |
| |
| void CallFinish(bool success) { proxy_base_->OnFinish(success); } |
| |
| void CallOnSignalConnected(bool success) { |
| proxy_base_->OnSignalConnected("unused interface", "unused signal", |
| success); |
| } |
| |
| void CallOnSessionFailed() { proxy_base_->OnSessionFailed(nullptr); } |
| |
| dbus::ObjectProxy* GetBiodAuthSession() { |
| return proxy_base_->biod_auth_session_; |
| } |
| |
| std::unique_ptr<BiometricsManagerProxyBase> proxy_base_; |
| scoped_refptr<dbus::MockObjectProxy> mock_object_proxy_; |
| scoped_refptr<dbus::MockBus> mock_bus_; |
| bool status_ = false; |
| }; |
| |
| namespace { |
| |
| // Test that we can install and exercise a custom finish handler. |
| TEST_F(BiometricsManagerProxyBaseTest, RunFinishHandlerWithTrue) { |
| status_ = false; |
| proxy_base_->SetFinishHandler( |
| base::BindLambdaForTesting([this](bool success) { status_ = success; })); |
| CallFinish(true); |
| EXPECT_TRUE(status_); |
| } |
| |
| // Test that we can install and exercise a custom finish handler. |
| TEST_F(BiometricsManagerProxyBaseTest, RunFinishHandlerWithFalse) { |
| status_ = true; |
| proxy_base_->SetFinishHandler( |
| base::BindLambdaForTesting([this](bool success) { status_ = success; })); |
| CallFinish(false); |
| EXPECT_FALSE(status_); |
| } |
| |
| // Test that StartAuthSession returns nullptr if no dbus response. |
| TEST_F(BiometricsManagerProxyBaseTest, StartAuthSessionNoResponse) { |
| EXPECT_CALL(*mock_object_proxy_, CallMethodAndBlock) |
| .WillOnce(Return(ByMove(dbus::Response::CreateEmpty()))); |
| EXPECT_FALSE(proxy_base_->StartAuthSession()); |
| EXPECT_EQ(GetBiodAuthSession(), nullptr); |
| } |
| |
| // Test that StartAuthSession succeeds and the object proxy saved by |
| // StartAuthSession is what the mock provides. |
| TEST_F(BiometricsManagerProxyBaseTest, StartAuthSessionGetSessionProxy) { |
| // The path must be correctly formatted for the writer to accept it. |
| const dbus::ObjectPath auth_session_path("/org/chromium/Foo/AuthSession"); |
| auto fake_response = dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(fake_response.get()); |
| writer.AppendObjectPath(auth_session_path); |
| |
| auto auth_session_proxy = base::MakeRefCounted<dbus::MockObjectProxy>( |
| mock_bus_.get(), kBiodServiceName, auth_session_path); |
| |
| // Set the underlying mock proxy to return our fake_response, and set the |
| // mock bus to return the predefined ObjectProxy once it sees that path, |
| // which the class under test will extract from the fake_response. |
| EXPECT_CALL(*mock_object_proxy_, CallMethodAndBlock) |
| .WillOnce(Return(ByMove(std::move(fake_response)))); |
| EXPECT_CALL(*mock_bus_, GetObjectProxy(kBiodServiceName, auth_session_path)) |
| .WillOnce(Return(auth_session_proxy.get())); |
| |
| EXPECT_TRUE(proxy_base_->StartAuthSession()); |
| EXPECT_EQ(GetBiodAuthSession(), auth_session_proxy.get()); |
| } |
| |
| // Test that StartAuthSessionAsync succeeds and the object proxy saved by |
| // StartAuthSession is what the mock provides. |
| TEST_F(BiometricsManagerProxyBaseTest, StartAuthSessionGetSessionProxyAsync) { |
| // The path must be correctly formatted for the writer to accept it. |
| const dbus::ObjectPath auth_session_path("/org/chromium/Foo/AuthSession"); |
| auto auth_session_proxy = base::MakeRefCounted<dbus::MockObjectProxy>( |
| mock_bus_.get(), kBiodServiceName, auth_session_path); |
| // Set the underlying |mock_object_proxy_| to invoke the dbus callback (in |
| // this case OnStartAuthSessionResp) with a fake response containing |
| // |auth_session_path|. |
| auto ExecuteCallbackWithFakeResponse = |
| [auth_session_path]( |
| dbus::MethodCall* unused_method, int unused_ms, |
| base::OnceCallback<void(dbus::Response*)>* dbus_callback) { |
| std::unique_ptr<dbus::Response> fake_response = |
| dbus::Response::CreateEmpty(); |
| dbus::MessageWriter writer(fake_response.get()); |
| writer.AppendObjectPath(auth_session_path); |
| std::move(*dbus_callback).Run(fake_response.get()); |
| }; |
| EXPECT_CALL(*mock_object_proxy_, DoCallMethod(_, _, _)) |
| .WillOnce(ExecuteCallbackWithFakeResponse); |
| // Once OnStartAuthSessionResp is invoked with the fake response, it extracts |
| // |auth_session_path| from the fake response and asks |mock_bus_| for the |
| // corresponding ObjectProxy, which we set to be |auth_session_proxy|. |
| // If OnStartAuthSessionResp is unable to extract the correct ObjectPath, the |
| // bus will not return the correct ObjectProxy, which we catch in the end. |
| EXPECT_CALL(*mock_bus_, GetObjectProxy(kBiodServiceName, auth_session_path)) |
| .WillOnce(Return(auth_session_proxy.get())); |
| |
| status_ = false; |
| // Install a lambda as the client callback and verify it is run. |
| proxy_base_->StartAuthSessionAsync( |
| base::BindLambdaForTesting([this](bool success) { status_ = success; })); |
| EXPECT_TRUE(status_); |
| EXPECT_EQ(GetBiodAuthSession(), auth_session_proxy.get()); |
| } |
| |
| // Test that OnSessionFailed will call on_finish_ with false |
| TEST_F(BiometricsManagerProxyBaseTest, OnSessionFailed) { |
| status_ = true; |
| proxy_base_->SetFinishHandler( |
| base::BindLambdaForTesting([this](bool success) { status_ = success; })); |
| CallOnSessionFailed(); |
| EXPECT_FALSE(status_); |
| } |
| |
| // Test that OnSignalConnected if failed will call on_finish_ with false |
| TEST_F(BiometricsManagerProxyBaseTest, OnSignalConnectFailed) { |
| status_ = true; |
| proxy_base_->SetFinishHandler( |
| base::BindLambdaForTesting([this](bool success) { status_ = success; })); |
| CallOnSignalConnected(false); |
| EXPECT_FALSE(status_); |
| } |
| |
| } // namespace |
| } // namespace biod |