blob: 8015de602fe1da4579a51025df901cc9b1dd291a [file] [log] [blame]
// 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/ui/url_identity.h"
#include <string_view>
#include "chrome/common/chrome_features.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/testing_profile.h"
#include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/ui/web_applications/test/isolated_web_app_test_utils.h"
#include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_builder.h"
#include "chrome/browser/web_applications/isolated_web_apps/test/test_signed_web_bundle_builder.h"
#include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
#include "chrome/browser/web_applications/test/web_app_test_utils.h"
#include "components/webapps/common/web_app_id.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_builder.h"
#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
using Type = UrlIdentity::Type;
using DefaultFormatOptions = UrlIdentity::DefaultFormatOptions;
using FormatOptions = UrlIdentity::FormatOptions;
using TypeSet = UrlIdentity::TypeSet;
using testing::Eq;
using testing::Field;
namespace {
struct TestCase {
GURL url;
TypeSet allowed_types;
FormatOptions options;
UrlIdentity expected_result;
};
constexpr std::string_view kTestExtensionId =
"0264075e-fd33-4a20-8484-b834afb0333d";
constexpr std::string_view kTestIsolatedWebAppName = "Test IWA Name";
const web_package::SignedWebBundleId kTestIsolatedWebAppId =
web_app::test::GetDefaultEd25519WebBundleId();
const std::string kTestIsolatedWebAppUrl =
base::StrCat({chrome::kIsolatedAppScheme, url::kStandardSchemeSeparator,
kTestIsolatedWebAppId.id()});
} // namespace
class UrlIdentityTest : public testing::Test {
protected:
void SetUp() override {
#if BUILDFLAG(ENABLE_EXTENSIONS)
InstallIsolatedWebApp();
InstallExtension();
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
void InstallIsolatedWebApp() {
web_app::test::AwaitStartWebAppProviderAndSubsystems(&testing_profile_);
const std::unique_ptr<web_app::ScopedBundledIsolatedWebApp> bundle =
web_app::IsolatedWebAppBuilder(
web_app::ManifestBuilder().SetName(kTestIsolatedWebAppName))
.BuildBundle(kTestIsolatedWebAppId,
{web_app::test::GetDefaultEd25519KeyPair()});
bundle->FakeInstallPageState(&testing_profile_);
bundle->TrustSigningKey();
bundle->InstallChecked(&testing_profile_);
}
void InstallExtension() {
std::string extension_id(kTestExtensionId);
auto extension = extensions::ExtensionBuilder("Test Extension 1")
.SetID(extension_id)
.Build();
extensions::ExtensionRegistry* extension_registry =
extensions::ExtensionRegistry::Get(profile());
extension_registry->AddEnabled(extension);
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
Profile* profile() { return &testing_profile_; }
private:
content::BrowserTaskEnvironment task_environment_;
TestingProfile testing_profile_;
#if BUILDFLAG(ENABLE_EXTENSIONS)
data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
#endif
};
TEST_F(UrlIdentityTest, AllowlistedTypesAreAllowed) {
std::string extension_id(kTestExtensionId);
std::vector<TestCase> test_cases = {
{GURL("http://example.com"),
{Type::kDefault},
{},
{
.type = Type::kDefault,
.name = u"http://example.com",
}},
#if BUILDFLAG(ENABLE_EXTENSIONS)
{GURL(kTestIsolatedWebAppUrl),
{Type::kIsolatedWebApp},
{},
{
.type = Type::kIsolatedWebApp,
.name = u"Test IWA Name",
}},
{extensions::Extension::GetBaseURLFromExtensionId(extension_id),
{Type::kChromeExtension},
{},
{
.type = Type::kChromeExtension,
.name = u"Test Extension 1",
}},
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
{GURL("file:///tmp/index.html"),
{Type::kFile},
{},
{
.type = Type::kFile,
.name = u"file:///tmp/index.html",
}},
};
for (const auto& test_case : test_cases) {
UrlIdentity result = UrlIdentity::CreateFromUrl(
profile(), test_case.url, test_case.allowed_types, test_case.options);
EXPECT_EQ(result.name, test_case.expected_result.name);
EXPECT_EQ(result.type, test_case.expected_result.type);
}
}
TEST_F(UrlIdentityTest, DefaultFormatOptionsTest) {
std::vector<TestCase> test_cases = {
{GURL("https://example.com"),
{Type::kDefault},
{},
{
.type = Type::kDefault,
.name = u"https://example.com",
}},
{GURL("https://example.com/123"),
{Type::kDefault},
{},
{
.type = Type::kDefault,
.name = u"https://example.com",
}},
{GURL("https://example.com/123"),
{Type::kDefault},
{.default_options = {DefaultFormatOptions::kRawSpec}},
{
.type = Type::kDefault,
.name = u"https://example.com/123",
}},
{GURL("https://example.com"),
{Type::kDefault},
{.default_options = {DefaultFormatOptions::kOmitCryptographicScheme}},
{
.type = Type::kDefault,
.name = u"example.com",
}},
{GURL("https://abc.example.com"),
{Type::kDefault},
{.default_options = {DefaultFormatOptions::kHostname}},
{
.type = Type::kDefault,
.name = u"abc.example.com",
}},
{GURL("http://user:pass@google.com/path"),
{Type::kDefault},
{.default_options =
{DefaultFormatOptions::kOmitSchemePathAndTrivialSubdomains}},
{
.type = Type::kDefault,
.name = u"google.com",
}},
};
for (const auto& test_case : test_cases) {
UrlIdentity result = UrlIdentity::CreateFromUrl(
profile(), test_case.url, test_case.allowed_types, test_case.options);
EXPECT_EQ(result.name, test_case.expected_result.name);
EXPECT_EQ(result.type, test_case.expected_result.type);
}
}
#if BUILDFLAG(ENABLE_EXTENSIONS)
TEST_F(UrlIdentityTest, ChromeExtensionsOptionsTest) {
std::string extension_id(kTestExtensionId);
std::vector<TestCase> test_cases = {
{extensions::Extension::GetBaseURLFromExtensionId(extension_id),
{Type::kChromeExtension},
{},
{
.type = Type::kChromeExtension,
.name = u"Test Extension 1",
}}};
for (const auto& test_case : test_cases) {
UrlIdentity result = UrlIdentity::CreateFromUrl(
profile(), test_case.url, test_case.allowed_types, test_case.options);
EXPECT_EQ(result.name, test_case.expected_result.name);
EXPECT_EQ(result.type, test_case.expected_result.type);
}
}
TEST_F(UrlIdentityTest, IsolatedWebAppsOptionsTest) {
std::vector<TestCase> test_cases = {
{GURL(kTestIsolatedWebAppUrl),
{Type::kIsolatedWebApp},
{},
{
.type = Type::kIsolatedWebApp,
.name = u"Test IWA Name",
}},
{GURL("isolated-app://unknown"),
{Type::kIsolatedWebApp},
{},
{
.type = Type::kDefault,
.name = u"isolated-app://unknown",
}},
{GURL("isolated-app://unknown"),
{Type::kIsolatedWebApp},
{.default_options = {DefaultFormatOptions::kHostname}},
{
.type = Type::kDefault,
.name = u"unknown",
}},
};
for (const auto& test_case : test_cases) {
UrlIdentity result = UrlIdentity::CreateFromUrl(
profile(), test_case.url, test_case.allowed_types, test_case.options);
EXPECT_EQ(result.name, test_case.expected_result.name);
EXPECT_EQ(result.type, test_case.expected_result.type);
}
}
#endif // BUILDFLAG(ENABLE_EXTENSIONS)
TEST_F(UrlIdentityTest, FileOptionsTest) {
std::vector<TestCase> test_cases = {
{GURL("file:///tmp/index.html"),
{Type::kFile},
{},
{
.type = Type::kFile,
.name = u"file:///tmp/index.html",
}},
};
for (const auto& test_case : test_cases) {
UrlIdentity result = UrlIdentity::CreateFromUrl(
profile(), test_case.url, test_case.allowed_types, test_case.options);
EXPECT_EQ(result.name, test_case.expected_result.name);
EXPECT_EQ(result.type, test_case.expected_result.type);
}
}