diff options
Diffstat (limited to 'chrome/browser/extensions/extensions_service_unittest.cc')
-rw-r--r-- | chrome/browser/extensions/extensions_service_unittest.cc | 544 |
1 files changed, 235 insertions, 309 deletions
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc index 8471fbe..ea01c25 100644 --- a/chrome/browser/extensions/extensions_service_unittest.cc +++ b/chrome/browser/extensions/extensions_service_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -11,24 +11,15 @@ #include "base/message_loop.h" #include "base/path_service.h" #include "base/string_util.h" -#include "base/time.h" #include "chrome/browser/extensions/extension.h" #include "chrome/browser/extensions/extension_error_reporter.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/common/extensions/url_pattern.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/json_value_serializer.h" -#include "chrome/common/notification_registrar.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" -#include "chrome/test/testing_profile.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" -#if defined(OS_WIN) -#include "base/registry.h" -#endif - namespace { struct ExtensionsOrder { @@ -58,79 +49,69 @@ static std::vector<std::string> GetErrors() { } // namespace -class ExtensionsServiceTest - : public testing::Test, public NotificationObserver { +// A mock implementation of ExtensionsServiceFrontendInterface for testing the +// backend. +class ExtensionsServiceTestFrontend + : public ExtensionsServiceFrontendInterface { public: - ExtensionsServiceTest() : installed_(NULL) { - registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, - NotificationService::AllSources()); - registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, - NotificationService::AllSources()); - registrar_.Add(this, NotificationType::EXTENSION_INSTALLED, - NotificationService::AllSources()); - - // Create a temporary area in the registry to test external extensions. - registry_path_ = "Software\\Google\\Chrome\\ExtensionsServiceTest_"; - registry_path_ += IntToString( - static_cast<int>(base::Time::Now().ToDoubleT())); - - profile_.reset(new TestingProfile()); - service_ = new ExtensionsService(profile_.get(), &loop_, &loop_, - registry_path_); + + ~ExtensionsServiceTestFrontend() { + for (ExtensionList::iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + delete *iter; + } } - static void SetUpTestCase() { - ExtensionErrorReporter::Init(false); // no noisy errors + ExtensionList* extensions() { + return &extensions_; } - virtual void SetUp() { - ExtensionErrorReporter::GetInstance()->ClearErrors(); + void ClearInstalledReinstalled() { + installed_ = NULL; + reinstalled_id_ = std::string(); } - virtual void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - switch (type.value) { - case NotificationType::EXTENSIONS_LOADED: { - ExtensionList* list = Details<ExtensionList>(details).ptr(); - for (ExtensionList::iterator iter = list->begin(); iter != list->end(); - ++iter) { - loaded_.push_back(*iter); - } - // The tests rely on the errors being in a certain order, which can vary - // depending on how filesystem iteration works. - std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder()); - break; - } + Extension* installed() { + return installed_; + } - case NotificationType::EXTENSION_UNLOADED: - unloaded_id_ = Details<Extension>(details).ptr()->id(); - break; + std::string reinstalled_id() { + return reinstalled_id_; + } - case NotificationType::EXTENSION_INSTALLED: - installed_ = Details<Extension>(details).ptr(); - break; + // ExtensionsServiceFrontendInterface + virtual MessageLoop* GetMessageLoop() { + return &message_loop_; + } - // TODO(glen): Add tests for themes. - // See: http://code.google.com/p/chromium/issues/detail?id=12231 + virtual void OnExtensionsLoaded(ExtensionList* new_extensions) { + extensions_.insert(extensions_.end(), new_extensions->begin(), + new_extensions->end()); + delete new_extensions; + // In the tests we rely on extensions being in particular order, which is + // not always the case (and is not guaranteed by used APIs). + std::stable_sort(extensions_.begin(), extensions_.end(), ExtensionsOrder()); + } - default: - DCHECK(false); - } + virtual void OnExtensionInstalled(Extension* extension, bool is_update) { + installed_ = extension; + } + + virtual void OnExtensionVersionReinstalled(const std::string& id) { + reinstalled_id_ = id; } void TestInstallExtension(const FilePath& path, + ExtensionsServiceBackend* backend, bool should_succeed) { ASSERT_TRUE(file_util::PathExists(path)); - service_->InstallExtension(path); - loop_.RunAllPending(); + backend->InstallExtension(path, + scoped_refptr<ExtensionsServiceFrontendInterface>(this)); + message_loop_.RunAllPending(); std::vector<std::string> errors = GetErrors(); if (should_succeed) { EXPECT_TRUE(installed_) << path.value(); - EXPECT_EQ(1u, loaded_.size()) << path.value(); EXPECT_EQ(0u, errors.size()) << path.value(); - EXPECT_EQ(1u, service_->extensions()->size()) << path.value(); - EXPECT_TRUE(service_->GetExtensionByID(loaded_[0]->id())) << path.value(); for (std::vector<std::string>::iterator err = errors.begin(); err != errors.end(); ++err) { LOG(ERROR) << *err; @@ -141,55 +122,61 @@ class ExtensionsServiceTest } installed_ = NULL; - loaded_.clear(); ExtensionErrorReporter::GetInstance()->ClearErrors(); } - protected: - scoped_ptr<TestingProfile> profile_; - scoped_refptr<ExtensionsService> service_; - MessageLoop loop_; - std::vector<Extension*> loaded_; - std::string unloaded_id_; + private: + MessageLoop message_loop_; + ExtensionList extensions_; Extension* installed_; - std::string registry_path_; + std::string reinstalled_id_; +}; - private: - NotificationRegistrar registrar_; +// make the test a PlatformTest to setup autorelease pools properly on mac +class ExtensionsServiceTest : public testing::Test { + public: + static void SetUpTestCase() { + ExtensionErrorReporter::Init(false); // no noisy errors + } + + virtual void SetUp() { + ExtensionErrorReporter::GetInstance()->ClearErrors(); + } }; // Test loading good extensions from the profile directory. TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) { - // Copy the test extensions into the test profile. - FilePath source_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); - source_path = source_path.AppendASCII("extensions"); - source_path = source_path.AppendASCII("good"); + FilePath extensions_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); + extensions_path = extensions_path.AppendASCII("extensions"); + extensions_path = extensions_path.AppendASCII("good"); - FilePath dest_path = profile_->GetPath().AppendASCII("Extensions"); - file_util::CopyDirectory(source_path, dest_path, true); // recursive + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(extensions_path, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); - ASSERT_TRUE(service_->Init()); - loop_.RunAllPending(); + std::vector<Extension*> extensions; + backend->LoadExtensionsFromInstallDirectory( + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); std::vector<std::string> errors = GetErrors(); for (std::vector<std::string>::iterator err = errors.begin(); err != errors.end(); ++err) { LOG(ERROR) << *err; } - ASSERT_EQ(3u, loaded_.size()); + ASSERT_EQ(3u, frontend->extensions()->size()); EXPECT_EQ(std::string("00123456789abcdef0123456789abcdef0123456"), - loaded_[0]->id()); + frontend->extensions()->at(0)->id()); EXPECT_EQ(std::string("My extension 1"), - loaded_[0]->name()); + frontend->extensions()->at(0)->name()); EXPECT_EQ(std::string("The first extension that I made."), - loaded_[0]->description()); - EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location()); - EXPECT_TRUE(service_->GetExtensionByID(loaded_[0]->id())); - EXPECT_EQ(3u, service_->extensions()->size()); + frontend->extensions()->at(0)->description()); + EXPECT_EQ(Extension::INTERNAL, frontend->extensions()->at(0)->location()); - Extension* extension = loaded_[0]; + Extension* extension = frontend->extensions()->at(0); const UserScriptList& scripts = extension->content_scripts(); const std::vector<std::string>& toolstrips = extension->toolstrips(); ASSERT_EQ(2u, scripts.size()); @@ -217,39 +204,47 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) { EXPECT_EQ("toolstrip2.html", toolstrips[1]); EXPECT_EQ(std::string("10123456789abcdef0123456789abcdef0123456"), - loaded_[1]->id()); - EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name()); - EXPECT_EQ(std::string(""), loaded_[1]->description()); - EXPECT_EQ(loaded_[1]->path().AppendASCII("npapi").value(), - loaded_[1]->plugins_dir().value()); - EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"), - loaded_[1]->background_url()); - EXPECT_EQ(0u, loaded_[1]->content_scripts().size()); - EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location()); + frontend->extensions()->at(1)->id()); + EXPECT_EQ(std::string("My extension 2"), + frontend->extensions()->at(1)->name()); + EXPECT_EQ(std::string(""), + frontend->extensions()->at(1)->description()); + EXPECT_EQ(frontend->extensions()->at(1)->path().AppendASCII("npapi").value(), + frontend->extensions()->at(1)->plugins_dir().value()); + EXPECT_EQ(frontend->extensions()->at(1)->GetResourceURL("background.html"), + frontend->extensions()->at(1)->background_url()); + EXPECT_EQ(0u, frontend->extensions()->at(1)->content_scripts().size()); + EXPECT_EQ(Extension::INTERNAL, frontend->extensions()->at(1)->location()); EXPECT_EQ(std::string("20123456789abcdef0123456789abcdef0123456"), - loaded_[2]->id()); - EXPECT_EQ(std::string("My extension 3"), loaded_[2]->name()); - EXPECT_EQ(std::string(""), loaded_[2]->description()); - EXPECT_EQ(0u, loaded_[2]->content_scripts().size()); - EXPECT_EQ(Extension::INTERNAL, loaded_[2]->location()); + frontend->extensions()->at(2)->id()); + EXPECT_EQ(std::string("My extension 3"), + frontend->extensions()->at(2)->name()); + EXPECT_EQ(std::string(""), + frontend->extensions()->at(2)->description()); + EXPECT_EQ(0u, frontend->extensions()->at(2)->content_scripts().size()); + EXPECT_EQ(Extension::EXTERNAL, frontend->extensions()->at(2)->location()); }; // Test loading bad extensions from the profile directory. TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) { - FilePath source_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); - source_path = source_path.AppendASCII("extensions"); - source_path = source_path.AppendASCII("bad"); + FilePath extensions_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); + extensions_path = extensions_path.AppendASCII("extensions"); + extensions_path = extensions_path.AppendASCII("bad"); - FilePath dest_path = profile_->GetPath().AppendASCII("Extensions"); - file_util::CopyDirectory(source_path, dest_path, true); // recursive + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(extensions_path, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); - ASSERT_TRUE(service_->Init()); - loop_.RunAllPending(); + std::vector<Extension*> extensions; + backend->LoadExtensionsFromInstallDirectory( + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); - EXPECT_EQ(3u, GetErrors().size()); - EXPECT_EQ(0u, loaded_.size()); + EXPECT_EQ(4u, GetErrors().size()); + EXPECT_EQ(0u, frontend->extensions()->size()); EXPECT_TRUE(MatchPattern(GetErrors()[0], std::string("Could not load extension from '*'. * ") + @@ -262,35 +257,11 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectoryFail) { EXPECT_TRUE(MatchPattern(GetErrors()[2], std::string("Could not load extension from '*'. ") + Extension::kInvalidManifestError)) << GetErrors()[2]; -}; -// Test that partially deleted extensions are cleaned up during startup -// Test loading bad extensions from the profile directory. -TEST_F(ExtensionsServiceTest, CleanupOnStartup) { - FilePath source_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); - source_path = source_path.AppendASCII("extensions"); - source_path = source_path.AppendASCII("good"); - - FilePath dest_path = profile_->GetPath().AppendASCII("Extensions"); - file_util::CopyDirectory(source_path, dest_path, true); // recursive - - // Simulate that one of them got partially deleted by deling the - // Current Version file. - dest_path = dest_path.AppendASCII("extension1") - .AppendASCII(ExtensionsService::kCurrentVersionFileName); - ASSERT_TRUE(file_util::Delete(dest_path, false)); // not recursive - - service_->Init(); - loop_.RunAllPending(); - - // We should have only gotten two extensions now. - EXPECT_EQ(2u, loaded_.size()); - - // And extension1 dir should now be toast. - dest_path = dest_path.DirName(); - ASSERT_FALSE(file_util::PathExists(dest_path)); -} + EXPECT_TRUE(MatchPattern(GetErrors()[3], + "Could not load extension from '*'. Could not read '*' file.")) << + GetErrors()[3]; +}; // Test installing extensions. TEST_F(ExtensionsServiceTest, InstallExtension) { @@ -298,239 +269,194 @@ TEST_F(ExtensionsServiceTest, InstallExtension) { ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); extensions_path = extensions_path.AppendASCII("extensions"); - // A simple extension that should install without error. + FilePath install_dir; + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("ext_test"), + &install_dir); + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(install_dir, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); + FilePath path = extensions_path.AppendASCII("good.crx"); - TestInstallExtension(path, true); + + // A simple extension that should install without error. + frontend->TestInstallExtension(path, backend, true); // TODO(erikkay): verify the contents of the installed extension. // 0-length extension file. path = extensions_path.AppendASCII("not_an_extension.crx"); - TestInstallExtension(path, false); + frontend->TestInstallExtension(path, backend, false); // Bad magic number. path = extensions_path.AppendASCII("bad_magic.crx"); - TestInstallExtension(path, false); + frontend->TestInstallExtension(path, backend, false); // Poorly formed JSON. path = extensions_path.AppendASCII("bad_json.crx"); - TestInstallExtension(path, false); + frontend->TestInstallExtension(path, backend, false); // Incorrect zip hash. path = extensions_path.AppendASCII("bad_hash.crx"); - TestInstallExtension(path, false); + frontend->TestInstallExtension(path, backend, false); // TODO(erikkay): add more tests for many of the failure cases. // TODO(erikkay): add tests for upgrade cases. } -// Test that when an extension version is reinstalled, nothing happens. -TEST_F(ExtensionsServiceTest, Reinstall) { +// Tests uninstalling extensions +TEST_F(ExtensionsServiceTest, UninstallExtension) { FilePath extensions_path; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); extensions_path = extensions_path.AppendASCII("extensions"); - // A simple extension that should install without error. - FilePath path = extensions_path.AppendASCII("good.crx"); - service_->InstallExtension(path); - loop_.RunAllPending(); - - ASSERT_TRUE(installed_); - ASSERT_EQ(1u, loaded_.size()); - ASSERT_EQ(0u, GetErrors().size()); - - installed_ = NULL; - loaded_.clear(); - ExtensionErrorReporter::GetInstance()->ClearErrors(); - - // Reinstall the same version, nothing should happen. - service_->InstallExtension(path); - loop_.RunAllPending(); - - ASSERT_FALSE(installed_); - ASSERT_EQ(0u, loaded_.size()); - ASSERT_EQ(0u, GetErrors().size()); -} + FilePath install_path; + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("ext_test"), + &install_path); + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(install_path, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); -// Tests uninstalling normal extensions -TEST_F(ExtensionsServiceTest, UninstallExtension) { - FilePath extensions_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); - extensions_path = extensions_path.AppendASCII("extensions"); + FilePath path = extensions_path.AppendASCII("good.crx"); // A simple extension that should install without error. - FilePath path = extensions_path.AppendASCII("good.crx"); - TestInstallExtension(path, true); + frontend->TestInstallExtension(path, backend, true); // The directory should be there now. - FilePath install_path = profile_->GetPath().AppendASCII("Extensions"); const char* extension_id = "00123456789abcdef0123456789abcdef0123456"; FilePath extension_path = install_path.AppendASCII(extension_id); EXPECT_TRUE(file_util::PathExists(extension_path)); - // Uninstall it. - service_->UninstallExtension(extension_id); - - // We should get an unload notification. - ASSERT_TRUE(unloaded_id_.length()); - EXPECT_EQ(extension_id, unloaded_id_); - - // The extension should not be in the service anymore. - ASSERT_FALSE(service_->GetExtensionByID(extension_id)); - loop_.RunAllPending(); - - // The directory should be gone. + // Uninstall it, directory should be gone. + backend->UninstallExtension(extension_id); EXPECT_FALSE(file_util::PathExists(extension_path)); // Try uinstalling one that doesn't have a Current Version file for some // reason. - unloaded_id_.clear(); - TestInstallExtension(path, true); + frontend->TestInstallExtension(path, backend, true); FilePath current_version_file = extension_path.AppendASCII(ExtensionsService::kCurrentVersionFileName); EXPECT_TRUE(file_util::Delete(current_version_file, true)); - service_->UninstallExtension(extension_id); - loop_.RunAllPending(); + backend->UninstallExtension(extension_id); EXPECT_FALSE(file_util::PathExists(extension_path)); + + // Try uninstalling one that doesn't even exist. We shouldn't crash. + backend->UninstallExtension(extension_id); +} + +TEST_F(ExtensionsServiceTest, ReinstallExtension) { + // In this test, we install two extensions, verify that they both install + // correctly, then install the first extension again and verify that it was + // not installed, and that VersionReinstalled was called instead. + FilePath extensions_path; + ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); + extensions_path = extensions_path.AppendASCII("extensions"); + + FilePath install_dir; + file_util::CreateNewTempDirectory(FILE_PATH_LITERAL("ext_test"), + &install_dir); + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(install_dir, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); + + FilePath path = extensions_path.AppendASCII("good.crx"); + FilePath path2 = extensions_path.AppendASCII("theme.crx"); + + // Verify that our extensions are valid. + ASSERT_TRUE(file_util::PathExists(path)); + ASSERT_TRUE(file_util::PathExists(path2)); + + frontend->ClearInstalledReinstalled(); + // Install an extension. + backend->InstallExtension(path, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); + std::vector<std::string> errors = GetErrors(); + + // Verify that it was installed. + EXPECT_TRUE(frontend->installed()) << path.value(); + EXPECT_EQ(0u, errors.size()) << path.value(); + + // Install our second extension. + frontend->ClearInstalledReinstalled(); + backend->InstallExtension(path2, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); + errors = GetErrors(); + + // Verify that it was installed without reinstall getting called. + EXPECT_TRUE(frontend->installed()) << path2.value(); + EXPECT_TRUE(frontend->reinstalled_id().empty()); + EXPECT_EQ(0u, errors.size()) << path.value(); + + // Install the first extension again. + frontend->ClearInstalledReinstalled(); + backend->InstallExtension(path, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); + errors = GetErrors(); + + // Verify that reinstall was called and installed was not. + EXPECT_FALSE(frontend->installed()) << path.value(); + EXPECT_FALSE(frontend->reinstalled_id().empty()) << path.value(); + EXPECT_EQ(0u, errors.size()) << path.value(); } -// Tests loading single extensions (like --load-extension) TEST_F(ExtensionsServiceTest, LoadExtension) { FilePath extensions_path; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); extensions_path = extensions_path.AppendASCII("extensions"); + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(extensions_path, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); + FilePath ext1 = extensions_path.AppendASCII("good").AppendASCII("extension1") .AppendASCII("1"); - service_->LoadExtension(ext1); - loop_.RunAllPending(); + backend->LoadSingleExtension(ext1, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); EXPECT_EQ(0u, GetErrors().size()); - ASSERT_EQ(1u, loaded_.size()); - ASSERT_EQ(Extension::LOAD, loaded_[0]->location()); + ASSERT_EQ(1u, frontend->extensions()->size()); FilePath no_manifest = extensions_path.AppendASCII("bad") .AppendASCII("no_manifest").AppendASCII("1"); - service_->LoadExtension(no_manifest); - loop_.RunAllPending(); + backend->LoadSingleExtension(no_manifest, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); EXPECT_EQ(1u, GetErrors().size()); - ASSERT_EQ(1u, loaded_.size()); - - // Test uninstall - std::string id = loaded_[0]->id(); - EXPECT_FALSE(unloaded_id_.length()); - service_->UninstallExtension(id); - loop_.RunAllPending(); - EXPECT_EQ(id, unloaded_id_); + ASSERT_EQ(1u, frontend->extensions()->size()); + ASSERT_EQ(Extension::LOAD, frontend->extensions()->at(0)->location()); } -// Tests that we generate IDs when they are not specified in the manifest for -// --load-extension. TEST_F(ExtensionsServiceTest, GenerateID) { FilePath extensions_path; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extensions_path)); extensions_path = extensions_path.AppendASCII("extensions"); + scoped_refptr<ExtensionsServiceBackend> backend( + new ExtensionsServiceBackend(extensions_path, NULL)); + scoped_refptr<ExtensionsServiceTestFrontend> frontend( + new ExtensionsServiceTestFrontend); + FilePath no_id_ext = extensions_path.AppendASCII("no_id"); - service_->LoadExtension(no_id_ext); - loop_.RunAllPending(); + backend->LoadSingleExtension(no_id_ext, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); EXPECT_EQ(0u, GetErrors().size()); - ASSERT_EQ(1u, loaded_.size()); - std::string id1 = loaded_[0]->id(); + ASSERT_EQ(1u, frontend->extensions()->size()); + std::string id1 = frontend->extensions()->at(0)->id(); ASSERT_EQ("0000000000000000000000000000000000000000", id1); ASSERT_EQ("chrome-extension://0000000000000000000000000000000000000000/", - loaded_[0]->url().spec()); + frontend->extensions()->at(0)->url().spec()); - service_->LoadExtension(no_id_ext); - loop_.RunAllPending(); - std::string id2 = loaded_[1]->id(); + backend->LoadSingleExtension(no_id_ext, + scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get())); + frontend->GetMessageLoop()->RunAllPending(); + std::string id2 = frontend->extensions()->at(1)->id(); ASSERT_EQ("0000000000000000000000000000000000000001", id2); ASSERT_EQ("chrome-extension://0000000000000000000000000000000000000001/", - loaded_[1]->url().spec()); + frontend->extensions()->at(1)->url().spec()); } - -// Tests the external installation feature -#if defined(OS_WIN) - -TEST_F(ExtensionsServiceTest, ExternalInstall) { - // Register a test extension externally. - FilePath source_path; - ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &source_path)); - source_path = source_path.AppendASCII("extensions").AppendASCII("good.crx"); - - RegKey key; - std::wstring reg_path = ASCIIToWide(registry_path_); - reg_path += L"\\00123456789ABCDEF0123456789ABCDEF0123456"; - ASSERT_TRUE(key.Create(HKEY_LOCAL_MACHINE, reg_path.c_str(), KEY_WRITE)); - ASSERT_TRUE(key.WriteValue(L"path", source_path.ToWStringHack().c_str())); - ASSERT_TRUE(key.WriteValue(L"version", L"1.0.0.0")); - - // Start up the service, it should find our externally registered extension - // and install it. - service_->Init(); - loop_.RunAllPending(); - - ASSERT_EQ(0u, GetErrors().size()); - ASSERT_EQ(1u, loaded_.size()); - ASSERT_EQ(Extension::EXTERNAL, loaded_[0]->location()); - ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); - - // Reinit the service without changing anything. The extension should be - // loaded again. - loaded_.clear(); - service_->Init(); - loop_.RunAllPending(); - ASSERT_EQ(0u, GetErrors().size()); - ASSERT_EQ(1u, loaded_.size()); - - // Now update the extension with a new version. We should get upgraded. - source_path = source_path.DirName().AppendASCII("good2.crx"); - ASSERT_TRUE(key.WriteValue(L"path", source_path.ToWStringHack().c_str())); - ASSERT_TRUE(key.WriteValue(L"version", L"1.0.0.1")); - - loaded_.clear(); - service_->Init(); - loop_.RunAllPending(); - ASSERT_EQ(0u, GetErrors().size()); - ASSERT_EQ(1u, loaded_.size()); - ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString()); - - // Uninstall the extension and reinit. Nothing should happen because the - // preference should prevent us from reinstalling. - std::string id = loaded_[0]->id(); - service_->UninstallExtension(id); - loop_.RunAllPending(); - - // The extension should also be gone from the install directory. - FilePath install_path = profile_->GetPath().AppendASCII("Extensions") - .AppendASCII(id); - ASSERT_FALSE(file_util::PathExists(install_path)); - - loaded_.clear(); - service_->Init(); - loop_.RunAllPending(); - ASSERT_EQ(0u, loaded_.size()); - - // Now clear the preference, reinstall, then remove the reg key. The extension - // should be uninstalled. - profile_->GetPrefs()->GetMutableList(L"extensions.uninstalled_external_ids") - ->Clear(); - profile_->GetPrefs()->ScheduleSavePersistentPrefs(); - - loaded_.clear(); - service_->Init(); - loop_.RunAllPending(); - ASSERT_EQ(1u, loaded_.size()); - - RegKey parent_key; - key.Open(HKEY_LOCAL_MACHINE, ASCIIToWide(registry_path_).c_str(), KEY_WRITE); - key.DeleteKey(ASCIIToWide(id).c_str()); - loaded_.clear(); - service_->Init(); - loop_.RunAllPending(); - ASSERT_EQ(0u, loaded_.size()); -} - -#else - -// TODO(port) - -#endif |