| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 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 <string> | |
| 6 #include <vector> | |
| 7 | |
| 8 #include "base/files/file_path.h" | |
| 9 #include "base/memory/scoped_ptr.h" | |
| 10 #include "base/stl_util.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | |
| 12 #include "chrome/common/extensions/extension.h" | |
| 13 #include "chrome/common/extensions/extension_builder.h" | |
| 14 #include "chrome/common/extensions/value_builder.h" | |
| 15 #include "extensions/common/install_warning.h" | |
| 16 #include "extensions/common/manifest_handler.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | |
| 18 | |
| 19 namespace extensions { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 std::vector<std::string> SingleKey(const std::string& key) { | |
| 24 return std::vector<std::string>(1, key); | |
| 25 } | |
| 26 | |
| 27 } // namespace | |
| 28 | |
| 29 class ScopedTestingManifestHandlerRegistry { | |
| 30 public: | |
| 31 ScopedTestingManifestHandlerRegistry() { | |
| 32 old_registry_ = ManifestHandlerRegistry::SetForTesting(®istry_); | |
| 33 } | |
| 34 | |
| 35 ~ScopedTestingManifestHandlerRegistry() { | |
| 36 ManifestHandlerRegistry::SetForTesting(old_registry_); | |
| 37 } | |
| 38 | |
| 39 ManifestHandlerRegistry registry_; | |
| 40 ManifestHandlerRegistry* old_registry_; | |
| 41 }; | |
| 42 | |
| 43 class ManifestHandlerTest : public testing::Test { | |
| 44 public: | |
| 45 class ParsingWatcher { | |
| 46 public: | |
| 47 // Called when a manifest handler parses. | |
| 48 void Record(const std::string& name) { | |
| 49 parsed_names_.push_back(name); | |
| 50 } | |
| 51 | |
| 52 const std::vector<std::string>& parsed_names() { | |
| 53 return parsed_names_; | |
| 54 } | |
| 55 | |
| 56 // Returns true if |name_before| was parsed before |name_after|. | |
| 57 bool ParsedBefore(const std::string& name_before, | |
| 58 const std::string& name_after) { | |
| 59 size_t i_before = parsed_names_.size(); | |
| 60 size_t i_after = 0; | |
| 61 for (size_t i = 0; i < parsed_names_.size(); ++i) { | |
| 62 if (parsed_names_[i] == name_before) | |
| 63 i_before = i; | |
| 64 if (parsed_names_[i] == name_after) | |
| 65 i_after = i; | |
| 66 } | |
| 67 if (i_before < i_after) | |
| 68 return true; | |
| 69 return false; | |
| 70 } | |
| 71 | |
| 72 private: | |
| 73 // The order of manifest handlers that we watched parsing. | |
| 74 std::vector<std::string> parsed_names_; | |
| 75 }; | |
| 76 | |
| 77 class TestManifestHandler : public ManifestHandler { | |
| 78 public: | |
| 79 TestManifestHandler(const std::string& name, | |
| 80 const std::vector<std::string>& keys, | |
| 81 const std::vector<std::string>& prereqs, | |
| 82 ParsingWatcher* watcher) | |
| 83 : name_(name), keys_(keys), prereqs_(prereqs), watcher_(watcher) { | |
| 84 } | |
| 85 | |
| 86 virtual bool Parse(Extension* extension, string16* error) OVERRIDE { | |
| 87 watcher_->Record(name_); | |
| 88 return true; | |
| 89 } | |
| 90 | |
| 91 virtual const std::vector<std::string> PrerequisiteKeys() const OVERRIDE { | |
| 92 return prereqs_; | |
| 93 } | |
| 94 | |
| 95 protected: | |
| 96 std::string name_; | |
| 97 std::vector<std::string> keys_; | |
| 98 std::vector<std::string> prereqs_; | |
| 99 ParsingWatcher* watcher_; | |
| 100 | |
| 101 virtual const std::vector<std::string> Keys() const OVERRIDE { | |
| 102 return keys_; | |
| 103 } | |
| 104 }; | |
| 105 | |
| 106 class FailingTestManifestHandler : public TestManifestHandler { | |
| 107 public: | |
| 108 FailingTestManifestHandler(const std::string& name, | |
| 109 const std::vector<std::string>& keys, | |
| 110 const std::vector<std::string>& prereqs, | |
| 111 ParsingWatcher* watcher) | |
| 112 : TestManifestHandler(name, keys, prereqs, watcher) { | |
| 113 } | |
| 114 virtual bool Parse(Extension* extension, string16* error) OVERRIDE { | |
| 115 *error = ASCIIToUTF16(name_); | |
| 116 return false; | |
| 117 } | |
| 118 }; | |
| 119 | |
| 120 class AlwaysParseTestManifestHandler : public TestManifestHandler { | |
| 121 public: | |
| 122 AlwaysParseTestManifestHandler(const std::string& name, | |
| 123 const std::vector<std::string>& keys, | |
| 124 const std::vector<std::string>& prereqs, | |
| 125 ParsingWatcher* watcher) | |
| 126 : TestManifestHandler(name, keys, prereqs, watcher) { | |
| 127 } | |
| 128 | |
| 129 virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE { | |
| 130 return true; | |
| 131 } | |
| 132 }; | |
| 133 | |
| 134 class TestManifestValidator : public ManifestHandler { | |
| 135 public: | |
| 136 TestManifestValidator(bool return_value, | |
| 137 bool always_validate, | |
| 138 std::vector<std::string> keys) | |
| 139 : return_value_(return_value), | |
| 140 always_validate_(always_validate), | |
| 141 keys_(keys) { | |
| 142 } | |
| 143 | |
| 144 virtual bool Parse(Extension* extension, string16* error) OVERRIDE { | |
| 145 return true; | |
| 146 } | |
| 147 | |
| 148 virtual bool Validate( | |
| 149 const Extension* extension, | |
| 150 std::string* error, | |
| 151 std::vector<InstallWarning>* warnings) const OVERRIDE { | |
| 152 return return_value_; | |
| 153 } | |
| 154 | |
| 155 virtual bool AlwaysValidateForType(Manifest::Type type) const OVERRIDE { | |
| 156 return always_validate_; | |
| 157 } | |
| 158 | |
| 159 private: | |
| 160 virtual const std::vector<std::string> Keys() const OVERRIDE { | |
| 161 return keys_; | |
| 162 } | |
| 163 | |
| 164 protected: | |
| 165 bool return_value_; | |
| 166 bool always_validate_; | |
| 167 std::vector<std::string> keys_; | |
| 168 }; | |
| 169 }; | |
| 170 | |
| 171 TEST_F(ManifestHandlerTest, DependentHandlers) { | |
| 172 ScopedTestingManifestHandlerRegistry registry; | |
| 173 ParsingWatcher watcher; | |
| 174 std::vector<std::string> prereqs; | |
| 175 (new TestManifestHandler("A", SingleKey("a"), prereqs, &watcher))->Register(); | |
| 176 (new TestManifestHandler("B", SingleKey("b"), prereqs, &watcher))->Register(); | |
| 177 (new TestManifestHandler("J", SingleKey("j"), prereqs, &watcher))->Register(); | |
| 178 (new AlwaysParseTestManifestHandler("K", SingleKey("k"), prereqs, &watcher))-> | |
| 179 Register(); | |
| 180 prereqs.push_back("c.d"); | |
| 181 std::vector<std::string> keys; | |
| 182 keys.push_back("c.e"); | |
| 183 keys.push_back("c.z"); | |
| 184 (new TestManifestHandler("C.EZ", keys, prereqs, &watcher))->Register(); | |
| 185 prereqs.clear(); | |
| 186 prereqs.push_back("b"); | |
| 187 prereqs.push_back("k"); | |
| 188 (new TestManifestHandler("C.D", SingleKey("c.d"), prereqs, &watcher))-> | |
| 189 Register(); | |
| 190 ManifestHandler::FinalizeRegistration(); | |
| 191 | |
| 192 scoped_refptr<Extension> extension = ExtensionBuilder() | |
| 193 .SetManifest(DictionaryBuilder() | |
| 194 .Set("name", "no name") | |
| 195 .Set("version", "0") | |
| 196 .Set("manifest_version", 2) | |
| 197 .Set("a", 1) | |
| 198 .Set("b", 2) | |
| 199 .Set("c", DictionaryBuilder() | |
| 200 .Set("d", 3) | |
| 201 .Set("e", 4) | |
| 202 .Set("f", 5)) | |
| 203 .Set("g", 6)) | |
| 204 .Build(); | |
| 205 | |
| 206 // A, B, C.EZ, C.D, K | |
| 207 EXPECT_EQ(5u, watcher.parsed_names().size()); | |
| 208 EXPECT_TRUE(watcher.ParsedBefore("B", "C.D")); | |
| 209 EXPECT_TRUE(watcher.ParsedBefore("K", "C.D")); | |
| 210 EXPECT_TRUE(watcher.ParsedBefore("C.D", "C.EZ")); | |
| 211 } | |
| 212 | |
| 213 TEST_F(ManifestHandlerTest, FailingHandlers) { | |
| 214 ScopedTestingManifestHandlerRegistry registry; | |
| 215 // Can't use ExtensionBuilder, because this extension will fail to | |
| 216 // be parsed. | |
| 217 scoped_ptr<base::DictionaryValue> manifest_a( | |
| 218 DictionaryBuilder() | |
| 219 .Set("name", "no name") | |
| 220 .Set("version", "0") | |
| 221 .Set("manifest_version", 2) | |
| 222 .Set("a", 1) | |
| 223 .Build()); | |
| 224 | |
| 225 // Succeeds when "a" is not recognized. | |
| 226 std::string error; | |
| 227 scoped_refptr<Extension> extension = Extension::Create( | |
| 228 base::FilePath(), | |
| 229 Manifest::INVALID_LOCATION, | |
| 230 *manifest_a, | |
| 231 Extension::NO_FLAGS, | |
| 232 &error); | |
| 233 EXPECT_TRUE(extension.get()); | |
| 234 | |
| 235 // Register a handler for "a" that fails. | |
| 236 ParsingWatcher watcher; | |
| 237 (new FailingTestManifestHandler( | |
| 238 "A", SingleKey("a"), std::vector<std::string>(), &watcher))->Register(); | |
| 239 ManifestHandler::FinalizeRegistration(); | |
| 240 | |
| 241 extension = Extension::Create( | |
| 242 base::FilePath(), | |
| 243 Manifest::INVALID_LOCATION, | |
| 244 *manifest_a, | |
| 245 Extension::NO_FLAGS, | |
| 246 &error); | |
| 247 EXPECT_FALSE(extension.get()); | |
| 248 EXPECT_EQ("A", error); | |
| 249 } | |
| 250 | |
| 251 TEST_F(ManifestHandlerTest, Validate) { | |
| 252 ScopedTestingManifestHandlerRegistry registry; | |
| 253 scoped_refptr<Extension> extension = ExtensionBuilder() | |
| 254 .SetManifest(DictionaryBuilder() | |
| 255 .Set("name", "no name") | |
| 256 .Set("version", "0") | |
| 257 .Set("manifest_version", 2) | |
| 258 .Set("a", 1) | |
| 259 .Set("b", 2)) | |
| 260 .Build(); | |
| 261 EXPECT_TRUE(extension.get()); | |
| 262 | |
| 263 std::string error; | |
| 264 std::vector<InstallWarning> warnings; | |
| 265 // Always validates and fails. | |
| 266 (new TestManifestValidator(false, true, SingleKey("c")))->Register(); | |
| 267 EXPECT_FALSE( | |
| 268 ManifestHandler::ValidateExtension(extension.get(), &error, &warnings)); | |
| 269 | |
| 270 // This overrides the registered handler for "c". | |
| 271 (new TestManifestValidator(false, false, SingleKey("c")))->Register(); | |
| 272 EXPECT_TRUE( | |
| 273 ManifestHandler::ValidateExtension(extension.get(), &error, &warnings)); | |
| 274 | |
| 275 // Validates "a" and fails. | |
| 276 (new TestManifestValidator(false, true, SingleKey("a")))->Register(); | |
| 277 EXPECT_FALSE( | |
| 278 ManifestHandler::ValidateExtension(extension.get(), &error, &warnings)); | |
| 279 } | |
| 280 | |
| 281 } // namespace extensions | |
| OLD | NEW |