1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/memory/ref_counted.h" 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/memory/scoped_ptr.h" 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/strings/string16.h" 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/values.h" 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/extension_service.h" 10f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/extensions/extension_service_test_base.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/pending_extension_manager.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/shared_module_service.h" 130de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "chrome/common/extensions/features/feature_channel.h" 1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/browser/extension_registry.h" 16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/browser/install_flag.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "extensions/browser/uninstall_reason.h" 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension_builder.h" 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/value_builder.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "sync/api/string_ordinal.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace extensions { 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace { 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Return an extension with |id| which imports a module with the given 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// |import_id|. 28c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochscoped_refptr<Extension> CreateExtensionImportingModule( 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& import_id, 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& id, 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& version) { 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DictionaryBuilder builder; 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch builder.Set("name", "Has Dependent Modules") 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("version", version) 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("manifest_version", 2); 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!import_id.empty()) { 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch builder.Set("import", 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ListBuilder().Append(DictionaryBuilder().Set("id", import_id))); 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::DictionaryValue> manifest = builder.Build(); 41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return ExtensionBuilder().SetManifest(manifest.Pass()) 43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch .AddFlags(Extension::FROM_WEBSTORE) 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .SetID(id) 45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch .Build(); 46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 48c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass SharedModuleServiceUnitTest : public ExtensionServiceTestBase { 510de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) public: 520de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) SharedModuleServiceUnitTest() : 530de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // The "export" key is open for dev-channel only, but unit tests 540de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) // run as stable channel on the official Windows build. 550de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) current_channel_(chrome::VersionInfo::CHANNEL_UNKNOWN) {} 56c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch protected: 57c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual void SetUp() OVERRIDE; 58c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Install an extension and notify the ExtensionService. 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch testing::AssertionResult InstallExtension(const Extension* extension, 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool is_update); 620de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles) ScopedCurrentChannel current_channel_; 63c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 64c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 65c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid SharedModuleServiceUnitTest::SetUp() { 66c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ExtensionServiceTestBase::SetUp(); 67c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch InitializeGoodInstalledExtensionService(); 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service()->Init(); 69c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 70c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochtesting::AssertionResult SharedModuleServiceUnitTest::InstallExtension( 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Extension* extension, 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool is_update) { 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const Extension* old = registry()->GetExtensionById( 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension->id(), 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionRegistry::ENABLED); 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Verify the extension is not already installed, if it is not update. 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!is_update) { 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (old) 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return testing::AssertionFailure() << "Extension already installed."; 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else { 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!old) 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return testing::AssertionFailure() << "The extension does not exist."; 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 87c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Notify the service that the extension is installed. This adds it to the 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // registry, notifies interested parties, etc. 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service()->OnExtensionInstalled( 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extension, syncer::StringOrdinal(), kInstallFlagInstallImmediately); 92c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 93c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Verify that the extension is now installed. 94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!registry()->GetExtensionById(extension->id(), 95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ExtensionRegistry::ENABLED)) { 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return testing::AssertionFailure() << "Could not install extension."; 97c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 98c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return testing::AssertionSuccess(); 100c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 102c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(SharedModuleServiceUnitTest, AddDependentSharedModules) { 103c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Create an extension that has a dependency. 10403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string import_id = crx_file::id_util::GenerateId("id"); 10503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string extension_id = crx_file::id_util::GenerateId("extension_id"); 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_refptr<Extension> extension = 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule(import_id, extension_id, "1.0"); 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch PendingExtensionManager* pending_extension_manager = 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service()->pending_extension_manager(); 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Verify that we don't currently want to install the imported module. 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_FALSE(pending_extension_manager->IsIdPending(import_id)); 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Try to satisfy imports for the extension. This should queue the imported 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // module's installation. 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service()->shared_module_service()->SatisfyImports(extension.get()); 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(pending_extension_manager->IsIdPending(import_id)); 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochTEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUninstall) { 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Create a module which exports a resource, and install it. 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_ptr<base::DictionaryValue> manifest = 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DictionaryBuilder() 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch .Set("name", "Shared Module") 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch .Set("version", "1.0") 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch .Set("manifest_version", 2) 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch .Set("export", 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DictionaryBuilder().Set("resources", 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ListBuilder().Append("foo.js"))).Build(); 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_refptr<Extension> shared_module = 13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ExtensionBuilder() 13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetManifest(manifest.Pass()) 13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .AddFlags(Extension::FROM_WEBSTORE) 13503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetID(crx_file::id_util::GenerateId("shared_module")) 13603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .Build(); 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(shared_module.get(), false)); 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string extension_id = crx_file::id_util::GenerateId("extension_id"); 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Create and install an extension that imports our new module. 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_refptr<Extension> importing_extension = 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule(shared_module->id(), extension_id, "1.0"); 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(importing_extension.get(), false)); 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Uninstall the extension that imports our module. 147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::string16 error; 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch service()->UninstallExtension(importing_extension->id(), 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extensions::UNINSTALL_REASON_FOR_TESTING, 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&base::DoNothing), 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &error); 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch EXPECT_TRUE(error.empty()); 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Since the module was only referenced by that single extension, it should 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // have been uninstalled as a side-effect of uninstalling the extension that 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // depended upon it. 157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_FALSE(registry()->GetExtensionById(shared_module->id(), 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ExtensionRegistry::EVERYTHING)); 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 161116680a4aac90f2aa7413d9095a592090648e557Ben MurdochTEST_F(SharedModuleServiceUnitTest, PruneSharedModulesOnUpdate) { 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Create two modules which export a resource, and install them. 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::DictionaryValue> manifest_1 = 164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DictionaryBuilder() 165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("name", "Shared Module 1") 166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("version", "1.0") 167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("manifest_version", 2) 168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("export", 169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DictionaryBuilder().Set("resources", 170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ListBuilder().Append("foo.js"))).Build(); 171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<Extension> shared_module_1 = 17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ExtensionBuilder() 17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetManifest(manifest_1.Pass()) 17403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .AddFlags(Extension::FROM_WEBSTORE) 17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetID(crx_file::id_util::GenerateId("shared_module_1")) 17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .Build(); 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(shared_module_1.get(), false)); 178116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 179116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<base::DictionaryValue> manifest_2 = 180116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DictionaryBuilder() 181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("name", "Shared Module 2") 182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("version", "1.0") 183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("manifest_version", 2) 184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .Set("export", 185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DictionaryBuilder().Set("resources", 186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ListBuilder().Append("foo.js"))).Build(); 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<Extension> shared_module_2 = 18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ExtensionBuilder() 18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetManifest(manifest_2.Pass()) 19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .AddFlags(Extension::FROM_WEBSTORE) 19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetID(crx_file::id_util::GenerateId("shared_module_2")) 19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .Build(); 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(shared_module_2.get(), false)); 194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string extension_id = crx_file::id_util::GenerateId("extension_id"); 196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Create and install an extension v1.0 that imports our new module 1. 198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<Extension> importing_extension_1 = 199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule(shared_module_1->id(), 200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_id, 201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "1.0"); 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(importing_extension_1.get(), false)); 203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Create and install a new version of the extension that imports our new 205116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // module 2. 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<Extension> importing_extension_2 = 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule(shared_module_2->id(), 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension_id, 209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "1.1"); 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(importing_extension_2.get(), true)); 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Since the extension v1.1 depends the module 2 insteand module 1. 213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // So the module 1 should be uninstalled. 214116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(registry()->GetExtensionById(shared_module_1->id(), 215116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionRegistry::EVERYTHING)); 216116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(registry()->GetExtensionById(shared_module_2->id(), 217116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionRegistry::EVERYTHING)); 218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 219116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Create and install a new version of the extension that does not import any 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // module. 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<Extension> importing_extension_3 = 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule("", extension_id, "1.2"); 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(importing_extension_3.get(), true)); 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // Since the extension v1.2 does not depend any module, so the all models 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // should have been uninstalled. 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(registry()->GetExtensionById(shared_module_1->id(), 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionRegistry::EVERYTHING)); 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_FALSE(registry()->GetExtensionById(shared_module_2->id(), 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ExtensionRegistry::EVERYTHING)); 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2340de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)TEST_F(SharedModuleServiceUnitTest, WhitelistedImports) { 23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string whitelisted_id = crx_file::id_util::GenerateId("whitelisted"); 23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::string nonwhitelisted_id = 23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) crx_file::id_util::GenerateId("nonwhitelisted"); 238010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Create a module which exports to a restricted whitelist. 239010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_ptr<base::DictionaryValue> manifest = 240010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DictionaryBuilder() 241010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .Set("name", "Shared Module") 242010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .Set("version", "1.0") 243010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .Set("manifest_version", 2) 244010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .Set("export", 245010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DictionaryBuilder().Set("whitelist", 246010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ListBuilder() 247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .Append(whitelisted_id)) 248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) .Set("resources", 249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ListBuilder().Append("*"))).Build(); 250010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<Extension> shared_module = 25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ExtensionBuilder() 25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetManifest(manifest.Pass()) 25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .AddFlags(Extension::FROM_WEBSTORE) 25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .SetID(crx_file::id_util::GenerateId("shared_module")) 25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) .Build(); 256010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(shared_module.get(), false)); 258010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 259010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Create and install an extension with the whitelisted ID. 260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<Extension> whitelisted_extension = 261116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule(shared_module->id(), 262116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch whitelisted_id, 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "1.0"); 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(whitelisted_extension.get(), false)); 265010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 266010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Try to install an extension with an ID that is not whitelisted. 267010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<Extension> nonwhitelisted_extension = 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch CreateExtensionImportingModule(shared_module->id(), 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch nonwhitelisted_id, 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "1.0"); 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This should succeed because only CRX installer (and by extension the 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // WebStore Installer) checks the shared module whitelist. InstallExtension 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // bypasses the whitelist check because the SharedModuleService does not 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // care about whitelists. 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_TRUE(InstallExtension(nonwhitelisted_extension.get(), false)); 276010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 277010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 278c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace extensions 279