blob: 8f1109ad13415c1f073f7dcf901119334465e9e3 [file] [log] [blame]
// Copyright 2020 The Chromium 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 "components/payments/content/android_app_communication.h"
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/callback.h"
#include "components/payments/content/android_app_communication_test_support.h"
#include "components/payments/core/android_app_description.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/test_web_contents_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
namespace payments {
namespace {
std::vector<std::unique_ptr<AndroidAppDescription>> createApp(
const std::vector<std::string>& activity_names,
const std::string& default_payment_method,
const std::vector<std::string>& service_names) {
auto app = std::make_unique<AndroidAppDescription>();
for (const auto& activity_name : activity_names) {
auto activity = std::make_unique<AndroidActivityDescription>();
activity->name = activity_name;
activity->default_payment_method = default_payment_method;
app->activities.emplace_back(std::move(activity));
}
app->package = "com.example.app";
app->service_names = service_names;
std::vector<std::unique_ptr<AndroidAppDescription>> apps;
apps.emplace_back(std::move(app));
return apps;
}
class AndroidAppCommunicationTest : public testing::Test {
public:
AndroidAppCommunicationTest()
: support_(AndroidAppCommunicationTestSupport::Create()),
web_contents_(
web_contents_factory_.CreateWebContents(support_->context())) {}
~AndroidAppCommunicationTest() override = default;
AndroidAppCommunicationTest(const AndroidAppCommunicationTest& other) =
delete;
AndroidAppCommunicationTest& operator=(
const AndroidAppCommunicationTest& other) = delete;
void OnGetAppDescriptionsResponse(
const absl::optional<std::string>& error,
std::vector<std::unique_ptr<AndroidAppDescription>> apps) {
error_ = error;
apps_ = std::move(apps);
}
void OnIsReadyToPayResponse(const absl::optional<std::string>& error,
bool is_ready_to_pay) {
error_ = error;
is_ready_to_pay_ = is_ready_to_pay;
}
void OnPaymentAppResponse(const absl::optional<std::string>& error,
bool is_activity_result_ok,
const std::string& payment_method_identifier,
const std::string& stringified_details) {
error_ = error;
is_activity_result_ok_ = is_activity_result_ok;
payment_method_identifier_ = payment_method_identifier;
stringified_details_ = stringified_details;
}
std::unique_ptr<AndroidAppCommunicationTestSupport> support_;
content::TestWebContentsFactory web_contents_factory_;
content::WebContents* web_contents_;
absl::optional<std::string> error_;
std::vector<std::unique_ptr<AndroidAppDescription>> apps_;
bool is_ready_to_pay_ = false;
bool is_activity_result_ok_ = false;
std::string payment_method_identifier_;
std::string stringified_details_;
};
TEST_F(AndroidAppCommunicationTest, OneInstancePerBrowserContext) {
auto communication_one =
AndroidAppCommunication::GetForBrowserContext(support_->context());
auto communication_two =
AndroidAppCommunication::GetForBrowserContext(support_->context());
EXPECT_EQ(communication_one.get(), communication_two.get());
}
TEST_F(AndroidAppCommunicationTest, NoArcForGetAppDescriptions) {
// Intentionally do not set an instance.
support_->ExpectNoListOfPaymentAppsQuery();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
"com.example.app",
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
} else {
EXPECT_FALSE(error_.has_value());
}
EXPECT_TRUE(apps_.empty());
}
TEST_F(AndroidAppCommunicationTest, NoAppDescriptions) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryListOfPaymentAppsAndRespond({});
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
"com.example.app",
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
EXPECT_FALSE(error_.has_value());
EXPECT_TRUE(apps_.empty());
}
TEST_F(AndroidAppCommunicationTest, TwoActivitiesInPackage) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryListOfPaymentAppsAndRespond(
createApp({"com.example.app.ActivityOne", "com.example.app.ActivityTwo"},
"https://play.google.com/billing", {}));
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
"com.example.app",
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ(
"Found more than one PAY activity in the Trusted Web Activity, but at "
"most one activity is supported.",
error_.value());
} else {
EXPECT_FALSE(error_.has_value());
}
EXPECT_TRUE(apps_.empty());
}
TEST_F(AndroidAppCommunicationTest, TwoServicesInPackage) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryListOfPaymentAppsAndRespond(
createApp({"com.example.app.Activity"}, "https://play.google.com/billing",
{"com.example.app.ServiceOne", "com.example.app.ServiceTwo"}));
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
"com.example.app",
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
EXPECT_FALSE(error_.has_value());
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
ASSERT_EQ(1u, apps_.size());
ASSERT_NE(nullptr, apps_.front().get());
EXPECT_EQ("com.example.app", apps_.front()->package);
// The logic for checking for multiple services is cross-platform in
// android_payment_app_factory.cc, so the platform-specific implementations
// of android_app_communication.h do not check for this error condition.
std::vector<std::string> expected_service_names = {
"com.example.app.ServiceOne", "com.example.app.ServiceTwo"};
EXPECT_EQ(expected_service_names, apps_.front()->service_names);
ASSERT_EQ(1u, apps_.front()->activities.size());
ASSERT_NE(nullptr, apps_.front()->activities.front().get());
EXPECT_EQ("com.example.app.Activity",
apps_.front()->activities.front()->name);
EXPECT_EQ("https://play.google.com/billing",
apps_.front()->activities.front()->default_payment_method);
} else {
EXPECT_TRUE(apps_.empty());
}
}
TEST_F(AndroidAppCommunicationTest, ActivityAndService) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryListOfPaymentAppsAndRespond(
createApp({"com.example.app.Activity"}, "https://play.google.com/billing",
{"com.example.app.Service"}));
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
"com.example.app",
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
EXPECT_FALSE(error_.has_value());
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
ASSERT_EQ(1u, apps_.size());
ASSERT_NE(nullptr, apps_.front().get());
EXPECT_EQ("com.example.app", apps_.front()->package);
EXPECT_EQ(std::vector<std::string>{"com.example.app.Service"},
apps_.front()->service_names);
ASSERT_EQ(1u, apps_.front()->activities.size());
ASSERT_NE(nullptr, apps_.front()->activities.front().get());
EXPECT_EQ("com.example.app.Activity",
apps_.front()->activities.front()->name);
EXPECT_EQ("https://play.google.com/billing",
apps_.front()->activities.front()->default_payment_method);
} else {
EXPECT_TRUE(apps_.empty());
}
}
TEST_F(AndroidAppCommunicationTest, OnlyActivity) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryListOfPaymentAppsAndRespond(createApp(
{"com.example.app.Activity"}, "https://play.google.com/billing", {}));
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
"com.example.app",
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
EXPECT_FALSE(error_.has_value());
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
ASSERT_EQ(1u, apps_.size());
ASSERT_NE(nullptr, apps_.front().get());
EXPECT_EQ("com.example.app", apps_.front()->package);
EXPECT_TRUE(apps_.front()->service_names.empty());
ASSERT_EQ(1u, apps_.front()->activities.size());
ASSERT_NE(nullptr, apps_.front()->activities.front().get());
EXPECT_EQ("com.example.app.Activity",
apps_.front()->activities.front()->name);
EXPECT_EQ("https://play.google.com/billing",
apps_.front()->activities.front()->default_payment_method);
} else {
EXPECT_TRUE(apps_.empty());
}
}
TEST_F(AndroidAppCommunicationTest, OutsideOfTwa) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectNoListOfPaymentAppsQuery();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
communication->GetAppDescriptions(
/*twa_package_name=*/"", // Empty string means this is not TWA.
base::BindOnce(&AndroidAppCommunicationTest::OnGetAppDescriptionsResponse,
base::Unretained(this)));
EXPECT_FALSE(error_.has_value());
EXPECT_TRUE(apps_.empty());
}
TEST_F(AndroidAppCommunicationTest, NoArcForIsReadyToPay) {
// Intentionally do not set an instance.
support_->ExpectNoIsReadyToPayQuery();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert("{}");
communication->IsReadyToPay(
"com.example.app", "com.example.app.Service", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
base::BindOnce(&AndroidAppCommunicationTest::OnIsReadyToPayResponse,
base::Unretained(this)));
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
EXPECT_FALSE(is_ready_to_pay_);
}
TEST_F(AndroidAppCommunicationTest, TwaIsReadyToPayOnlyWithPlayBilling) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectNoIsReadyToPayQuery();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://example.com"].insert("{}");
communication->IsReadyToPay(
"com.example.app", "com.example.app.Service", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
base::BindOnce(&AndroidAppCommunicationTest::OnIsReadyToPayResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
EXPECT_FALSE(is_ready_to_pay_);
}
TEST_F(AndroidAppCommunicationTest, MoreThanOnePaymentMethodDataNotReadyToPay) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectNoIsReadyToPayQuery();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert(
"{\"product_id\": \"1\"}");
stringified_method_data["https://play.google.com/billing"].insert(
"{\"product_id\": \"2\"}");
communication->IsReadyToPay(
"com.example.app", "com.example.app.Service", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
base::BindOnce(&AndroidAppCommunicationTest::OnIsReadyToPayResponse,
base::Unretained(this)));
ASSERT_TRUE(error_.has_value());
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_EQ("At most one payment method specific data is supported.",
error_.value());
} else {
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
EXPECT_FALSE(is_ready_to_pay_);
}
TEST_F(AndroidAppCommunicationTest, EmptyMethodDataIsReadyToPay) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryIsReadyToPayAndRespond(true);
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data.insert(std::make_pair(
"https://play.google.com/billing", std::set<std::string>()));
communication->IsReadyToPay(
"com.example.app", "com.example.app.Service", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
base::BindOnce(&AndroidAppCommunicationTest::OnIsReadyToPayResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
EXPECT_TRUE(is_ready_to_pay_);
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
EXPECT_FALSE(is_ready_to_pay_);
}
}
TEST_F(AndroidAppCommunicationTest, NotReadyToPay) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryIsReadyToPayAndRespond(false);
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert("{}");
communication->IsReadyToPay(
"com.example.app", "com.example.app.Service", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
base::BindOnce(&AndroidAppCommunicationTest::OnIsReadyToPayResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
EXPECT_FALSE(is_ready_to_pay_);
}
TEST_F(AndroidAppCommunicationTest, ReadyToPay) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectQueryIsReadyToPayAndRespond(true);
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert("{}");
communication->IsReadyToPay(
"com.example.app", "com.example.app.Service", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
base::BindOnce(&AndroidAppCommunicationTest::OnIsReadyToPayResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
EXPECT_TRUE(is_ready_to_pay_);
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
EXPECT_FALSE(is_ready_to_pay_);
}
}
TEST_F(AndroidAppCommunicationTest, NoArcForInvokePaymentApp) {
// Intentionally do not set an instance.
support_->ExpectNoPaymentAppInvoke();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert("{}");
communication->InvokePaymentApp(
"com.example.app", "com.example.app.Activity", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
web_contents_,
base::BindOnce(&AndroidAppCommunicationTest::OnPaymentAppResponse,
base::Unretained(this)));
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
EXPECT_FALSE(is_activity_result_ok_);
EXPECT_TRUE(payment_method_identifier_.empty());
EXPECT_EQ("{}", stringified_details_);
}
TEST_F(AndroidAppCommunicationTest, TwaPaymentOnlyWithPlayBilling) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectNoPaymentAppInvoke();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://example.com"].insert("{}");
communication->InvokePaymentApp(
"com.example.app", "com.example.app.Activity", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
web_contents_,
base::BindOnce(&AndroidAppCommunicationTest::OnPaymentAppResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
EXPECT_FALSE(is_activity_result_ok_);
EXPECT_TRUE(payment_method_identifier_.empty());
EXPECT_EQ("{}", stringified_details_);
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
}
TEST_F(AndroidAppCommunicationTest, NoPaymentWithMoreThanOnePaymentMethodData) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectNoPaymentAppInvoke();
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert(
"{\"product_id\": \"1\"}");
stringified_method_data["https://play.google.com/billing"].insert(
"{\"product_id\": \"2\"}");
communication->InvokePaymentApp(
"com.example.app", "com.example.app.Activity", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
web_contents_,
base::BindOnce(&AndroidAppCommunicationTest::OnPaymentAppResponse,
base::Unretained(this)));
EXPECT_FALSE(is_activity_result_ok_);
EXPECT_EQ("{}", stringified_details_);
EXPECT_TRUE(payment_method_identifier_.empty());
ASSERT_TRUE(error_.has_value());
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_EQ("At most one payment method specific data is supported.",
error_.value());
} else {
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
}
TEST_F(AndroidAppCommunicationTest, PaymentWithEmptyMethodData) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectInvokePaymentAppAndRespond(
/*is_activity_result_ok=*/true,
/*payment_method_identifier=*/"https://play.google.com/billing",
/*stringified_details*/ "{\"status\": \"ok\"}");
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data.insert(std::make_pair(
"https://play.google.com/billing", std::set<std::string>()));
communication->InvokePaymentApp(
"com.example.app", "com.example.app.Activity", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
web_contents_,
base::BindOnce(&AndroidAppCommunicationTest::OnPaymentAppResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
EXPECT_TRUE(is_activity_result_ok_);
EXPECT_EQ("https://play.google.com/billing", payment_method_identifier_);
EXPECT_EQ("{\"status\": \"ok\"}", stringified_details_);
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
}
TEST_F(AndroidAppCommunicationTest, UserCancelInvokePaymentApp) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectInvokePaymentAppAndRespond(
/*is_activity_result_ok=*/false,
/*payment_method_identifier=*/"https://play.google.com/billing",
/*stringified_details*/ "{}");
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert("{}");
communication->InvokePaymentApp(
"com.example.app", "com.example.app.Activity", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
web_contents_,
base::BindOnce(&AndroidAppCommunicationTest::OnPaymentAppResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
EXPECT_FALSE(is_activity_result_ok_);
EXPECT_EQ("https://play.google.com/billing", payment_method_identifier_);
EXPECT_EQ("{}", stringified_details_);
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
}
TEST_F(AndroidAppCommunicationTest, UserConfirmInvokePaymentApp) {
auto scoped_initialization = support_->CreateScopedInitialization();
support_->ExpectInvokePaymentAppAndRespond(
/*is_activity_result_ok=*/true,
/*payment_method_identifier=*/"https://play.google.com/billing",
/*stringified_details*/ "{\"status\": \"ok\"}");
auto communication =
AndroidAppCommunication::GetForBrowserContext(support_->context());
communication->SetForTesting();
std::map<std::string, std::set<std::string>> stringified_method_data;
stringified_method_data["https://play.google.com/billing"].insert("{}");
communication->InvokePaymentApp(
"com.example.app", "com.example.app.Activity", stringified_method_data,
GURL("https://top-level-origin.com"),
GURL("https://payment-request-origin.com"), "payment-request-id",
web_contents_,
base::BindOnce(&AndroidAppCommunicationTest::OnPaymentAppResponse,
base::Unretained(this)));
if (support_->AreAndroidAppsSupportedOnThisPlatform()) {
EXPECT_FALSE(error_.has_value());
EXPECT_TRUE(is_activity_result_ok_);
EXPECT_EQ("https://play.google.com/billing", payment_method_identifier_);
EXPECT_EQ("{\"status\": \"ok\"}", stringified_details_);
} else {
ASSERT_TRUE(error_.has_value());
EXPECT_EQ("Unable to invoke Android apps.", error_.value());
}
}
} // namespace
} // namespace payments