| // 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_util.h" | 
 | #include "base/values.h" | 
 | #include "extensions/common/extension_l10n_util.h" | 
 | #include "extensions/common/extension_paths.h" | 
 | #include "ui/base/l10n/l10n_util.h" | 
 |  | 
 | namespace extensions { | 
 | namespace { | 
 |  | 
 | // |manifest_path| is an absolute path to a manifest file. | 
 | std::unique_ptr<base::DictionaryValue> 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::DictionaryValue> manifest = | 
 |       base::DictionaryValue::From(deserializer.Deserialize(NULL, error)); | 
 |  | 
 |   // 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 && | 
 |       manifest_path.value().find(FILE_PATH_LITERAL("localized")) != | 
 |       std::string::npos) | 
 |     extension_l10n_util::LocalizeExtension(extension_path, manifest.get(), | 
 |                                            error); | 
 |  | 
 |   return 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(const char* name) | 
 |     : name_(name), manifest_(nullptr) {} | 
 |  | 
 | // This does not take ownership of |manifest|. | 
 | ManifestTest::ManifestData::ManifestData(base::DictionaryValue* manifest, | 
 |                                           const char* name) | 
 |     : name_(name), manifest_(manifest) { | 
 |   CHECK(manifest_) << "Manifest NULL"; | 
 | } | 
 |  | 
 | ManifestTest::ManifestData::ManifestData( | 
 |     std::unique_ptr<base::DictionaryValue> manifest) | 
 |     : manifest_(manifest.get()), manifest_holder_(std::move(manifest)) { | 
 |   CHECK(manifest_) << "Manifest NULL"; | 
 | } | 
 |  | 
 | ManifestTest::ManifestData::ManifestData( | 
 |     std::unique_ptr<base::DictionaryValue> manifest, | 
 |     const char* name) | 
 |     : name_(name), | 
 |       manifest_(manifest.get()), | 
 |       manifest_holder_(std::move(manifest)) { | 
 |   CHECK(manifest_) << "Manifest NULL"; | 
 | } | 
 |  | 
 | ManifestTest::ManifestData::ManifestData(const ManifestData& m) { | 
 |   NOTREACHED(); | 
 | } | 
 |  | 
 | ManifestTest::ManifestData::~ManifestData() { | 
 | } | 
 |  | 
 | base::DictionaryValue* ManifestTest::ManifestData::GetManifest( | 
 |     const base::FilePath& test_data_dir, | 
 |     std::string* error) const { | 
 |   if (manifest_) | 
 |     return manifest_; | 
 |  | 
 |   base::FilePath manifest_path = test_data_dir.AppendASCII(name_); | 
 |   manifest_holder_ = LoadManifestFile(manifest_path, error); | 
 |   manifest_ = manifest_holder_.get(); | 
 |   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"); | 
 | } | 
 |  | 
 | std::unique_ptr<base::DictionaryValue> 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, | 
 |     extensions::Manifest::Location location, | 
 |     int flags) { | 
 |   base::FilePath test_data_dir = GetTestDataDir(); | 
 |   base::DictionaryValue* value = manifest.GetManifest(test_data_dir, error); | 
 |   if (!value) | 
 |     return NULL; | 
 |   return Extension::Create(test_data_dir.DirName(), location, *value, flags, | 
 |       GetTestExtensionID(), error); | 
 | } | 
 |  | 
 | scoped_refptr<Extension> ManifestTest::LoadAndExpectSuccess( | 
 |     const ManifestData& manifest, | 
 |     extensions::Manifest::Location location, | 
 |     int flags) { | 
 |   std::string error; | 
 |   scoped_refptr<Extension> extension = | 
 |       LoadExtension(manifest, &error, location, flags); | 
 |   EXPECT_TRUE(extension.get()) << manifest.name(); | 
 |   EXPECT_EQ("", error) << manifest.name(); | 
 |   return extension; | 
 | } | 
 |  | 
 | scoped_refptr<Extension> ManifestTest::LoadAndExpectSuccess( | 
 |     char const* manifest_name, | 
 |     extensions::Manifest::Location location, | 
 |     int flags) { | 
 |   return LoadAndExpectSuccess(ManifestData(manifest_name), location, flags); | 
 | } | 
 |  | 
 | scoped_refptr<Extension> ManifestTest::LoadAndExpectWarning( | 
 |     const ManifestData& manifest, | 
 |     const std::string& expected_warning, | 
 |     extensions::Manifest::Location location, | 
 |     int flags) { | 
 |   std::string error; | 
 |   scoped_refptr<Extension> extension = | 
 |       LoadExtension(manifest, &error, location, flags); | 
 |   EXPECT_TRUE(extension.get()) << manifest.name(); | 
 |   EXPECT_EQ("", error) << manifest.name(); | 
 |   EXPECT_EQ(1u, extension->install_warnings().size()); | 
 |   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, | 
 |     extensions::Manifest::Location location, | 
 |     int flags) { | 
 |   return LoadAndExpectWarning( | 
 |       ManifestData(manifest_name), expected_warning, location, flags); | 
 | } | 
 |  | 
 | 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, | 
 |     extensions::Manifest::Location 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( | 
 |     char const* manifest_name, | 
 |     const std::string& expected_error, | 
 |     extensions::Manifest::Location location, | 
 |     int flags) { | 
 |   return LoadAndExpectError( | 
 |       ManifestData(manifest_name), 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, | 
 |                                  extensions::Manifest::Location 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::string& expected_error) | 
 |     : manifest_filename_(manifest_filename), | 
 |       expected_error_(expected_error), | 
 |       location_(extensions::Manifest::INTERNAL), | 
 |       flags_(Extension::NO_FLAGS) {} | 
 |  | 
 | ManifestTest::Testcase::Testcase(const std::string& manifest_filename) | 
 |     : manifest_filename_(manifest_filename), | 
 |       location_(extensions::Manifest::INTERNAL), | 
 |       flags_(Extension::NO_FLAGS) {} | 
 |  | 
 | ManifestTest::Testcase::Testcase(const std::string& manifest_filename, | 
 |                                  extensions::Manifest::Location 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) { | 
 |   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 |