123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- // Copyright (c) 2012 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 "extensions/common/manifest_test.h"
- #include <utility>
- #include "base/files/file_path.h"
- #include "base/files/file_util.h"
- #include "base/json/json_file_value_serializer.h"
- #include "base/path_service.h"
- #include "base/strings/pattern.h"
- #include "base/strings/string_piece.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringprintf.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/values.h"
- #include "extensions/common/extension_l10n_util.h"
- #include "extensions/common/extension_paths.h"
- #include "extensions/common/manifest_constants.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "ui/base/l10n/l10n_util.h"
- using extensions::mojom::ManifestLocation;
- namespace extensions {
- namespace {
- std::string GetNameFromManifest(const base::Value& manifest) {
- if (!manifest.is_dict())
- return std::string();
- const std::string* name = manifest.FindStringKey(manifest_keys::kName);
- return name ? *name : std::string();
- }
- // |manifest_path| is an absolute path to a manifest file.
- base::Value LoadManifestFile(const base::FilePath& manifest_path,
- std::string* error) {
- base::FilePath extension_path = manifest_path.DirName();
- EXPECT_TRUE(base::PathExists(manifest_path)) <<
- "Couldn't find " << manifest_path.value();
- JSONFileValueDeserializer deserializer(manifest_path);
- std::unique_ptr<base::Value> manifest =
- deserializer.Deserialize(nullptr, error);
- if (!manifest || !manifest->is_dict())
- return base::Value();
- // Most unit tests don't need localization, and they'll fail if we try to
- // localize them, since their manifests don't have a default_locale key.
- // Only localize manifests that indicate they want to be localized.
- // Calling LocalizeExtension at this point mirrors file_util::LoadExtension.
- if (manifest_path.value().find(FILE_PATH_LITERAL("localized")) !=
- std::string::npos) {
- base::DictionaryValue* manifest_dictionary = nullptr;
- manifest->GetAsDictionary(&manifest_dictionary);
- extension_l10n_util::LocalizeExtension(
- extension_path, manifest_dictionary,
- extension_l10n_util::GzippedMessagesPermission::kDisallow, error);
- }
- return base::Value(std::move(*manifest));
- }
- } // namespace
- ManifestTest::ManifestTest()
- : enable_apps_(true) {
- }
- ManifestTest::~ManifestTest() {
- }
- // Helper class that simplifies creating methods that take either a filename
- // to a manifest or the manifest itself.
- ManifestTest::ManifestData::ManifestData(base::StringPiece name)
- : name_(name) {}
- ManifestTest::ManifestData::ManifestData(base::Value manifest,
- base::StringPiece name)
- : name_(name), manifest_(std::move(manifest)) {
- CHECK(manifest_.is_dict()) << "Manifest must be a dictionary. " << name_;
- }
- ManifestTest::ManifestData::ManifestData(base::Value manifest)
- : name_(GetNameFromManifest(manifest)), manifest_(std::move(manifest)) {
- CHECK(manifest_.is_dict()) << "Manifest must be a dictionary.";
- CHECK(!name_.empty()) << R"("name" must be specified in the manifest.)";
- }
- ManifestTest::ManifestData::ManifestData(ManifestData&& other) = default;
- ManifestTest::ManifestData::~ManifestData() = default;
- const base::Value& ManifestTest::ManifestData::GetManifest(
- const base::FilePath& test_data_dir,
- std::string* error) const {
- if (manifest_.is_none()) {
- base::FilePath manifest_path = test_data_dir.AppendASCII(name_);
- manifest_ = LoadManifestFile(manifest_path, error);
- }
- return manifest_;
- }
- std::string ManifestTest::GetTestExtensionID() const {
- return std::string();
- }
- base::FilePath ManifestTest::GetTestDataDir() {
- base::FilePath path;
- base::PathService::Get(DIR_TEST_DATA, &path);
- return path.AppendASCII("manifest_tests");
- }
- base::Value ManifestTest::LoadManifest(char const* manifest_name,
- std::string* error) {
- base::FilePath manifest_path = GetTestDataDir().AppendASCII(manifest_name);
- return LoadManifestFile(manifest_path, error);
- }
- scoped_refptr<Extension> ManifestTest::LoadExtension(
- const ManifestData& manifest,
- std::string* error,
- ManifestLocation location,
- int flags) {
- base::FilePath test_data_dir = GetTestDataDir();
- const base::Value& value = manifest.GetManifest(test_data_dir, error);
- if (value.is_none())
- return nullptr;
- DCHECK(value.is_dict());
- const base::DictionaryValue* dictionary_manifest = nullptr;
- value.GetAsDictionary(&dictionary_manifest);
- return Extension::Create(test_data_dir.DirName(), location,
- *dictionary_manifest, flags, GetTestExtensionID(),
- error);
- }
- scoped_refptr<Extension> ManifestTest::LoadAndExpectSuccess(
- const ManifestData& manifest,
- ManifestLocation location,
- int flags) {
- std::string error;
- scoped_refptr<Extension> extension =
- LoadExtension(manifest, &error, location, flags);
- EXPECT_TRUE(extension.get()) << manifest.name();
- EXPECT_EQ(std::string(), error) << manifest.name();
- return extension;
- }
- scoped_refptr<Extension> ManifestTest::LoadAndExpectSuccess(
- char const* manifest_name,
- ManifestLocation location,
- int flags) {
- return LoadAndExpectSuccess(ManifestData(manifest_name), location, flags);
- }
- scoped_refptr<Extension> ManifestTest::LoadAndExpectWarning(
- const ManifestData& manifest,
- const std::string& expected_warning,
- ManifestLocation location,
- int flags) {
- std::string error;
- scoped_refptr<Extension> extension =
- LoadExtension(manifest, &error, location, flags);
- EXPECT_TRUE(extension.get()) << manifest.name();
- EXPECT_EQ(std::string(), error) << manifest.name();
- EXPECT_EQ(1u, extension->install_warnings().size());
- if (extension->install_warnings().size() == 1)
- EXPECT_EQ(expected_warning, extension->install_warnings()[0].message);
- return extension;
- }
- scoped_refptr<Extension> ManifestTest::LoadAndExpectWarning(
- char const* manifest_name,
- const std::string& expected_warning,
- ManifestLocation location,
- int flags) {
- return LoadAndExpectWarning(
- ManifestData(manifest_name), expected_warning, location, flags);
- }
- scoped_refptr<Extension> ManifestTest::LoadAndExpectWarnings(
- char const* manifest_name,
- const std::vector<std::string>& expected_warnings,
- ManifestLocation location,
- int flags) {
- std::string error;
- scoped_refptr<Extension> extension =
- LoadExtension(ManifestData(manifest_name), &error, location, flags);
- EXPECT_TRUE(extension.get()) << manifest_name;
- EXPECT_EQ(std::string(), error) << manifest_name;
- std::vector<std::string> warning_messages;
- warning_messages.reserve(extension->install_warnings().size());
- for (const auto& warning : extension->install_warnings()) {
- warning_messages.push_back(warning.message);
- }
- EXPECT_THAT(warning_messages,
- testing::UnorderedElementsAreArray(expected_warnings));
- return extension;
- }
- void ManifestTest::VerifyExpectedError(
- Extension* extension,
- const std::string& name,
- const std::string& error,
- const std::string& expected_error) {
- EXPECT_FALSE(extension) <<
- "Expected failure loading extension '" << name <<
- "', but didn't get one.";
- EXPECT_TRUE(base::MatchPattern(error, expected_error))
- << name << " expected '" << expected_error << "' but got '" << error
- << "'";
- }
- void ManifestTest::LoadAndExpectError(const ManifestData& manifest,
- const std::string& expected_error,
- ManifestLocation location,
- int flags) {
- std::string error;
- scoped_refptr<Extension> extension(
- LoadExtension(manifest, &error, location, flags));
- VerifyExpectedError(extension.get(), manifest.name(), error,
- expected_error);
- }
- void ManifestTest::LoadAndExpectError(const ManifestData& manifest,
- const std::u16string& expected_error,
- ManifestLocation location,
- int flags) {
- return LoadAndExpectError(manifest, base::UTF16ToUTF8(expected_error),
- location, flags);
- }
- void ManifestTest::LoadAndExpectError(char const* manifest_name,
- const std::string& expected_error,
- ManifestLocation location,
- int flags) {
- return LoadAndExpectError(
- ManifestData(manifest_name), expected_error, location, flags);
- }
- void ManifestTest::LoadAndExpectError(char const* manifest_name,
- const std::u16string& expected_error,
- ManifestLocation location,
- int flags) {
- return LoadAndExpectError(ManifestData(manifest_name),
- base::UTF16ToUTF8(expected_error), location, flags);
- }
- void ManifestTest::AddPattern(extensions::URLPatternSet* extent,
- const std::string& pattern) {
- int schemes = URLPattern::SCHEME_ALL;
- extent->AddPattern(URLPattern(schemes, pattern));
- }
- ManifestTest::Testcase::Testcase(const std::string& manifest_filename,
- const std::string& expected_error,
- ManifestLocation location,
- int flags)
- : manifest_filename_(manifest_filename),
- expected_error_(expected_error),
- location_(location),
- flags_(flags) {}
- ManifestTest::Testcase::Testcase(const std::string& manifest_filename,
- const std::u16string& expected_error,
- ManifestLocation location,
- int flags)
- : Testcase(manifest_filename,
- base::UTF16ToUTF8(expected_error),
- location,
- flags) {}
- ManifestTest::Testcase::Testcase(const std::string& manifest_filename,
- const std::string& expected_error)
- : manifest_filename_(manifest_filename),
- expected_error_(expected_error),
- location_(ManifestLocation::kInternal),
- flags_(Extension::NO_FLAGS) {}
- ManifestTest::Testcase::Testcase(const std::string& manifest_filename,
- const std::u16string& expected_error)
- : Testcase(manifest_filename, base::UTF16ToUTF8(expected_error)) {}
- ManifestTest::Testcase::Testcase(const std::string& manifest_filename)
- : manifest_filename_(manifest_filename),
- location_(ManifestLocation::kInternal),
- flags_(Extension::NO_FLAGS) {}
- ManifestTest::Testcase::Testcase(const std::string& manifest_filename,
- ManifestLocation location,
- int flags)
- : manifest_filename_(manifest_filename),
- location_(location),
- flags_(flags) {}
- void ManifestTest::RunTestcases(const Testcase* testcases,
- size_t num_testcases,
- ExpectType type) {
- for (size_t i = 0; i < num_testcases; ++i)
- RunTestcase(testcases[i], type);
- }
- void ManifestTest::RunTestcase(const Testcase& testcase,
- ExpectType type) {
- SCOPED_TRACE(base::StringPrintf("Testing file '%s'",
- testcase.manifest_filename_.c_str()));
- switch (type) {
- case EXPECT_TYPE_ERROR:
- LoadAndExpectError(testcase.manifest_filename_.c_str(),
- testcase.expected_error_,
- testcase.location_,
- testcase.flags_);
- break;
- case EXPECT_TYPE_WARNING:
- LoadAndExpectWarning(testcase.manifest_filename_.c_str(),
- testcase.expected_error_,
- testcase.location_,
- testcase.flags_);
- break;
- case EXPECT_TYPE_SUCCESS:
- LoadAndExpectSuccess(testcase.manifest_filename_.c_str(),
- testcase.location_,
- testcase.flags_);
- break;
- }
- }
- } // namespace extensions
|