| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/memory/ref_counted.h" | 5 #include "base/memory/ref_counted.h" |
| 6 #include "base/memory/scoped_ptr.h" | 6 #include "base/memory/scoped_ptr.h" |
| 7 #include "base/strings/string16.h" | 7 #include "base/strings/string16.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/extensions/extension_service.h" | 9 #include "chrome/browser/extensions/extension_service.h" |
| 10 #include "chrome/browser/extensions/extension_service_test_base.h" | 10 #include "chrome/browser/extensions/extension_service_test_base.h" |
| 11 #include "chrome/browser/extensions/pending_extension_manager.h" | 11 #include "chrome/browser/extensions/pending_extension_manager.h" |
| 12 #include "chrome/browser/extensions/shared_module_service.h" | 12 #include "chrome/browser/extensions/shared_module_service.h" |
| 13 #include "chrome/common/extensions/features/feature_channel.h" | 13 #include "chrome/common/extensions/features/feature_channel.h" |
| 14 #include "components/crx_file/id_util.h" |
| 14 #include "extensions/browser/extension_registry.h" | 15 #include "extensions/browser/extension_registry.h" |
| 15 #include "extensions/browser/install_flag.h" | 16 #include "extensions/browser/install_flag.h" |
| 16 #include "extensions/browser/uninstall_reason.h" | 17 #include "extensions/browser/uninstall_reason.h" |
| 17 #include "extensions/common/extension_builder.h" | 18 #include "extensions/common/extension_builder.h" |
| 18 #include "extensions/common/id_util.h" | |
| 19 #include "extensions/common/value_builder.h" | 19 #include "extensions/common/value_builder.h" |
| 20 #include "sync/api/string_ordinal.h" | 20 #include "sync/api/string_ordinal.h" |
| 21 | 21 |
| 22 namespace extensions { | 22 namespace extensions { |
| 23 | 23 |
| 24 namespace { | 24 namespace { |
| 25 | 25 |
| 26 // Return an extension with |id| which imports a module with the given | 26 // Return an extension with |id| which imports a module with the given |
| 27 // |import_id|. | 27 // |import_id|. |
| 28 scoped_refptr<Extension> CreateExtensionImportingModule( | 28 scoped_refptr<Extension> CreateExtensionImportingModule( |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 if (!registry()->GetExtensionById(extension->id(), | 94 if (!registry()->GetExtensionById(extension->id(), |
| 95 ExtensionRegistry::ENABLED)) { | 95 ExtensionRegistry::ENABLED)) { |
| 96 return testing::AssertionFailure() << "Could not install extension."; | 96 return testing::AssertionFailure() << "Could not install extension."; |
| 97 } | 97 } |
| 98 | 98 |
| 99 return testing::AssertionSuccess(); | 99 return testing::AssertionSuccess(); |
| 100 } | 100 } |
| 101 | 101 |
| 102 TEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) { | 102 TEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) { |
| 103 // Create an extension that has a dependency. | 103 // Create an extension that has a dependency. |
| 104 std::string import_id = id_util::GenerateId("id"); | 104 std::string import_id = crx_file::id_util::GenerateId("id"); |
| 105 std::string extension_id = id_util::GenerateId("extension_id"); | 105 std::string extension_id = crx_file::id_util::GenerateId("extension_id"); |
| 106 scoped_refptr<Extension> extension = | 106 scoped_refptr<Extension> extension = |
| 107 CreateExtensionImportingModule(import_id, extension_id, "1.0"); | 107 CreateExtensionImportingModule(import_id, extension_id, "1.0"); |
| 108 | 108 |
| 109 PendingExtensionManager* pending_extension_manager = | 109 PendingExtensionManager* pending_extension_manager = |
| 110 service()->pending_extension_manager(); | 110 service()->pending_extension_manager(); |
| 111 | 111 |
| 112 // Verify that we don't currently want to install the imported module. | 112 // Verify that we don't currently want to install the imported module. |
| 113 EXPECT_FALSE(pending_extension_manager->IsIdPending(import_id)); | 113 EXPECT_FALSE(pending_extension_manager->IsIdPending(import_id)); |
| 114 | 114 |
| 115 // Try to satisfy imports for the extension. This should queue the imported | 115 // Try to satisfy imports for the extension. This should queue the imported |
| 116 // module's installation. | 116 // module's installation. |
| 117 service()->shared_module_service()->SatisfyImports(extension); | 117 service()->shared_module_service()->SatisfyImports(extension); |
| 118 EXPECT_TRUE(pending_extension_manager->IsIdPending(import_id)); | 118 EXPECT_TRUE(pending_extension_manager->IsIdPending(import_id)); |
| 119 } | 119 } |
| 120 | 120 |
| 121 TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) { | 121 TEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) { |
| 122 // Create a module which exports a resource, and install it. | 122 // Create a module which exports a resource, and install it. |
| 123 scoped_ptr<base::DictionaryValue> manifest = | 123 scoped_ptr<base::DictionaryValue> manifest = |
| 124 DictionaryBuilder() | 124 DictionaryBuilder() |
| 125 .Set("name", "Shared Module") | 125 .Set("name", "Shared Module") |
| 126 .Set("version", "1.0") | 126 .Set("version", "1.0") |
| 127 .Set("manifest_version", 2) | 127 .Set("manifest_version", 2) |
| 128 .Set("export", | 128 .Set("export", |
| 129 DictionaryBuilder().Set("resources", | 129 DictionaryBuilder().Set("resources", |
| 130 ListBuilder().Append("foo.js"))).Build(); | 130 ListBuilder().Append("foo.js"))).Build(); |
| 131 scoped_refptr<Extension> shared_module = | 131 scoped_refptr<Extension> shared_module = |
| 132 ExtensionBuilder().SetManifest(manifest.Pass()) | 132 ExtensionBuilder() |
| 133 .AddFlags(Extension::FROM_WEBSTORE) | 133 .SetManifest(manifest.Pass()) |
| 134 .SetID(id_util::GenerateId("shared_module")) | 134 .AddFlags(Extension::FROM_WEBSTORE) |
| 135 .Build(); | 135 .SetID(crx_file::id_util::GenerateId("shared_module")) |
| 136 .Build(); |
| 136 | 137 |
| 137 EXPECT_TRUE(InstallExtension(shared_module, false)); | 138 EXPECT_TRUE(InstallExtension(shared_module, false)); |
| 138 | 139 |
| 139 std::string extension_id = id_util::GenerateId("extension_id"); | 140 std::string extension_id = crx_file::id_util::GenerateId("extension_id"); |
| 140 // Create and install an extension that imports our new module. | 141 // Create and install an extension that imports our new module. |
| 141 scoped_refptr<Extension> importing_extension = | 142 scoped_refptr<Extension> importing_extension = |
| 142 CreateExtensionImportingModule(shared_module->id(), extension_id, "1.0"); | 143 CreateExtensionImportingModule(shared_module->id(), extension_id, "1.0"); |
| 143 EXPECT_TRUE(InstallExtension(importing_extension, false)); | 144 EXPECT_TRUE(InstallExtension(importing_extension, false)); |
| 144 | 145 |
| 145 // Uninstall the extension that imports our module. | 146 // Uninstall the extension that imports our module. |
| 146 base::string16 error; | 147 base::string16 error; |
| 147 service()->UninstallExtension(importing_extension->id(), | 148 service()->UninstallExtension(importing_extension->id(), |
| 148 extensions::UNINSTALL_REASON_FOR_TESTING, | 149 extensions::UNINSTALL_REASON_FOR_TESTING, |
| 149 base::Bind(&base::DoNothing), | 150 base::Bind(&base::DoNothing), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 161 // Create two modules which export a resource, and install them. | 162 // Create two modules which export a resource, and install them. |
| 162 scoped_ptr<base::DictionaryValue> manifest_1 = | 163 scoped_ptr<base::DictionaryValue> manifest_1 = |
| 163 DictionaryBuilder() | 164 DictionaryBuilder() |
| 164 .Set("name", "Shared Module 1") | 165 .Set("name", "Shared Module 1") |
| 165 .Set("version", "1.0") | 166 .Set("version", "1.0") |
| 166 .Set("manifest_version", 2) | 167 .Set("manifest_version", 2) |
| 167 .Set("export", | 168 .Set("export", |
| 168 DictionaryBuilder().Set("resources", | 169 DictionaryBuilder().Set("resources", |
| 169 ListBuilder().Append("foo.js"))).Build(); | 170 ListBuilder().Append("foo.js"))).Build(); |
| 170 scoped_refptr<Extension> shared_module_1 = | 171 scoped_refptr<Extension> shared_module_1 = |
| 171 ExtensionBuilder().SetManifest(manifest_1.Pass()) | 172 ExtensionBuilder() |
| 172 .AddFlags(Extension::FROM_WEBSTORE) | 173 .SetManifest(manifest_1.Pass()) |
| 173 .SetID(id_util::GenerateId("shared_module_1")) | 174 .AddFlags(Extension::FROM_WEBSTORE) |
| 174 .Build(); | 175 .SetID(crx_file::id_util::GenerateId("shared_module_1")) |
| 176 .Build(); |
| 175 EXPECT_TRUE(InstallExtension(shared_module_1, false)); | 177 EXPECT_TRUE(InstallExtension(shared_module_1, false)); |
| 176 | 178 |
| 177 scoped_ptr<base::DictionaryValue> manifest_2 = | 179 scoped_ptr<base::DictionaryValue> manifest_2 = |
| 178 DictionaryBuilder() | 180 DictionaryBuilder() |
| 179 .Set("name", "Shared Module 2") | 181 .Set("name", "Shared Module 2") |
| 180 .Set("version", "1.0") | 182 .Set("version", "1.0") |
| 181 .Set("manifest_version", 2) | 183 .Set("manifest_version", 2) |
| 182 .Set("export", | 184 .Set("export", |
| 183 DictionaryBuilder().Set("resources", | 185 DictionaryBuilder().Set("resources", |
| 184 ListBuilder().Append("foo.js"))).Build(); | 186 ListBuilder().Append("foo.js"))).Build(); |
| 185 scoped_refptr<Extension> shared_module_2 = | 187 scoped_refptr<Extension> shared_module_2 = |
| 186 ExtensionBuilder().SetManifest(manifest_2.Pass()) | 188 ExtensionBuilder() |
| 187 .AddFlags(Extension::FROM_WEBSTORE) | 189 .SetManifest(manifest_2.Pass()) |
| 188 .SetID(id_util::GenerateId("shared_module_2")) | 190 .AddFlags(Extension::FROM_WEBSTORE) |
| 189 .Build(); | 191 .SetID(crx_file::id_util::GenerateId("shared_module_2")) |
| 192 .Build(); |
| 190 EXPECT_TRUE(InstallExtension(shared_module_2, false)); | 193 EXPECT_TRUE(InstallExtension(shared_module_2, false)); |
| 191 | 194 |
| 192 std::string extension_id = id_util::GenerateId("extension_id"); | 195 std::string extension_id = crx_file::id_util::GenerateId("extension_id"); |
| 193 | 196 |
| 194 // Create and install an extension v1.0 that imports our new module 1. | 197 // Create and install an extension v1.0 that imports our new module 1. |
| 195 scoped_refptr<Extension> importing_extension_1 = | 198 scoped_refptr<Extension> importing_extension_1 = |
| 196 CreateExtensionImportingModule(shared_module_1->id(), | 199 CreateExtensionImportingModule(shared_module_1->id(), |
| 197 extension_id, | 200 extension_id, |
| 198 "1.0"); | 201 "1.0"); |
| 199 EXPECT_TRUE(InstallExtension(importing_extension_1, false)); | 202 EXPECT_TRUE(InstallExtension(importing_extension_1, false)); |
| 200 | 203 |
| 201 // Create and install a new version of the extension that imports our new | 204 // Create and install a new version of the extension that imports our new |
| 202 // module 2. | 205 // module 2. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 222 // Since the extension v1.2 does not depend any module, so the all models | 225 // Since the extension v1.2 does not depend any module, so the all models |
| 223 // should have been uninstalled. | 226 // should have been uninstalled. |
| 224 EXPECT_FALSE(registry()->GetExtensionById(shared_module_1->id(), | 227 EXPECT_FALSE(registry()->GetExtensionById(shared_module_1->id(), |
| 225 ExtensionRegistry::EVERYTHING)); | 228 ExtensionRegistry::EVERYTHING)); |
| 226 EXPECT_FALSE(registry()->GetExtensionById(shared_module_2->id(), | 229 EXPECT_FALSE(registry()->GetExtensionById(shared_module_2->id(), |
| 227 ExtensionRegistry::EVERYTHING)); | 230 ExtensionRegistry::EVERYTHING)); |
| 228 | 231 |
| 229 } | 232 } |
| 230 | 233 |
| 231 TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) { | 234 TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) { |
| 232 std::string whitelisted_id = id_util::GenerateId("whitelisted"); | 235 std::string whitelisted_id = crx_file::id_util::GenerateId("whitelisted"); |
| 233 std::string nonwhitelisted_id = id_util::GenerateId("nonwhitelisted"); | 236 std::string nonwhitelisted_id = |
| 237 crx_file::id_util::GenerateId("nonwhitelisted"); |
| 234 // Create a module which exports to a restricted whitelist. | 238 // Create a module which exports to a restricted whitelist. |
| 235 scoped_ptr<base::DictionaryValue> manifest = | 239 scoped_ptr<base::DictionaryValue> manifest = |
| 236 DictionaryBuilder() | 240 DictionaryBuilder() |
| 237 .Set("name", "Shared Module") | 241 .Set("name", "Shared Module") |
| 238 .Set("version", "1.0") | 242 .Set("version", "1.0") |
| 239 .Set("manifest_version", 2) | 243 .Set("manifest_version", 2) |
| 240 .Set("export", | 244 .Set("export", |
| 241 DictionaryBuilder().Set("whitelist", | 245 DictionaryBuilder().Set("whitelist", |
| 242 ListBuilder() | 246 ListBuilder() |
| 243 .Append(whitelisted_id)) | 247 .Append(whitelisted_id)) |
| 244 .Set("resources", | 248 .Set("resources", |
| 245 ListBuilder().Append("*"))).Build(); | 249 ListBuilder().Append("*"))).Build(); |
| 246 scoped_refptr<Extension> shared_module = | 250 scoped_refptr<Extension> shared_module = |
| 247 ExtensionBuilder().SetManifest(manifest.Pass()) | 251 ExtensionBuilder() |
| 248 .AddFlags(Extension::FROM_WEBSTORE) | 252 .SetManifest(manifest.Pass()) |
| 249 .SetID(id_util::GenerateId("shared_module")) | 253 .AddFlags(Extension::FROM_WEBSTORE) |
| 250 .Build(); | 254 .SetID(crx_file::id_util::GenerateId("shared_module")) |
| 255 .Build(); |
| 251 | 256 |
| 252 EXPECT_TRUE(InstallExtension(shared_module, false)); | 257 EXPECT_TRUE(InstallExtension(shared_module, false)); |
| 253 | 258 |
| 254 // Create and install an extension with the whitelisted ID. | 259 // Create and install an extension with the whitelisted ID. |
| 255 scoped_refptr<Extension> whitelisted_extension = | 260 scoped_refptr<Extension> whitelisted_extension = |
| 256 CreateExtensionImportingModule(shared_module->id(), | 261 CreateExtensionImportingModule(shared_module->id(), |
| 257 whitelisted_id, | 262 whitelisted_id, |
| 258 "1.0"); | 263 "1.0"); |
| 259 EXPECT_TRUE(InstallExtension(whitelisted_extension, false)); | 264 EXPECT_TRUE(InstallExtension(whitelisted_extension, false)); |
| 260 | 265 |
| 261 // Try to install an extension with an ID that is not whitelisted. | 266 // Try to install an extension with an ID that is not whitelisted. |
| 262 scoped_refptr<Extension> nonwhitelisted_extension = | 267 scoped_refptr<Extension> nonwhitelisted_extension = |
| 263 CreateExtensionImportingModule(shared_module->id(), | 268 CreateExtensionImportingModule(shared_module->id(), |
| 264 nonwhitelisted_id, | 269 nonwhitelisted_id, |
| 265 "1.0"); | 270 "1.0"); |
| 266 EXPECT_FALSE(InstallExtension(nonwhitelisted_extension, false)); | 271 EXPECT_FALSE(InstallExtension(nonwhitelisted_extension, false)); |
| 267 } | 272 } |
| 268 | 273 |
| 269 } // namespace extensions | 274 } // namespace extensions |
| OLD | NEW |