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 3 // found in the LICENSE file. 4 5 #include "base/bind.h" 6 #include "base/command_line.h" 7 #include "base/files/file_util.h" 8 #include "base/memory/ref_counted.h" 9 #include "base/message_loop/message_loop.h" 10 #include "base/path_service.h" 11 #include "base/run_loop.h" 12 #include "base/strings/string_util.h" 13 #include "base/values.h" 14 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/test_extension_system.h" 16 #include "chrome/browser/extensions/zipfile_installer.h" 17 #include "chrome/common/chrome_paths.h" 18 #include "chrome/test/base/testing_profile.h" 19 #include "content/public/test/test_browser_thread_bundle.h" 20 #include "content/public/test/test_utils.h" 21 #include "extensions/browser/extension_registry.h" 22 #include "extensions/browser/extension_registry_observer.h" 23 #include "extensions/common/constants.h" 24 #include "extensions/common/extension.h" 25 #include "testing/gtest/include/gtest/gtest.h" 26 27 #if defined(OS_CHROMEOS) 28 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h" 29 #include "chrome/browser/chromeos/settings/cros_settings.h" 30 #include "chrome/browser/chromeos/settings/device_settings_service.h" 31 #endif 32 33 namespace extensions { 34 35 namespace { 36 37 struct MockExtensionRegistryObserver : public ExtensionRegistryObserver { 38 void WaitForInstall() { 39 scoped_refptr<content::MessageLoopRunner> runner = 40 new content::MessageLoopRunner; 41 quit_closure_ = runner->QuitClosure(); 42 runner->Run(); 43 } 44 45 virtual void OnExtensionWillBeInstalled( 46 content::BrowserContext* browser_context, 47 const Extension* extension, 48 bool is_update, 49 bool from_ephemeral, 50 const std::string& old_name) OVERRIDE { 51 last_extension_installed = extension->id(); 52 quit_closure_.Run(); 53 } 54 55 std::string last_extension_installed; 56 base::Closure quit_closure_; 57 }; 58 59 } // namespace 60 61 class ZipFileInstallerTest : public testing::Test { 62 public: 63 ZipFileInstallerTest() 64 : browser_threads_(content::TestBrowserThreadBundle::IO_MAINLOOP) {} 65 66 virtual void SetUp() { 67 in_process_utility_thread_helper_.reset( 68 new content::InProcessUtilityThreadHelper); 69 70 // Create profile for extension service. 71 profile_.reset(new TestingProfile()); 72 TestExtensionSystem* system = 73 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(profile_.get())); 74 extension_service_ = system->CreateExtensionService( 75 base::CommandLine::ForCurrentProcess(), base::FilePath(), false); 76 ExtensionRegistry* registry(ExtensionRegistry::Get(profile_.get())); 77 registry->AddObserver(&observer_); 78 } 79 80 virtual void TearDown() { 81 // Need to destruct ZipFileInstaller before the message loop since 82 // it posts a task to it. 83 zipfile_installer_ = NULL; 84 ExtensionRegistry* registry(ExtensionRegistry::Get(profile_.get())); 85 registry->RemoveObserver(&observer_); 86 profile_.reset(); 87 base::RunLoop().RunUntilIdle(); 88 } 89 90 void RunInstaller(const std::string& zip_name) { 91 base::FilePath original_path; 92 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &original_path)); 93 original_path = original_path.AppendASCII("extensions") 94 .AppendASCII("zipfile_installer") 95 .AppendASCII(zip_name); 96 ASSERT_TRUE(base::PathExists(original_path)) << original_path.value(); 97 98 zipfile_installer_ = ZipFileInstaller::Create(extension_service_); 99 100 base::MessageLoopProxy::current()->PostTask( 101 FROM_HERE, 102 base::Bind(&ZipFileInstaller::LoadFromZipFile, 103 zipfile_installer_.get(), 104 original_path)); 105 observer_.WaitForInstall(); 106 } 107 108 protected: 109 scoped_refptr<ZipFileInstaller> zipfile_installer_; 110 111 scoped_ptr<TestingProfile> profile_; 112 ExtensionService* extension_service_; 113 114 content::TestBrowserThreadBundle browser_threads_; 115 scoped_ptr<content::InProcessUtilityThreadHelper> 116 in_process_utility_thread_helper_; 117 MockExtensionRegistryObserver observer_; 118 119 #if defined(OS_CHROMEOS) 120 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 121 chromeos::ScopedTestCrosSettings test_cros_settings_; 122 // ChromeOS needs a user manager to instantiate an extension service. 123 chromeos::ScopedTestUserManager test_user_manager_; 124 #endif 125 }; 126 127 TEST_F(ZipFileInstallerTest, GoodZip) { 128 RunInstaller("good.zip"); 129 } 130 131 TEST_F(ZipFileInstallerTest, ZipWithPublicKey) { 132 RunInstaller("public_key.zip"); 133 const char kIdForPublicKey[] = "ikppjpenhoddphklkpdfdfdabbakkpal"; 134 EXPECT_EQ(observer_.last_extension_installed, kIdForPublicKey); 135 } 136 137 } // namespace extensions 138