| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| #include "chrome/browser/ash/crosapi/payment_app_instance_ash.h" |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "ash/components/arc/test/arc_payment_app_bridge_test_support.h" |
| #include "ash/public/cpp/external_arc/overlay/test/test_arc_overlay_manager.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/test/task_environment.h" |
| #include "base/test/test_future.h" |
| #include "base/unguessable_token.h" |
| #include "chrome/test/base/testing_profile.h" |
| #include "chromeos/components/payments/mojom/payment_app.mojom.h" |
| #include "chromeos/components/payments/mojom/payment_app_types.mojom-forward.h" |
| #include "components/payments/core/android_app_description.h" |
| #include "components/services/app_service/public/cpp/instance_registry.h" |
| #include "components/services/app_service/public/cpp/instance_update.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/test/test_web_contents_factory.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "url/gurl.h" |
| |
| namespace payments { |
| namespace { |
| |
| class PaymentAppInstanceAshTest : public testing::Test { |
| public: |
| void SetUp() override { |
| payment_app_instance_ash_ = |
| std::make_unique<crosapi::PaymentAppInstanceAsh>(); |
| payment_app_instance_ash_->BindReceiver( |
| payment_app_instance_remote_.BindNewPipeAndPassReceiver()); |
| scoped_set_instance_ = support_.CreateScopedSetInstance(); |
| payment_app_instance_ash_->SetPaymentAppServiceForTesting( |
| arc::ArcPaymentAppBridge::GetForBrowserContextForTesting( |
| support_.context())); |
| payment_app_instance_ash_->SetInstanceRegistryForTesting( |
| &instance_registry_); |
| } |
| base::UnguessableToken CreateTWAInstance() { |
| aura::Window window(nullptr); |
| window.Init(ui::LAYER_NOT_DRAWN); |
| instance_registry_.CreateOrUpdateInstance( |
| apps::InstanceParams("twa_app_id", &window)); |
| base::UnguessableToken twa_instance_id; |
| instance_registry_.ForInstancesWithWindow( |
| &window, [&twa_instance_id](const apps::InstanceUpdate& update) { |
| twa_instance_id = update.InstanceId(); |
| }); |
| return twa_instance_id; |
| } |
| |
| protected: |
| arc::ArcPaymentAppBridgeTestSupport support_; |
| mojo::Remote<chromeos::payments::mojom::PaymentAppInstance> |
| payment_app_instance_remote_; |
| std::unique_ptr<crosapi::PaymentAppInstanceAsh> payment_app_instance_ash_; |
| std::unique_ptr<arc::ArcPaymentAppBridgeTestSupport::ScopedSetInstance> |
| scoped_set_instance_; |
| ash::TestArcOverlayManager overlay_manager_; |
| apps::InstanceRegistry instance_registry_; |
| }; |
| |
| TEST_F(PaymentAppInstanceAshTest, IsPaymentImplemented) { |
| EXPECT_CALL(*support_.instance(), |
| IsPaymentImplemented(testing::_, testing::_)) |
| .WillOnce([](const std::string& package_name, |
| arc::ArcPaymentAppBridge::IsPaymentImplementedCallback |
| callback) { |
| auto valid = |
| chromeos::payments::mojom::IsPaymentImplementedValidResult::New(); |
| valid->activity_names.push_back("com.example.Activity"); |
| valid->service_names.push_back("com.example.Service"); |
| std::move(callback).Run( |
| chromeos::payments::mojom::IsPaymentImplementedResult::NewValid( |
| std::move(valid))); |
| }); |
| |
| base::test::TestFuture< |
| chromeos::payments::mojom::IsPaymentImplementedResultPtr> |
| future; |
| payment_app_instance_ash_->IsPaymentImplemented("test_package_name", |
| future.GetCallback()); |
| |
| auto is_payment_implemented_result = future.Take(); |
| ASSERT_TRUE(is_payment_implemented_result); |
| ASSERT_FALSE(is_payment_implemented_result.is_null()); |
| EXPECT_FALSE(is_payment_implemented_result->is_error()); |
| ASSERT_TRUE(is_payment_implemented_result->is_valid()); |
| ASSERT_FALSE(is_payment_implemented_result->get_valid().is_null()); |
| EXPECT_EQ(std::vector<std::string>{"com.example.Activity"}, |
| is_payment_implemented_result->get_valid()->activity_names); |
| EXPECT_EQ(std::vector<std::string>{"com.example.Service"}, |
| is_payment_implemented_result->get_valid()->service_names); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, IsPaymentImplementedError) { |
| EXPECT_CALL(*support_.instance(), |
| IsPaymentImplemented(testing::_, testing::_)) |
| .WillOnce([&](const std::string& package_name, |
| crosapi::PaymentAppInstanceAsh::IsPaymentImplementedCallback |
| callback) { |
| std::move(callback).Run( |
| chromeos::payments::mojom::IsPaymentImplementedResult::NewError( |
| "Error message.")); |
| }); |
| |
| base::test::TestFuture< |
| chromeos::payments::mojom::IsPaymentImplementedResultPtr> |
| future; |
| payment_app_instance_ash_->IsPaymentImplemented("test_package_name", |
| future.GetCallback()); |
| |
| auto is_payment_implemented_result = future.Take(); |
| ASSERT_TRUE(is_payment_implemented_result); |
| ASSERT_FALSE(is_payment_implemented_result.is_null()); |
| EXPECT_FALSE(is_payment_implemented_result->is_valid()); |
| ASSERT_TRUE(is_payment_implemented_result->is_error()); |
| EXPECT_EQ("Error message.", is_payment_implemented_result->get_error()); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, IsReadyToPay) { |
| EXPECT_CALL(*support_.instance(), IsReadyToPay(testing::_, testing::_)) |
| .WillOnce( |
| [](chromeos::payments::mojom::PaymentParametersPtr parameters, |
| crosapi::PaymentAppInstanceAsh::IsReadyToPayCallback callback) { |
| std::move(callback).Run( |
| chromeos::payments::mojom::IsReadyToPayResult::NewResponse( |
| true)); |
| }); |
| |
| base::test::TestFuture<chromeos::payments::mojom::IsReadyToPayResultPtr> |
| future; |
| payment_app_instance_ash_->IsReadyToPay( |
| chromeos::payments::mojom::PaymentParameters::New(), |
| future.GetCallback()); |
| |
| auto is_ready_to_pay_result = future.Take(); |
| ASSERT_TRUE(is_ready_to_pay_result); |
| ASSERT_FALSE(is_ready_to_pay_result.is_null()); |
| EXPECT_FALSE(is_ready_to_pay_result->is_error()); |
| ASSERT_TRUE(is_ready_to_pay_result->is_response()); |
| EXPECT_TRUE(is_ready_to_pay_result->get_response()); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, IsNotReadyToPay) { |
| EXPECT_CALL(*support_.instance(), IsReadyToPay(testing::_, testing::_)) |
| .WillOnce( |
| [](chromeos::payments::mojom::PaymentParametersPtr parameters, |
| crosapi::PaymentAppInstanceAsh::IsReadyToPayCallback callback) { |
| std::move(callback).Run( |
| chromeos::payments::mojom::IsReadyToPayResult::NewResponse( |
| false)); |
| }); |
| |
| base::test::TestFuture<chromeos::payments::mojom::IsReadyToPayResultPtr> |
| future; |
| payment_app_instance_ash_->IsReadyToPay( |
| chromeos::payments::mojom::PaymentParameters::New(), |
| future.GetCallback()); |
| |
| auto is_ready_to_pay_result = future.Take(); |
| ASSERT_TRUE(is_ready_to_pay_result); |
| ASSERT_FALSE(is_ready_to_pay_result.is_null()); |
| EXPECT_FALSE(is_ready_to_pay_result->is_error()); |
| ASSERT_TRUE(is_ready_to_pay_result->is_response()); |
| EXPECT_FALSE(is_ready_to_pay_result->get_response()); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, InvokePaymentAppNoToken) { |
| base::test::TestFuture<chromeos::payments::mojom::InvokePaymentAppResultPtr> |
| future; |
| payment_app_instance_ash_->InvokePaymentApp( |
| chromeos::payments::mojom::PaymentParameters::New(), |
| future.GetCallback()); |
| |
| auto invoke_payment_app_result = future.Take(); |
| ASSERT_TRUE(invoke_payment_app_result); |
| ASSERT_FALSE(invoke_payment_app_result.is_null()); |
| EXPECT_FALSE(invoke_payment_app_result->is_valid()); |
| ASSERT_TRUE(invoke_payment_app_result->is_error()); |
| EXPECT_EQ("Unable to invoke Android apps.", |
| invoke_payment_app_result->get_error()); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, InvokePaymentAppResultOK) { |
| EXPECT_CALL(*support_.instance(), InvokePaymentApp(testing::_, testing::_)) |
| .WillOnce([](chromeos::payments::mojom::PaymentParametersPtr parameters, |
| crosapi::PaymentAppInstanceAsh::InvokePaymentAppCallback |
| callback) { |
| auto valid = |
| chromeos::payments::mojom::InvokePaymentAppValidResult::New(); |
| valid->is_activity_result_ok = true; |
| valid->stringified_details = "{}"; |
| std::move(callback).Run( |
| chromeos::payments::mojom::InvokePaymentAppResult::NewValid( |
| std::move(valid))); |
| }); |
| |
| auto params = chromeos::payments::mojom::PaymentParameters::New(); |
| params->request_token = "Abc"; |
| params->twa_instance_identifier = CreateTWAInstance(); |
| |
| base::test::TestFuture<chromeos::payments::mojom::InvokePaymentAppResultPtr> |
| future; |
| payment_app_instance_ash_->InvokePaymentApp(std::move(params), |
| future.GetCallback()); |
| |
| auto invoke_payment_app_result = future.Take(); |
| ASSERT_TRUE(invoke_payment_app_result); |
| ASSERT_FALSE(invoke_payment_app_result.is_null()); |
| EXPECT_FALSE(invoke_payment_app_result->is_error()); |
| ASSERT_TRUE(invoke_payment_app_result->is_valid()); |
| ASSERT_FALSE(invoke_payment_app_result->get_valid().is_null()); |
| EXPECT_TRUE(invoke_payment_app_result->get_valid()->is_activity_result_ok); |
| EXPECT_EQ("{}", invoke_payment_app_result->get_valid()->stringified_details); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, InvokePaymentAppError) { |
| EXPECT_CALL(*support_.instance(), InvokePaymentApp(testing::_, testing::_)) |
| .WillOnce([](chromeos::payments::mojom::PaymentParametersPtr parameters, |
| crosapi::PaymentAppInstanceAsh::InvokePaymentAppCallback |
| callback) { |
| std::move(callback).Run( |
| chromeos::payments::mojom::InvokePaymentAppResult::NewError( |
| "Error message.")); |
| }); |
| |
| auto params = chromeos::payments::mojom::PaymentParameters::New(); |
| params->request_token = "Abc"; |
| params->twa_instance_identifier = CreateTWAInstance(); |
| |
| base::test::TestFuture<chromeos::payments::mojom::InvokePaymentAppResultPtr> |
| future; |
| payment_app_instance_ash_->InvokePaymentApp(std::move(params), |
| future.GetCallback()); |
| |
| auto invoke_payment_app_result = future.Take(); |
| ASSERT_TRUE(invoke_payment_app_result); |
| ASSERT_FALSE(invoke_payment_app_result.is_null()); |
| EXPECT_FALSE(invoke_payment_app_result->is_valid()); |
| ASSERT_TRUE(invoke_payment_app_result->is_error()); |
| EXPECT_EQ("Error message.", invoke_payment_app_result->get_error()); |
| } |
| |
| TEST_F(PaymentAppInstanceAshTest, AbortPaymentAppOK) { |
| EXPECT_CALL(*support_.instance(), AbortPaymentApp(testing::_, testing::_)) |
| .WillOnce( |
| [](const std::string& request_token, |
| crosapi::PaymentAppInstanceAsh::AbortPaymentAppCallback callback) { |
| std::move(callback).Run(true); |
| }); |
| |
| base::test::TestFuture<bool> future; |
| payment_app_instance_ash_->AbortPaymentApp("some token", |
| future.GetCallback()); |
| |
| auto abort_app_result = future.Take(); |
| ASSERT_TRUE(abort_app_result); |
| } |
| |
| } // namespace |
| } // namespace payments |