// Copyright 2017 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/service_worker_payment_app_factory.h"

#include <algorithm>
#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/permissions/permission_request_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_data_service_factory.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/remoting/remote_test_helper.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/payments/content/payment_manifest_web_data_service.h"
#include "components/payments/core/features.h"
#include "components/payments/core/test_payment_manifest_downloader.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_request_context_getter.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace payments {
namespace {

static const char kDefaultScope[] = "/app1/";

}  // namespace

// Tests for the service worker payment app factory.
class ServiceWorkerPaymentAppFactoryBrowserTest : public InProcessBrowserTest {
 public:
  ServiceWorkerPaymentAppFactoryBrowserTest()
      : alicepay_(net::EmbeddedTestServer::TYPE_HTTPS),
        bobpay_(net::EmbeddedTestServer::TYPE_HTTPS),
        frankpay_(net::EmbeddedTestServer::TYPE_HTTPS),
        georgepay_(net::EmbeddedTestServer::TYPE_HTTPS),
        kylepay_(net::EmbeddedTestServer::TYPE_HTTPS),
        larrypay_(net::EmbeddedTestServer::TYPE_HTTPS),
        charlie_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        david_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        frank_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        george_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        harry_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        ike_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        john_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        kyle_example_(net::EmbeddedTestServer::TYPE_HTTPS),
        larry_example_(net::EmbeddedTestServer::TYPE_HTTPS) {
    scoped_feature_list_.InitWithFeatures(
        {::features::kServiceWorkerPaymentApps,
         features::kWebPaymentsJustInTimePaymentApp},
        {});
  }

  ~ServiceWorkerPaymentAppFactoryBrowserTest() override {}

  void SetUpCommandLine(base::CommandLine* command_line) override {
    // HTTPS server only serves a valid cert for localhost, so this is needed to
    // load pages from the test servers with custom hostnames without an
    // interstitial.
    command_line->AppendSwitch(switches::kIgnoreCertificateErrors);
  }

  PermissionRequestManager* GetPermissionRequestManager() {
    return PermissionRequestManager::FromWebContents(
        browser()->tab_strip_model()->GetActiveWebContents());
  }

  // Starts the test severs and opens a test page on alicepay.com.
  void SetUpOnMainThread() override {
    ASSERT_TRUE(StartTestServer("alicepay.com", &alicepay_));
    ASSERT_TRUE(StartTestServer("bobpay.com", &bobpay_));
    ASSERT_TRUE(StartTestServer("frankpay.com", &frankpay_));
    ASSERT_TRUE(StartTestServer("georgepay.com", &georgepay_));
    ASSERT_TRUE(StartTestServer("kylepay.com", &kylepay_));
    ASSERT_TRUE(StartTestServer("larrypay.com", &larrypay_));
    ASSERT_TRUE(StartTestServer("charlie.example.com", &charlie_example_));
    ASSERT_TRUE(StartTestServer("david.example.com", &david_example_));
    ASSERT_TRUE(StartTestServer("frank.example.com", &frank_example_));
    ASSERT_TRUE(StartTestServer("george.example.com", &george_example_));
    ASSERT_TRUE(StartTestServer("harry.example.com", &harry_example_));
    ASSERT_TRUE(StartTestServer("ike.example.com", &ike_example_));
    ASSERT_TRUE(StartTestServer("john.example.com", &john_example_));
    ASSERT_TRUE(StartTestServer("kyle.example.com", &kyle_example_));
    ASSERT_TRUE(StartTestServer("larry.example.com", &larry_example_));

    GetPermissionRequestManager()->set_auto_response_for_test(
        PermissionRequestManager::ACCEPT_ALL);
  }

  // Invokes the JavaScript function install(|method_name|) in
  // components/test/data/payments/alicepay.com/app1/index.js, which responds
  // back via domAutomationController.
  void InstallPaymentAppForMethod(const std::string& method_name) {
    InstallPaymentAppInScopeForMethod(kDefaultScope, method_name);
  }

  // Invokes the JavaScript function install(|method_name|) in
  // components/test/data/payments/alicepay.com|scope|index.js, which responds
  // back via domAutomationController.
  void InstallPaymentAppInScopeForMethod(const std::string& scope,
                                         const std::string& method_name) {
    ui_test_utils::NavigateToURL(browser(),
                                 alicepay_.GetURL("alicepay.com", scope));
    std::string contents;
    std::string script = "install('" + method_name + "');";
    ASSERT_TRUE(content::ExecuteScriptAndExtractString(
        browser()->tab_strip_model()->GetActiveWebContents(), script,
        &contents))
        << "Script execution failed: " << script;
    ASSERT_NE(std::string::npos,
              contents.find("Payment app for \"" + method_name +
                            "\" method installed."))
        << method_name << " method install message not found in:\n"
        << contents;
  }

  // Retrieves all valid payment apps that can handle the methods in
  // |payment_method_identifiers_set|. Blocks until the factory has finished
  // using all resources.
  void GetAllPaymentAppsForMethods(
      const std::vector<std::string>& payment_method_identifiers) {
    content::WebContents* web_contents =
        browser()->tab_strip_model()->GetActiveWebContents();
    content::BrowserContext* context = web_contents->GetBrowserContext();
    auto downloader = std::make_unique<TestDownloader>(
        content::BrowserContext::GetDefaultStoragePartition(context)
            ->GetURLLoaderFactoryForBrowserProcess());
    downloader->AddTestServerURL("https://alicepay.com/",
                                 alicepay_.GetURL("alicepay.com", "/"));
    downloader->AddTestServerURL("https://bobpay.com/",
                                 bobpay_.GetURL("bobpay.com", "/"));
    downloader->AddTestServerURL("https://frankpay.com/",
                                 frankpay_.GetURL("frankpay.com", "/"));
    downloader->AddTestServerURL("https://georgepay.com/",
                                 georgepay_.GetURL("georgepay.com", "/"));
    downloader->AddTestServerURL("https://kylepay.com/",
                                 kylepay_.GetURL("kylepay.com", "/"));
    downloader->AddTestServerURL("https://larrypay.com/",
                                 larrypay_.GetURL("larrypay.com", "/"));
    downloader->AddTestServerURL(
        "https://charlie.example.com/",
        charlie_example_.GetURL("charlie.example.com", "/"));
    downloader->AddTestServerURL(
        "https://david.example.com/",
        david_example_.GetURL("david.example.com", "/"));
    downloader->AddTestServerURL(
        "https://frank.example.com/",
        frank_example_.GetURL("frank.example.com", "/"));
    downloader->AddTestServerURL(
        "https://george.example.com/",
        george_example_.GetURL("george.example.com", "/"));
    downloader->AddTestServerURL(
        "https://harry.example.com/",
        harry_example_.GetURL("harry.example.com", "/"));
    downloader->AddTestServerURL("https://ike.example.com/",
                                 ike_example_.GetURL("ike.example.com", "/"));
    downloader->AddTestServerURL("https://john.example.com/",
                                 john_example_.GetURL("john.example.com", "/"));
    downloader->AddTestServerURL("https://kyle.example.com/",
                                 kyle_example_.GetURL("kyle.example.com", "/"));
    downloader->AddTestServerURL(
        "https://larry.example.com/",
        larry_example_.GetURL("larry.example.com", "/"));
    ServiceWorkerPaymentAppFactory::GetInstance()
        ->SetDownloaderAndIgnorePortInOriginComparisonForTesting(
            std::move(downloader));

    std::vector<mojom::PaymentMethodDataPtr> method_data;
    for (const auto& identifier : payment_method_identifiers) {
      method_data.emplace_back(mojom::PaymentMethodData::New());
      method_data.back()->supported_method = identifier;
    }

    base::RunLoop run_loop;
    ServiceWorkerPaymentAppFactory::GetInstance()->GetAllPaymentApps(
        web_contents,
        WebDataServiceFactory::GetPaymentManifestWebDataForProfile(
            Profile::FromBrowserContext(context),
            ServiceAccessType::EXPLICIT_ACCESS),
        method_data,
        /*may_crawl_for_installable_payment_apps=*/true,
        base::BindOnce(
            &ServiceWorkerPaymentAppFactoryBrowserTest::OnGotAllPaymentApps,
            base::Unretained(this)),
        run_loop.QuitClosure());
    run_loop.Run();
  }

  // Returns the installed apps that have been found in
  // GetAllPaymentAppsForMethods().
  const content::PaymentAppProvider::PaymentApps& apps() const { return apps_; }

  // Returns the installable apps that have been found in
  // GetAllPaymentAppsForMethods().
  const ServiceWorkerPaymentAppFactory::InstallablePaymentApps&
  installable_apps() const {
    return installable_apps_;
  }

  // Expects that the first app has the |expected_method|.
  void ExpectPaymentAppWithMethod(const std::string& expected_method) {
    ExpectPaymentAppFromScopeWithMethod(kDefaultScope, expected_method);
  }

  // Expects that the app from |scope| has the |expected_method|.
  void ExpectPaymentAppFromScopeWithMethod(const std::string& scope,
                                           const std::string& expected_method) {
    ASSERT_FALSE(apps().empty());
    content::StoredPaymentApp* app = nullptr;
    for (const auto& it : apps()) {
      if (it.second->scope.path() == scope) {
        app = it.second.get();
        break;
      }
    }
    ASSERT_NE(nullptr, app) << "No app found in scope " << scope;
    EXPECT_TRUE(base::ContainsValue(app->enabled_methods, expected_method))
        << "Unable to find payment method " << expected_method
        << " in the list of enabled methods for the app installed from "
        << app->scope;
  }

  // Expects an installable payment app in |scope|. The |scope| is also the
  // payment method.
  void ExpectInstallablePaymentAppInScope(const std::string& scope) {
    ASSERT_FALSE(installable_apps().empty());
    WebAppInstallationInfo* app = nullptr;
    for (const auto& it : installable_apps()) {
      if (it.second->sw_scope == scope) {
        app = it.second.get();
        break;
      }
    }
    ASSERT_NE(nullptr, app) << "No installable app found in scope " << scope;
  }

 private:
  // Called by the factory upon completed app lookup. These |apps| have only
  // valid payment methods.
  void OnGotAllPaymentApps(
      content::PaymentAppProvider::PaymentApps apps,
      ServiceWorkerPaymentAppFactory::InstallablePaymentApps installable_apps) {
    apps_ = std::move(apps);
    installable_apps_ = std::move(installable_apps);
  }

  // Starts the |test_server| for |hostname|. Returns true on success.
  bool StartTestServer(const std::string& hostname,
                       net::EmbeddedTestServer* test_server) {
    host_resolver()->AddRule(hostname, "127.0.0.1");
    if (!test_server->InitializeAndListen())
      return false;
    test_server->ServeFilesFromSourceDirectory(
        "components/test/data/payments/" + hostname);
    test_server->StartAcceptingConnections();
    return true;
  }

  // https://alicepay.com hosts the payment app.
  net::EmbeddedTestServer alicepay_;

  // https://bobpay.com/webpay does not permit any other origin to use this
  // payment method.
  net::EmbeddedTestServer bobpay_;

  // https://frankpay.com/webpay supports payment apps from any origin.
  net::EmbeddedTestServer frankpay_;

  // https://georgepay.com/webpay supports payment apps only from
  // https://alicepay.com.
  net::EmbeddedTestServer georgepay_;

  // https://kylepay.com hosts a payment handler that can be installed "just in
  // time."
  net::EmbeddedTestServer kylepay_;

  // https://larrypay.com/webpay cross-site redirects to
  // https://kylepay.com/webpay.
  net::EmbeddedTestServer larrypay_;

  // https://charlie.example.com/webpay same-site redirects to
  // https://david.example.com/webpay.
  net::EmbeddedTestServer charlie_example_;

  // https://david.example.com/webpay same-site redirects to
  // https://frank.example.com/webpay.
  net::EmbeddedTestServer david_example_;

  // https://frank.example.com/webpay same-site redirects to
  // https://george.example.com/webpay.
  net::EmbeddedTestServer frank_example_;

  // https://george.example.com/webpay same-site redirects to
  // https://harry.example.com/webpay.
  net::EmbeddedTestServer george_example_;

  // https://harry.example.com/webpay hosts a payment handler that can be
  // installed "just in time."
  net::EmbeddedTestServer harry_example_;

  // https://ike.example.com/webpay has a cross-origin HTTP Link header to
  // https://harry.example.com/payment-manifest.json.
  net::EmbeddedTestServer ike_example_;

  // https://john.example.com/payment-method.json has a cross-origin default
  // application https://harry.example.com/app.json.
  net::EmbeddedTestServer john_example_;

  // https://kyle.example.com/app.json has a cross-origin service worker
  // https://harry.example.com/app.js.
  net::EmbeddedTestServer kyle_example_;

  // https://larry.example.com/app.json has a cross-origin service worker scope
  // https://harry.example.com/webpay/.
  net::EmbeddedTestServer larry_example_;

  // The installed apps that have been found by the factory in
  // GetAllPaymentAppsForMethods() method.
  content::PaymentAppProvider::PaymentApps apps_;

  // The installable apps that have been found by the factory in
  // GetAllPaymentAppsForMethods() method.
  ServiceWorkerPaymentAppFactory::InstallablePaymentApps installable_apps_;

  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(ServiceWorkerPaymentAppFactoryBrowserTest);
};

// A payment app has to be installed first.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest, NoApps) {
  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    EXPECT_TRUE(apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    EXPECT_TRUE(apps().empty());
  }
}

// Unknown payment method names are not permitted.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       UnknownMethod) {
  InstallPaymentAppForMethod("unknown-payment-method");

  {
    GetAllPaymentAppsForMethods({"unknown-payment-method", "basic-card",
                                 "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    EXPECT_TRUE(apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"unknown-payment-method", "basic-card",
                                 "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    EXPECT_TRUE(apps().empty());
  }
}

// A payment app can use "basic-card" payment method.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest, BasicCard) {
  InstallPaymentAppForMethod("basic-card");

  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("basic-card");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("basic-card");
  }
}

// A payment app can use any payment method name from its own origin.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest, OwnOrigin) {
  InstallPaymentAppForMethod("https://alicepay.com/webpay");

  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("https://alicepay.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("https://alicepay.com/webpay");
  }
}

// A payment app from https://alicepay.com cannot use the payment method
// https://bobpay.com/webpay, because https://bobpay.com/payment-method.json
// does not have an entry for "supported_origins".
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       NotSupportedOrigin) {
  InstallPaymentAppForMethod("https://bobpay.com/webpay");

  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    EXPECT_TRUE(apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"basic-card", "https://alicepay.com/webpay",
                                 "https://bobpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    EXPECT_TRUE(apps().empty());
  }
}

// A payment app from https://alicepay.com can use the payment method
// https://frankpay.com/webpay, because https://frankpay.com/payment-method.json
// specifies "supported_origins": "*" (all origins supported).
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       AllOringsSupported) {
  InstallPaymentAppForMethod("https://frankpay.com/webpay");

  {
    GetAllPaymentAppsForMethods({"https://frankpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("https://frankpay.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://frankpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("https://frankpay.com/webpay");
  }
}

// A payment app from https://alicepay.com can use the payment method
// https://georgepay.com/webpay, because
// https://georgepay.com/payment-method.json explicitly includes
// "https://alicepay.com" as one of the "supported_origins".
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       SupportedOrigin) {
  InstallPaymentAppForMethod("https://georgepay.com/webpay");

  {
    GetAllPaymentAppsForMethods({"https://georgepay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("https://georgepay.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://georgepay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(1U, apps().size());
    ExpectPaymentAppWithMethod("https://georgepay.com/webpay");
  }
}

// Multiple payment apps from https://alicepay.com can use the payment method
// https://georgepay.com/webpay at the same time, because
// https://georgepay.com/payment-method.json explicitly includes
// "https://alicepay.com" as on of the "supported_origins".
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       TwoAppsSameMethod) {
  InstallPaymentAppInScopeForMethod("/app1/", "https://georgepay.com/webpay");
  InstallPaymentAppInScopeForMethod("/app2/", "https://georgepay.com/webpay");

  {
    GetAllPaymentAppsForMethods({"https://georgepay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(2U, apps().size());
    ExpectPaymentAppFromScopeWithMethod("/app1/",
                                        "https://georgepay.com/webpay");
    ExpectPaymentAppFromScopeWithMethod("/app2/",
                                        "https://georgepay.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://georgepay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(2U, apps().size());
    ExpectPaymentAppFromScopeWithMethod("/app1/",
                                        "https://georgepay.com/webpay");
    ExpectPaymentAppFromScopeWithMethod("/app2/",
                                        "https://georgepay.com/webpay");
  }
}

// Multiple payment apps from https://alicepay.com can use either
// https://georgepay.com/webpay or https://frankepay.com/webpay payment method,
// because https://frankpay.com/payment-method.json specifies
// "supported_origins": "*" (all origins supported) and
// https://georgepay.com/payment-method.json explicitly includes
// "https://alicepay.com" as on of the "supported_origins".
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       TwoAppsDifferentMethods) {
  InstallPaymentAppInScopeForMethod("/app1/", "https://georgepay.com/webpay");
  InstallPaymentAppInScopeForMethod("/app2/", "https://frankpay.com/webpay");

  {
    GetAllPaymentAppsForMethods(
        {"https://georgepay.com/webpay", "https://frankpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(2U, apps().size());
    ExpectPaymentAppFromScopeWithMethod("/app1/",
                                        "https://georgepay.com/webpay");
    ExpectPaymentAppFromScopeWithMethod("/app2/",
                                        "https://frankpay.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods(
        {"https://georgepay.com/webpay", "https://frankpay.com/webpay"});

    EXPECT_TRUE(installable_apps().empty());
    ASSERT_EQ(2U, apps().size());
    ExpectPaymentAppFromScopeWithMethod("/app1/",
                                        "https://georgepay.com/webpay");
    ExpectPaymentAppFromScopeWithMethod("/app2/",
                                        "https://frankpay.com/webpay");
  }
}

// The payment method https://kylepay.com/webpay does not require explicit
// installation, because the webapp manifest https://kylepay.com/app.json
// includes enough information for just in time installation of the service
// worker https://kylepay.com/app.js with scope https://kylepay.com/webpay.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       InstallablePaymentApp) {
  {
    GetAllPaymentAppsForMethods({"https://kylepay.com/webpay"});

    EXPECT_TRUE(apps().empty());
    ASSERT_EQ(1U, installable_apps().size());
    ExpectInstallablePaymentAppInScope("https://kylepay.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://kylepay.com/webpay"});

    EXPECT_TRUE(apps().empty());
    ASSERT_EQ(1U, installable_apps().size());
    ExpectInstallablePaymentAppInScope("https://kylepay.com/webpay");
  }
}

// The payment method https://larrypay.com/webpay is not valid, because it
// redirects to a different site (https://kylepay.com/webpay).
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       InvalidDifferentSiteRedirect) {
  {
    GetAllPaymentAppsForMethods({"https://larrypay.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://larrypay.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }
}

// The payment method https://charlie.example.com/webpay is not valid, because
// it redirects 4 times (charlie -> david -> frank -> george -> harry).
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       FourRedirectsIsNotValid) {
  {
    GetAllPaymentAppsForMethods({"https://charlie.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://charlie.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }
}

// The payment method https://david.example.com/webpay is valid, because it
// redirects 3 times (david -> frank -> george -> harry).
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       ThreeRedirectsIsValid) {
  {
    GetAllPaymentAppsForMethods({"https://david.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    ASSERT_EQ(1U, installable_apps().size());
    ExpectInstallablePaymentAppInScope("https://harry.example.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://david.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    ASSERT_EQ(1U, installable_apps().size());
    ExpectInstallablePaymentAppInScope("https://harry.example.com/webpay");
  }
}

// The payment method https://george.example.com/webpay is valid, because it
// redirects once (george -> harry).
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       OneRedirectIsValid) {
  {
    GetAllPaymentAppsForMethods({"https://george.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    ASSERT_EQ(1U, installable_apps().size());
    ExpectInstallablePaymentAppInScope("https://harry.example.com/webpay");
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://george.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    ASSERT_EQ(1U, installable_apps().size());
    ExpectInstallablePaymentAppInScope("https://harry.example.com/webpay");
  }
}

// The payment method https://ike.example.com/webpay is not valid, because of
// its cross-origin HTTP Link to
// https://harry.example.com/payment-manifest.json.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       CrossOriginHttpLinkHeaderIsInvalid) {
  {
    GetAllPaymentAppsForMethods({"https://ike.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://ike.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }
}

// The payment method https://john.example.com/webpay is not valid, because of
// its cross-origin default application https://harry.example.com/app.json.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       CrossOriginDefaultApplicationIsInvalid) {
  {
    GetAllPaymentAppsForMethods({"https://john.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://john.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }
}

// The payment method https://kyle.example.com/webpay is not valid, because of
// its cross-origin service worker location https://harry.example.com/app.js.
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       CrossOriginServiceWorkerIsInvalid) {
  {
    GetAllPaymentAppsForMethods({"https://kyle.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://kyle.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }
}

// The payment method https://larry.example.com/webpay is not valid, because of
// its cross-origin service worker scope https://harry.example.com/webpay/".
IN_PROC_BROWSER_TEST_F(ServiceWorkerPaymentAppFactoryBrowserTest,
                       CrossOriginServiceWorkerScopeIsInvalid) {
  {
    GetAllPaymentAppsForMethods({"https://larry.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }

  // Repeat lookups should have identical results.
  {
    GetAllPaymentAppsForMethods({"https://larry.example.com/webpay"});

    EXPECT_TRUE(apps().empty());
    EXPECT_TRUE(installable_apps().empty());
  }
}

}  // namespace payments
