blob: 537bd98d27c973bc6f741caa0e260625a3c980d3 [file] [log] [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/files/scoped_temp_dir.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_constants.h"
#include "extensions/common/manifest_handlers/devtools_page_handler.h"
#include "extensions/common/manifest_test.h"
#include "extensions/common/permissions/permissions_data.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace extensions {
namespace {
using DevToolsPageManifestTest = ManifestTest;
TEST_F(DevToolsPageManifestTest, DevToolsExtensions) {
LoadAndExpectError("devtools_extension_url_invalid_type.json",
manifest_errors::kInvalidDevToolsPage);
LoadAndExpectError("devtools_extension_invalid_page_url.json",
manifest_errors::kInvalidDevToolsPage);
LoadAndExpectError("devtools_extension_page_url_https.json",
manifest_errors::kInvalidDevToolsPage);
scoped_refptr<Extension> extension =
LoadAndExpectSuccess("devtools_extension.json");
EXPECT_EQ(extension->url().spec() + "devtools.html",
chrome_manifest_urls::GetDevToolsPage(extension.get()).spec());
EXPECT_TRUE(extension->permissions_data()
->active_permissions()
.HasEffectiveAccessToAllHosts());
}
class ManifestDevToolsPageHandlerTest : public ManifestTest {
public:
ManifestDevToolsPageHandlerTest() = default;
protected:
base::Value::Dict CreateManifest(const std::string& devtools_page) {
return base::Value::Dict()
.Set("name", "DevTools")
.Set("version", "1")
.Set("manifest_version", 3)
.Set("devtools_page", devtools_page);
}
void LoadAndExpectSuccess(const std::string& id,
const std::string& devtools_page,
const std::string& parsed_devtools_page) {
base::ScopedTempDir dir;
std::u16string error;
base::Value::Dict manifest = CreateManifest(devtools_page);
ASSERT_TRUE(dir.CreateUniqueTempDir());
scoped_refptr<Extension> extension =
Extension::Create(dir.GetPath(), mojom::ManifestLocation::kInternal,
manifest, Extension::NO_FLAGS, id, &error);
ASSERT_TRUE(extension.get());
EXPECT_TRUE(error.empty());
ASSERT_EQ(parsed_devtools_page,
chrome_manifest_urls::GetDevToolsPage(extension.get()).spec());
}
void LoadAndExpectSuccess(const std::string& id,
const std::string& devtools_page) {
LoadAndExpectSuccess(id, devtools_page, devtools_page);
}
void LoadAndExpectError(const std::string& id,
const std::string& devtools_page,
const std::u16string& expected_error) {
base::ScopedTempDir dir;
std::u16string error;
base::Value::Dict manifest = CreateManifest(devtools_page);
ASSERT_TRUE(dir.CreateUniqueTempDir());
scoped_refptr<Extension> extension =
Extension::Create(dir.GetPath(), mojom::ManifestLocation::kInternal,
manifest, Extension::NO_FLAGS, id, &error);
ASSERT_FALSE(extension);
ASSERT_EQ(expected_error, error);
}
void LoadAndExpectError(const std::string& devtools_page,
const std::u16string& expected_error) {
LoadAndExpectError(std::string(), devtools_page, expected_error);
}
void ValidateAndExpectWarning(const std::string& id,
const std::string& devtools_page,
const std::string& expected_warning) {
base::ScopedTempDir dir;
std::string error;
std::u16string utf16_error;
std::vector<InstallWarning> warnings;
base::Value::Dict manifest = CreateManifest(devtools_page);
ASSERT_TRUE(dir.CreateUniqueTempDir());
scoped_refptr<Extension> extension =
Extension::Create(dir.GetPath(), mojom::ManifestLocation::kInternal,
manifest, Extension::NO_FLAGS, id, &utf16_error);
ASSERT_TRUE(extension);
EXPECT_TRUE(
ManifestHandler::ValidateExtension(extension.get(), &error, &warnings));
EXPECT_TRUE(error.empty());
ASSERT_EQ(1u, warnings.size());
EXPECT_EQ(InstallWarning(expected_warning), warnings[0]);
}
void ValidateAndExpectWarning(const std::string& devtools_page,
const std::string& expected_warning) {
ValidateAndExpectWarning(std::string(), devtools_page, expected_warning);
}
};
} // namespace
TEST_F(ManifestDevToolsPageHandlerTest, DevToolsPageImported) {
// Specifying an absolute URL for an imported resource should fail, similar
// to other remote sources.
LoadAndExpectError("someid",
"chrome-extension://someid/_modules/"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/devtools.html",
std::u16string(manifest_errors::kInvalidDevToolsPage));
// Specifying an absolute URL for a resouce with '_modules' in it but not
// actually an imported resource should be fine
LoadAndExpectSuccess("someid",
"chrome-extension://someid/_modules1/devtools.html");
}
TEST_F(ManifestDevToolsPageHandlerTest, DevTools) {
LoadAndExpectSuccess("someid", "chrome-extension://someid/path");
ValidateAndExpectWarning(
"does-not-exist.html",
ErrorUtils::FormatErrorMessage(manifest_errors::kFileNotFound,
"does-not-exist.html"));
ValidateAndExpectWarning(
"/does-not-exist.html",
ErrorUtils::FormatErrorMessage(manifest_errors::kFileNotFound,
"does-not-exist.html"));
ValidateAndExpectWarning(
"aaaa", "_modules/aaaa/bbbb/index.html",
ErrorUtils::FormatErrorMessage(manifest_errors::kFileNotFound,
"_modules/aaaa/bbbb/index.html"));
ValidateAndExpectWarning(
"aaaa", "chrome-extension://aaaa/does-not-exist.html",
ErrorUtils::FormatErrorMessage(manifest_errors::kFileNotFound,
"does-not-exist.html"));
// Specifying an absolute URL for a different extension's resource should
// fail, similar to other remote sources.
LoadAndExpectError("aaaa", "chrome-extension://bbbb/index.html",
std::u16string(manifest_errors::kInvalidDevToolsPage));
LoadAndExpectError("wss://bad.example.com",
std::u16string(manifest_errors::kInvalidDevToolsPage));
LoadAndExpectError("https://bad.example.com/dont_ever_do_this.html",
std::u16string(manifest_errors::kInvalidDevToolsPage));
}
} // namespace extensions