Home | History | Annotate | Download | only in common
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "extensions/common/manifest_test.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "base/files/file_util.h"
      9 #include "base/json/json_file_value_serializer.h"
     10 #include "base/path_service.h"
     11 #include "base/strings/string_util.h"
     12 #include "base/values.h"
     13 #include "extensions/common/extension_l10n_util.h"
     14 #include "extensions/common/extension_paths.h"
     15 #include "extensions/common/test_util.h"
     16 #include "ui/base/l10n/l10n_util.h"
     17 
     18 namespace extensions {
     19 namespace {
     20 
     21 // |manifest_path| is an absolute path to a manifest file.
     22 base::DictionaryValue* LoadManifestFile(const base::FilePath& manifest_path,
     23                                         std::string* error) {
     24   base::FilePath extension_path = manifest_path.DirName();
     25 
     26   EXPECT_TRUE(base::PathExists(manifest_path)) <<
     27       "Couldn't find " << manifest_path.value();
     28 
     29   JSONFileValueSerializer serializer(manifest_path);
     30   base::DictionaryValue* manifest =
     31       static_cast<base::DictionaryValue*>(serializer.Deserialize(NULL, error));
     32 
     33   // Most unit tests don't need localization, and they'll fail if we try to
     34   // localize them, since their manifests don't have a default_locale key.
     35   // Only localize manifests that indicate they want to be localized.
     36   // Calling LocalizeExtension at this point mirrors file_util::LoadExtension.
     37   if (manifest &&
     38       manifest_path.value().find(FILE_PATH_LITERAL("localized")) !=
     39       std::string::npos)
     40     extension_l10n_util::LocalizeExtension(extension_path, manifest, error);
     41 
     42   return manifest;
     43 }
     44 
     45 }  // namespace
     46 
     47 ManifestTest::ManifestTest()
     48     : enable_apps_(true) {
     49 }
     50 
     51 ManifestTest::~ManifestTest() {
     52 }
     53 
     54 // Helper class that simplifies creating methods that take either a filename
     55 // to a manifest or the manifest itself.
     56 ManifestTest::ManifestData::ManifestData(const char* name)
     57     : name_(name), manifest_(NULL) {
     58 }
     59 
     60 ManifestTest::ManifestData::ManifestData(base::DictionaryValue* manifest,
     61                                           const char* name)
     62     : name_(name), manifest_(manifest) {
     63   CHECK(manifest_) << "Manifest NULL";
     64 }
     65 
     66 ManifestTest::ManifestData::ManifestData(
     67     scoped_ptr<base::DictionaryValue> manifest)
     68     : manifest_(manifest.get()), manifest_holder_(manifest.Pass()) {
     69   CHECK(manifest_) << "Manifest NULL";
     70 }
     71 
     72 ManifestTest::ManifestData::ManifestData(const ManifestData& m) {
     73   NOTREACHED();
     74 }
     75 
     76 ManifestTest::ManifestData::~ManifestData() {
     77 }
     78 
     79 base::DictionaryValue* ManifestTest::ManifestData::GetManifest(
     80     base::FilePath test_data_dir, std::string* error) const {
     81   if (manifest_)
     82     return manifest_;
     83 
     84   base::FilePath manifest_path = test_data_dir.AppendASCII(name_);
     85   manifest_ = LoadManifestFile(manifest_path, error);
     86   manifest_holder_.reset(manifest_);
     87   return manifest_;
     88 }
     89 
     90 base::FilePath ManifestTest::GetTestDataDir() {
     91   base::FilePath path;
     92   PathService::Get(DIR_TEST_DATA, &path);
     93   return path.AppendASCII("manifest_tests");
     94 }
     95 
     96 scoped_ptr<base::DictionaryValue> ManifestTest::LoadManifest(
     97     char const* manifest_name, std::string* error) {
     98   base::FilePath manifest_path = GetTestDataDir().AppendASCII(manifest_name);
     99   return make_scoped_ptr(LoadManifestFile(manifest_path, error));
    100 }
    101 
    102 scoped_refptr<Extension> ManifestTest::LoadExtension(
    103     const ManifestData& manifest,
    104     std::string* error,
    105     extensions::Manifest::Location location,
    106     int flags) {
    107   base::FilePath test_data_dir = GetTestDataDir();
    108   base::DictionaryValue* value = manifest.GetManifest(test_data_dir, error);
    109   if (!value)
    110     return NULL;
    111   return Extension::Create(
    112       test_data_dir.DirName(), location, *value, flags, error);
    113 }
    114 
    115 scoped_refptr<Extension> ManifestTest::LoadAndExpectSuccess(
    116     const ManifestData& manifest,
    117     extensions::Manifest::Location location,
    118     int flags) {
    119   std::string error;
    120   scoped_refptr<Extension> extension =
    121       LoadExtension(manifest, &error, location, flags);
    122   EXPECT_TRUE(extension.get()) << manifest.name();
    123   EXPECT_EQ("", error) << manifest.name();
    124   return extension;
    125 }
    126 
    127 scoped_refptr<Extension> ManifestTest::LoadAndExpectSuccess(
    128     char const* manifest_name,
    129     extensions::Manifest::Location location,
    130     int flags) {
    131   return LoadAndExpectSuccess(ManifestData(manifest_name), location, flags);
    132 }
    133 
    134 scoped_refptr<Extension> ManifestTest::LoadAndExpectWarning(
    135     const ManifestData& manifest,
    136     const std::string& expected_warning,
    137     extensions::Manifest::Location location,
    138     int flags) {
    139   std::string error;
    140   scoped_refptr<Extension> extension =
    141       LoadExtension(manifest, &error, location, flags);
    142   EXPECT_TRUE(extension.get()) << manifest.name();
    143   EXPECT_EQ("", error) << manifest.name();
    144   EXPECT_EQ(1u, extension->install_warnings().size());
    145   EXPECT_EQ(expected_warning, extension->install_warnings()[0].message);
    146   return extension;
    147 }
    148 
    149 scoped_refptr<Extension> ManifestTest::LoadAndExpectWarning(
    150     char const* manifest_name,
    151     const std::string& expected_warning,
    152     extensions::Manifest::Location location,
    153     int flags) {
    154   return LoadAndExpectWarning(
    155       ManifestData(manifest_name), expected_warning, location, flags);
    156 }
    157 
    158 void ManifestTest::VerifyExpectedError(
    159     Extension* extension,
    160     const std::string& name,
    161     const std::string& error,
    162     const std::string& expected_error) {
    163   EXPECT_FALSE(extension) <<
    164       "Expected failure loading extension '" << name <<
    165       "', but didn't get one.";
    166   EXPECT_TRUE(MatchPattern(error, expected_error)) << name <<
    167       " expected '" << expected_error << "' but got '" << error << "'";
    168 }
    169 
    170 void ManifestTest::LoadAndExpectError(
    171     const ManifestData& manifest,
    172     const std::string& expected_error,
    173     extensions::Manifest::Location location,
    174     int flags) {
    175   std::string error;
    176   scoped_refptr<Extension> extension(
    177       LoadExtension(manifest, &error, location, flags));
    178   VerifyExpectedError(extension.get(), manifest.name(), error,
    179                       expected_error);
    180 }
    181 
    182 void ManifestTest::LoadAndExpectError(
    183     char const* manifest_name,
    184     const std::string& expected_error,
    185     extensions::Manifest::Location location,
    186     int flags) {
    187   return LoadAndExpectError(
    188       ManifestData(manifest_name), expected_error, location, flags);
    189 }
    190 
    191 void ManifestTest::AddPattern(extensions::URLPatternSet* extent,
    192                                        const std::string& pattern) {
    193   int schemes = URLPattern::SCHEME_ALL;
    194   extent->AddPattern(URLPattern(schemes, pattern));
    195 }
    196 
    197 ManifestTest::Testcase::Testcase(
    198     std::string manifest_filename,
    199     std::string expected_error,
    200     extensions::Manifest::Location location,
    201     int flags)
    202     : manifest_filename_(manifest_filename),
    203       expected_error_(expected_error),
    204       location_(location), flags_(flags) {
    205 }
    206 
    207 ManifestTest::Testcase::Testcase(std::string manifest_filename,
    208                                           std::string expected_error)
    209     : manifest_filename_(manifest_filename),
    210       expected_error_(expected_error),
    211       location_(extensions::Manifest::INTERNAL),
    212       flags_(Extension::NO_FLAGS) {
    213 }
    214 
    215 ManifestTest::Testcase::Testcase(std::string manifest_filename)
    216     : manifest_filename_(manifest_filename),
    217       location_(extensions::Manifest::INTERNAL),
    218       flags_(Extension::NO_FLAGS) {}
    219 
    220 ManifestTest::Testcase::Testcase(
    221     std::string manifest_filename,
    222     extensions::Manifest::Location location,
    223     int flags)
    224     : manifest_filename_(manifest_filename),
    225       location_(location),
    226       flags_(flags) {}
    227 
    228 void ManifestTest::RunTestcases(const Testcase* testcases,
    229                                          size_t num_testcases,
    230                                          ExpectType type) {
    231   for (size_t i = 0; i < num_testcases; ++i)
    232     RunTestcase(testcases[i], type);
    233 }
    234 
    235 void ManifestTest::RunTestcase(const Testcase& testcase,
    236                                         ExpectType type) {
    237   switch (type) {
    238     case EXPECT_TYPE_ERROR:
    239       LoadAndExpectError(testcase.manifest_filename_.c_str(),
    240                          testcase.expected_error_,
    241                          testcase.location_,
    242                          testcase.flags_);
    243       break;
    244     case EXPECT_TYPE_WARNING:
    245       LoadAndExpectWarning(testcase.manifest_filename_.c_str(),
    246                            testcase.expected_error_,
    247                            testcase.location_,
    248                            testcase.flags_);
    249       break;
    250     case EXPECT_TYPE_SUCCESS:
    251       LoadAndExpectSuccess(testcase.manifest_filename_.c_str(),
    252                            testcase.location_,
    253                            testcase.flags_);
    254       break;
    255    }
    256 }
    257 
    258 }  // namespace extensions
    259