manifest_handler_unittest.cc revision f2477e01787aa58f445919b809d89e252beef54f
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 "extensions/common/extension.h" 13#include "extensions/common/extension_builder.h" 14#include "extensions/common/install_warning.h" 15#include "extensions/common/manifest_handler.h" 16#include "extensions/common/value_builder.h" 17#include "testing/gtest/include/gtest/gtest.h" 18 19namespace extensions { 20 21namespace { 22 23std::vector<std::string> SingleKey(const std::string& key) { 24 return std::vector<std::string>(1, key); 25} 26 27} // namespace 28 29class 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 43class 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 171TEST_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 213TEST_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 251TEST_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 282