Index: chrome/browser/extensions/extension_service_unittest.cc |
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc |
index 8047d11b1c2e51ca1692e5a014c167b0073568f7..27b95131df6fe514d719989d232efafe3eea77e8 100644 |
--- a/chrome/browser/extensions/extension_service_unittest.cc |
+++ b/chrome/browser/extensions/extension_service_unittest.cc |
@@ -97,6 +97,7 @@ |
#include "extensions/browser/extension_prefs.h" |
#include "extensions/browser/extension_registry.h" |
#include "extensions/browser/extension_system.h" |
+#include "extensions/browser/external_install_info.h" |
#include "extensions/browser/external_provider_interface.h" |
#include "extensions/browser/install_flag.h" |
#include "extensions/browser/management_policy.h" |
@@ -163,6 +164,9 @@ using extensions::ExtensionRegistry; |
using extensions::ExtensionResource; |
using extensions::ExtensionSystem; |
using extensions::ExternalInstallError; |
+using extensions::ExternalInstallInfoFile; |
+using extensions::ExternalInstallInfoUpdateUrl; |
+using extensions::ExternalProviderInterface; |
using extensions::FakeSafeBrowsingDatabaseManager; |
using extensions::FeatureSwitch; |
using extensions::Manifest; |
@@ -248,11 +252,12 @@ class MockExtensionProvider : public extensions::ExternalProviderInterface { |
visit_count_++; |
for (DataMap::const_iterator i = extension_map_.begin(); |
i != extension_map_.end(); ++i) { |
- Version version(i->second.first); |
+ scoped_ptr<Version> version(new Version(i->second.first)); |
- visitor_->OnExternalExtensionFileFound( |
- i->first, &version, i->second.second, location_, |
- Extension::NO_FLAGS, false, false); |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ i->first, std::move(version), i->second.second, location_, |
+ Extension::NO_FLAGS, false, false)); |
+ visitor_->OnExternalExtensionFileFound(*info); |
} |
visitor_->OnExternalProviderReady(this); |
} |
@@ -324,26 +329,22 @@ class MockProviderVisitor |
} |
int Visit(const std::string& json_data) { |
+ return Visit(json_data, Manifest::EXTERNAL_PREF, |
+ Manifest::EXTERNAL_PREF_DOWNLOAD); |
+ } |
+ |
+ int Visit(const std::string& json_data, |
+ Manifest::Location crx_location, |
+ Manifest::Location download_location) { |
+ crx_location_ = crx_location; |
// Give the test json file to the provider for parsing. |
provider_.reset(new extensions::ExternalProviderImpl( |
- this, |
- new extensions::ExternalTestingLoader(json_data, fake_base_path_), |
- profile_.get(), |
- Manifest::EXTERNAL_PREF, |
- Manifest::EXTERNAL_PREF_DOWNLOAD, |
- Extension::NO_FLAGS)); |
+ this, new extensions::ExternalTestingLoader(json_data, fake_base_path_), |
+ profile_.get(), crx_location, download_location, Extension::NO_FLAGS)); |
// We also parse the file into a dictionary to compare what we get back |
// from the provider. |
- JSONStringValueDeserializer deserializer(json_data); |
- scoped_ptr<base::Value> json_value = deserializer.Deserialize(NULL, NULL); |
- |
- if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) { |
- NOTREACHED() << "Unable to deserialize json data"; |
- return -1; |
- } else { |
- prefs_ = base::DictionaryValue::From(std::move(json_value)); |
- } |
+ prefs_ = GetDictionaryFromJSON(json_data); |
// Reset our counter. |
ids_found_ = 0; |
@@ -353,85 +354,90 @@ class MockProviderVisitor |
return ids_found_; |
} |
- bool OnExternalExtensionFileFound(const std::string& id, |
- const Version* version, |
- const base::FilePath& path, |
- Manifest::Location unused, |
- int creation_flags, |
- bool mark_acknowledged, |
- bool install_immediately) override { |
- EXPECT_EQ(expected_creation_flags_, creation_flags); |
+ bool OnExternalExtensionFileFound( |
+ const ExternalInstallInfoFile& info) override { |
+ EXPECT_EQ(expected_creation_flags_, info.creation_flags); |
++ids_found_; |
base::DictionaryValue* pref; |
// This tests is to make sure that the provider only notifies us of the |
// values we gave it. So if the id we doesn't exist in our internal |
// dictionary then something is wrong. |
- EXPECT_TRUE(prefs_->GetDictionary(id, &pref)) |
- << "Got back ID (" << id.c_str() << ") we weren't expecting"; |
+ EXPECT_TRUE(prefs_->GetDictionary(info.extension_id, &pref)) |
+ << "Got back ID (" << info.extension_id.c_str() |
+ << ") we weren't expecting"; |
- EXPECT_TRUE(path.IsAbsolute()); |
+ EXPECT_TRUE(info.path.IsAbsolute()); |
if (!fake_base_path_.empty()) |
- EXPECT_TRUE(fake_base_path_.IsParent(path)); |
+ EXPECT_TRUE(fake_base_path_.IsParent(info.path)); |
if (pref) { |
- EXPECT_TRUE(provider_->HasExtension(id)); |
+ EXPECT_TRUE(provider_->HasExtension(info.extension_id)); |
// Ask provider if the extension we got back is registered. |
Manifest::Location location = Manifest::INVALID_LOCATION; |
scoped_ptr<Version> v1; |
base::FilePath crx_path; |
- EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1)); |
- EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); |
+ EXPECT_TRUE(provider_->GetExtensionDetails(info.extension_id, NULL, &v1)); |
+ EXPECT_STREQ(info.version->GetString().c_str(), v1->GetString().c_str()); |
scoped_ptr<Version> v2; |
- EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2)); |
- EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); |
- EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str()); |
- EXPECT_EQ(Manifest::EXTERNAL_PREF, location); |
+ EXPECT_TRUE( |
+ provider_->GetExtensionDetails(info.extension_id, &location, &v2)); |
+ EXPECT_STREQ(info.version->GetString().c_str(), v1->GetString().c_str()); |
+ EXPECT_STREQ(info.version->GetString().c_str(), v2->GetString().c_str()); |
+ EXPECT_EQ(crx_location_, location); |
// Remove it so we won't count it ever again. |
- prefs_->Remove(id, NULL); |
+ prefs_->Remove(info.extension_id, NULL); |
} |
return true; |
} |
- bool OnExternalExtensionUpdateUrlFound(const std::string& id, |
- const std::string& install_parameter, |
- const GURL& update_url, |
- Manifest::Location location, |
- int creation_flags, |
- bool mark_acknowledged) override { |
+ bool OnExternalExtensionUpdateUrlFound( |
+ const ExternalInstallInfoUpdateUrl& info, |
+ bool is_initial_load) override { |
++ids_found_; |
base::DictionaryValue* pref; |
// This tests is to make sure that the provider only notifies us of the |
// values we gave it. So if the id we doesn't exist in our internal |
// dictionary then something is wrong. |
- EXPECT_TRUE(prefs_->GetDictionary(id, &pref)) |
- << L"Got back ID (" << id.c_str() << ") we weren't expecting"; |
- EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location); |
+ EXPECT_TRUE(prefs_->GetDictionary(info.extension_id, &pref)) |
+ << L"Got back ID (" << info.extension_id.c_str() |
+ << ") we weren't expecting"; |
+ EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, info.download_location); |
if (pref) { |
- EXPECT_TRUE(provider_->HasExtension(id)); |
+ EXPECT_TRUE(provider_->HasExtension(info.extension_id)); |
// External extensions with update URLs do not have versions. |
scoped_ptr<Version> v1; |
Manifest::Location location1 = Manifest::INVALID_LOCATION; |
- EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1)); |
+ EXPECT_TRUE( |
+ provider_->GetExtensionDetails(info.extension_id, &location1, &v1)); |
EXPECT_FALSE(v1.get()); |
EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1); |
std::string parsed_install_parameter; |
pref->GetString("install_parameter", &parsed_install_parameter); |
- EXPECT_EQ(parsed_install_parameter, install_parameter); |
+ EXPECT_EQ(parsed_install_parameter, info.install_parameter); |
// Remove it so we won't count it again. |
- prefs_->Remove(id, NULL); |
+ prefs_->Remove(info.extension_id, NULL); |
} |
return true; |
} |
+ void OnExternalProviderUpdateComplete( |
+ const ExternalProviderInterface* provider, |
+ const ScopedVector<ExternalInstallInfoUpdateUrl>& update_url_extensions, |
+ const ScopedVector<ExternalInstallInfoFile>& file_extensions, |
+ const std::set<std::string>& removed_extensions) override { |
+ ADD_FAILURE() << "MockProviderVisitor does not provide incremental updates," |
+ " use MockUpdateProviderVisitor instead."; |
+ } |
+ |
void OnExternalProviderReady( |
const extensions::ExternalProviderInterface* provider) override { |
EXPECT_EQ(provider, provider_.get()); |
@@ -440,17 +446,98 @@ class MockProviderVisitor |
Profile* profile() { return profile_.get(); } |
+ protected: |
+ scoped_ptr<extensions::ExternalProviderImpl> provider_; |
+ |
+ scoped_ptr<base::DictionaryValue> GetDictionaryFromJSON( |
+ const std::string& json_data) { |
+ // We also parse the file into a dictionary to compare what we get back |
+ // from the provider. |
+ JSONStringValueDeserializer deserializer(json_data); |
+ scoped_ptr<base::Value> json_value = deserializer.Deserialize(NULL, NULL); |
+ |
+ if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) { |
+ ADD_FAILURE() << "Unable to deserialize json data"; |
+ return scoped_ptr<base::DictionaryValue>(); |
+ } else { |
+ return base::DictionaryValue::From(std::move(json_value)); |
+ } |
+ } |
+ |
private: |
int ids_found_; |
base::FilePath fake_base_path_; |
int expected_creation_flags_; |
- scoped_ptr<extensions::ExternalProviderImpl> provider_; |
+ Manifest::Location crx_location_; |
scoped_ptr<base::DictionaryValue> prefs_; |
scoped_ptr<TestingProfile> profile_; |
DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor); |
}; |
+// Mock provider that can simulate incremental update like |
+// ExternalRegistryLoader. |
+class MockUpdateProviderVisitor : public MockProviderVisitor { |
+ public: |
+ // The provider will return |fake_base_path| from |
+ // GetBaseCrxFilePath(). User can test the behavior with |
+ // and without an empty path using this parameter. |
+ explicit MockUpdateProviderVisitor(base::FilePath fake_base_path) |
+ : MockProviderVisitor(fake_base_path) {} |
+ |
+ void VisitDueToUpdate(const std::string& json_data) { |
+ update_url_extension_ids_.clear(); |
+ file_extension_ids_.clear(); |
+ removed_extension_ids_.clear(); |
+ |
+ scoped_ptr<base::DictionaryValue> new_prefs = |
+ GetDictionaryFromJSON(json_data); |
+ if (!new_prefs) |
+ return; |
+ provider_->UpdatePrefs(new_prefs.release()); |
+ } |
+ |
+ void OnExternalProviderUpdateComplete( |
+ const ExternalProviderInterface* provider, |
+ const ScopedVector<ExternalInstallInfoUpdateUrl>& update_url_extensions, |
+ const ScopedVector<ExternalInstallInfoFile>& file_extensions, |
+ const std::set<std::string>& removed_extensions) override { |
+ for (const auto& extension_info : update_url_extensions) |
+ update_url_extension_ids_.insert(extension_info->extension_id); |
+ EXPECT_EQ(update_url_extension_ids_.size(), update_url_extensions.size()); |
+ |
+ for (const auto& extension_info : file_extensions) |
+ file_extension_ids_.insert(extension_info->extension_id); |
+ EXPECT_EQ(file_extension_ids_.size(), file_extensions.size()); |
+ |
+ for (const auto& extension_id : removed_extensions) |
+ removed_extension_ids_.insert(extension_id); |
+ } |
+ |
+ size_t GetUpdateURLExtensionCount() { |
+ return update_url_extension_ids_.size(); |
+ } |
+ size_t GetFileExtensionCount() { return file_extension_ids_.size(); } |
+ size_t GetRemovedExtensionCount() { return removed_extension_ids_.size(); } |
+ |
+ bool HasSeenUpdateWithUpdateUrl(const std::string& extension_id) { |
+ return update_url_extension_ids_.count(extension_id) > 0u; |
+ } |
+ bool HasSeenUpdateWithFile(const std::string& extension_id) { |
+ return file_extension_ids_.count(extension_id) > 0u; |
+ } |
+ bool HasSeenRemoval(const std::string& extension_id) { |
+ return removed_extension_ids_.count(extension_id) > 0u; |
+ } |
+ |
+ private: |
+ std::set<std::string> update_url_extension_ids_; |
+ std::set<std::string> file_extension_ids_; |
+ std::set<std::string> removed_extension_ids_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MockUpdateProviderVisitor); |
+}; |
+ |
class ExtensionServiceTest |
: public extensions::ExtensionServiceTestWithInstall { |
public: |
@@ -1029,20 +1116,16 @@ TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) { |
service()->set_extensions_enabled(true); |
// Register and install an external extension. |
- Version version("1.0.0.0"); |
+ scoped_ptr<Version> version(new Version("1.0.0.0")); |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- if (service()->OnExternalExtensionFileFound( |
- good_crx, |
- &version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::FROM_BOOKMARK, |
- false /* mark_acknowledged */, |
- false /* install_immediately */)) { |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ good_crx, std::move(version), path, Manifest::EXTERNAL_PREF, |
+ Extension::FROM_BOOKMARK, false /* mark_acknowledged */, |
+ false /* install_immediately */)); |
+ if (service()->OnExternalExtensionFileFound(*info)) |
observer.Wait(); |
- } |
const Extension* extension = service()->GetExtensionById(good_crx, false); |
ASSERT_TRUE(extension); |
@@ -1066,19 +1149,15 @@ TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) { |
service()->set_extensions_enabled(true); |
// Install an external extension. |
- Version version("1.0.0.0"); |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- if (service()->OnExternalExtensionFileFound(good_crx, |
- &version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false)) { |
+ scoped_ptr<Version> version(new Version("1.0.0.0")); |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ good_crx, std::move(version), path, Manifest::EXTERNAL_PREF, |
+ Extension::NO_FLAGS, false, false)); |
+ if (service()->OnExternalExtensionFileFound(*info)) |
observer.Wait(); |
- } |
ASSERT_TRUE(service()->GetExtensionById(good_crx, false)); |
@@ -1088,28 +1167,19 @@ TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) { |
Extension::EXTERNAL_EXTENSION_UNINSTALLED); |
// Try to re-install it externally. This should fail because of the killbit. |
- service()->OnExternalExtensionFileFound(good_crx, |
- &version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false); |
+ service()->OnExternalExtensionFileFound(*info); |
base::RunLoop().RunUntilIdle(); |
ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false)); |
ValidateIntegerPref(good_crx, "state", |
Extension::EXTERNAL_EXTENSION_UNINSTALLED); |
- version = Version("1.0.0.1"); |
+ version.reset(new Version("1.0.0.1")); |
// Repeat the same thing with a newer version of the extension. |
path = data_dir().AppendASCII("good2.crx"); |
- service()->OnExternalExtensionFileFound(good_crx, |
- &version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false); |
+ info.reset(new ExternalInstallInfoFile(good_crx, std::move(version), path, |
+ Manifest::EXTERNAL_PREF, |
+ Extension::NO_FLAGS, false, false)); |
+ service()->OnExternalExtensionFileFound(*info); |
base::RunLoop().RunUntilIdle(); |
ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false)); |
ValidateIntegerPref(good_crx, "state", |
@@ -1160,7 +1230,7 @@ TEST_F(ExtensionServiceTest, FailOnWrongId) { |
base::FilePath path = data_dir().AppendASCII("good.crx"); |
service()->set_extensions_enabled(true); |
- Version version("1.0.0.0"); |
+ scoped_ptr<Version> version(new Version("1.0.0.0")); |
const std::string wrong_id = all_zero; |
const std::string correct_id = good_crx; |
@@ -1171,13 +1241,10 @@ TEST_F(ExtensionServiceTest, FailOnWrongId) { |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- service()->OnExternalExtensionFileFound(wrong_id, |
- &version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false); |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ wrong_id, std::move(version), path, Manifest::EXTERNAL_PREF, |
+ Extension::NO_FLAGS, false, false)); |
+ service()->OnExternalExtensionFileFound(*info); |
observer.Wait(); |
ASSERT_FALSE(service()->GetExtensionById(good_crx, false)); |
@@ -1186,15 +1253,9 @@ TEST_F(ExtensionServiceTest, FailOnWrongId) { |
content::WindowedNotificationObserver observer2( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- if (service()->OnExternalExtensionFileFound(correct_id, |
- &version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false)) { |
+ info->extension_id = correct_id; |
+ if (service()->OnExternalExtensionFileFound(*info)) |
observer2.Wait(); |
- } |
ASSERT_TRUE(service()->GetExtensionById(good_crx, false)); |
} |
@@ -1206,36 +1267,27 @@ TEST_F(ExtensionServiceTest, FailOnWrongVersion) { |
// Install an external extension with a version from the external |
// source that is not equal to the version in the extension manifest. |
- Version wrong_version("1.2.3.4"); |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- service()->OnExternalExtensionFileFound(good_crx, |
- &wrong_version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false); |
+ scoped_ptr<Version> wrong_version(new Version("1.2.3.4")); |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ good_crx, std::move(wrong_version), path, Manifest::EXTERNAL_PREF, |
+ Extension::NO_FLAGS, false, false)); |
+ service()->OnExternalExtensionFileFound(*info); |
observer.Wait(); |
ASSERT_FALSE(service()->GetExtensionById(good_crx, false)); |
// Try again with the right version. Expect success. |
service()->pending_extension_manager()->Remove(good_crx); |
- Version correct_version("1.0.0.0"); |
+ scoped_ptr<Version> correct_version(new Version("1.0.0.0")); |
+ info->version = std::move(correct_version); |
content::WindowedNotificationObserver observer2( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- if (service()->OnExternalExtensionFileFound(good_crx, |
- &correct_version, |
- path, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false)) { |
+ if (service()->OnExternalExtensionFileFound(*info)) |
observer2.Wait(); |
- } |
ASSERT_TRUE(service()->GetExtensionById(good_crx, false)); |
} |
@@ -5051,6 +5103,90 @@ TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) { |
EXPECT_EQ(1, visitor.Visit(json_data)); |
} |
+TEST_F(ExtensionServiceTest, IncrementalUpdateThroughRegistry) { |
+ InitializeEmptyExtensionService(); |
+ |
+ // Test some valid extension records. |
+ // Set a base path to avoid erroring out on relative paths. |
+ // Paths starting with // are absolute on every platform we support. |
+ base::FilePath base_path(FILE_PATH_LITERAL("//base/path")); |
+ ASSERT_TRUE(base_path.IsAbsolute()); |
+ MockUpdateProviderVisitor visitor(base_path); |
+ std::string json_data = |
+ "{" |
+ " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" |
+ " \"external_crx\": \"RandomExtension.crx\"," |
+ " \"external_version\": \"1.0\"" |
+ " }," |
+ " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" |
+ " \"external_crx\": \"RandomExtension2.crx\"," |
+ " \"external_version\": \"2.0\"" |
+ " }," |
+ " \"cccccccccccccccccccccccccccccccc\": {" |
+ " \"external_update_url\": \"http:\\\\foo.com/update\"," |
+ " \"install_parameter\": \"id\"" |
+ " }" |
+ "}"; |
+ EXPECT_EQ(3, visitor.Visit(json_data, Manifest::EXTERNAL_REGISTRY, |
+ Manifest::EXTERNAL_PREF_DOWNLOAD)); |
+ |
+ // c* removed and d*, e*, f* added, a*, b* existing. |
+ json_data = |
+ "{" |
+ " \"dddddddddddddddddddddddddddddddd\": {" |
+ " \"external_crx\": \"RandomExtension3.crx\"," |
+ " \"external_version\": \"1.0\"" |
+ " }," |
+ " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {" |
+ " \"external_update_url\": \"http:\\\\foo.com/update\"," |
+ " \"install_parameter\": \"id\"" |
+ " }," |
+ " \"ffffffffffffffffffffffffffffffff\": {" |
+ " \"external_update_url\": \"http:\\\\bar.com/update\"," |
+ " \"install_parameter\": \"id\"" |
+ " }," |
+ " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" |
+ " \"external_crx\": \"RandomExtension.crx\"," |
+ " \"external_version\": \"1.0\"" |
+ " }," |
+ " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" |
+ " \"external_crx\": \"RandomExtension2.crx\"," |
+ " \"external_version\": \"2.0\"" |
+ " }" |
+ "}"; |
+ |
+ // This will simulate registry loader observing new changes in registry and |
+ // hence will discover new extensions. |
+ visitor.VisitDueToUpdate(json_data); |
+ |
+ // UpdateUrl. |
+ EXPECT_EQ(2u, visitor.GetUpdateURLExtensionCount()); |
+ EXPECT_TRUE( |
+ visitor.HasSeenUpdateWithUpdateUrl("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")); |
+ EXPECT_TRUE( |
+ visitor.HasSeenUpdateWithUpdateUrl("ffffffffffffffffffffffffffffffff")); |
+ |
+ // File. |
+ EXPECT_EQ(3u, visitor.GetFileExtensionCount()); |
+ EXPECT_TRUE( |
+ visitor.HasSeenUpdateWithFile("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); |
+ EXPECT_TRUE( |
+ visitor.HasSeenUpdateWithFile("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")); |
+ EXPECT_TRUE( |
+ visitor.HasSeenUpdateWithFile("dddddddddddddddddddddddddddddddd")); |
+ |
+ // Removed extensions. |
+ EXPECT_EQ(1u, visitor.GetRemovedExtensionCount()); |
+ EXPECT_TRUE(visitor.HasSeenRemoval("cccccccccccccccccccccccccccccccc")); |
+ |
+ // Simulate all 5 extensions being removed. |
+ json_data = "{}"; |
+ visitor.VisitDueToUpdate(json_data); |
+ EXPECT_EQ(0u, visitor.GetUpdateURLExtensionCount()); |
+ EXPECT_EQ(0u, visitor.GetFileExtensionCount()); |
+ EXPECT_EQ(5u, visitor.GetRemovedExtensionCount()); |
+} |
+ |
// Test loading good extensions from the profile directory. |
TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) { |
// Ensure we're testing in "en" and leave global state untouched. |
@@ -5295,33 +5431,22 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) { |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
// Skip install when the location is the same. |
- EXPECT_FALSE( |
- service()->OnExternalExtensionUpdateUrlFound(kGoodId, |
- std::string(), |
- GURL(kGoodUpdateURL), |
- Manifest::INTERNAL, |
- Extension::NO_FLAGS, |
- false)); |
+ scoped_ptr<GURL> good_update_url(new GURL(kGoodUpdateURL)); |
+ scoped_ptr<ExternalInstallInfoUpdateUrl> info( |
+ new ExternalInstallInfoUpdateUrl( |
+ kGoodId, std::string(), std::move(good_update_url), |
+ Manifest::INTERNAL, Extension::NO_FLAGS, false)); |
+ EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(*info, true)); |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
// Install when the location has higher priority. |
- EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound( |
- kGoodId, |
- std::string(), |
- GURL(kGoodUpdateURL), |
- Manifest::EXTERNAL_POLICY_DOWNLOAD, |
- Extension::NO_FLAGS, |
- false)); |
+ info->download_location = Manifest::EXTERNAL_POLICY_DOWNLOAD; |
+ EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(*info, true)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
// Try the low priority again. Should be rejected. |
- EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound( |
- kGoodId, |
- std::string(), |
- GURL(kGoodUpdateURL), |
- Manifest::EXTERNAL_PREF_DOWNLOAD, |
- Extension::NO_FLAGS, |
- false)); |
+ info->download_location = Manifest::EXTERNAL_PREF_DOWNLOAD; |
+ EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(*info, true)); |
// The existing record should still be present in the pending extension |
// manager. |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
@@ -5330,13 +5455,8 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) { |
// Skip install when the location has the same priority as the installed |
// location. |
- EXPECT_FALSE( |
- service()->OnExternalExtensionUpdateUrlFound(kGoodId, |
- std::string(), |
- GURL(kGoodUpdateURL), |
- Manifest::INTERNAL, |
- Extension::NO_FLAGS, |
- false)); |
+ info->download_location = Manifest::INTERNAL; |
+ EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(*info, true)); |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
} |
@@ -5374,19 +5494,17 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) { |
service()->pending_extension_manager(); |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
+ scoped_ptr<Version> older_version_ptr(new Version(older_version)); |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ kGoodId, std::move(older_version_ptr), kInvalidPathToCrx, |
+ Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged, |
+ kDontInstallImmediately)); |
{ |
// Simulate an external source adding the extension as INTERNAL. |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::INTERNAL, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
observer.Wait(); |
VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED); |
@@ -5397,14 +5515,8 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) { |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::EXTERNAL_PREF; |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
observer.Wait(); |
VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED); |
@@ -5413,25 +5525,12 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) { |
// Simulate an external source adding as EXTERNAL_PREF again. |
// This is rejected because the version and the location are the same as |
// the previous installation, which is still pending. |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
// Try INTERNAL again. Should fail. |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::INTERNAL, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::INTERNAL; |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
{ |
@@ -5439,38 +5538,20 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) { |
content::WindowedNotificationObserver observer( |
extensions::NOTIFICATION_CRX_INSTALLER_DONE, |
content::NotificationService::AllSources()); |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_REGISTRY, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::EXTERNAL_REGISTRY; |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
observer.Wait(); |
VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED); |
} |
// Registry outranks both external pref and internal, so both fail. |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::EXTERNAL_PREF; |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::INTERNAL, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::INTERNAL; |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
pending->Remove(kGoodId); |
@@ -5494,83 +5575,42 @@ TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) { |
// older, or the same, and succeed if the version is newer. |
// Older than the installed version... |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::INTERNAL, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->version.reset(new Version(older_version)); |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
// Same version as the installed version... |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- ext->version(), |
- kInvalidPathToCrx, |
- Manifest::INTERNAL, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->version.reset(new Version(ext->VersionString())); |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
// Newer than the installed version... |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &newer_version, |
- kInvalidPathToCrx, |
- Manifest::INTERNAL, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->version.reset(new Version(newer_version)); |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
// An external install for a higher priority install source should succeed |
// if the version is greater. |older_version| is not... |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &older_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->version.reset(new Version(older_version)); |
+ info->crx_location = Manifest::EXTERNAL_PREF; |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
// |newer_version| is newer. |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &newer_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->version.reset(new Version(newer_version)); |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
// An external install for an even higher priority install source should |
// succeed if the version is greater. |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &newer_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_REGISTRY, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::EXTERNAL_REGISTRY; |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
// Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY, |
// adding from external pref will now fail. |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &newer_version, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
+ info->crx_location = Manifest::EXTERNAL_PREF; |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
EXPECT_TRUE(pending->IsIdPending(kGoodId)); |
} |
@@ -5590,70 +5630,48 @@ TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) { |
EXPECT_FALSE(pending->IsIdPending(kGoodId)); |
// An external provider starts installing from a local crx. |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &kVersion123, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ kGoodId, make_scoped_ptr(new Version(kVersion123)), kInvalidPathToCrx, |
+ Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged, |
kDontInstallImmediately)); |
- const extensions::PendingExtensionInfo* info; |
- EXPECT_TRUE((info = pending->GetById(kGoodId))); |
- EXPECT_TRUE(info->version().IsValid()); |
- EXPECT_EQ(info->version(), kVersion123); |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
+ |
+ const extensions::PendingExtensionInfo* pending_info; |
+ EXPECT_TRUE((pending_info = pending->GetById(kGoodId))); |
+ EXPECT_TRUE(pending_info->version().IsValid()); |
+ EXPECT_EQ(pending_info->version(), kVersion123); |
// Adding a newer version overrides the currently pending version. |
- EXPECT_TRUE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &kVersion124, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
- EXPECT_TRUE((info = pending->GetById(kGoodId))); |
- EXPECT_TRUE(info->version().IsValid()); |
- EXPECT_EQ(info->version(), kVersion124); |
+ info->version.reset(new Version(kVersion124)); |
+ EXPECT_TRUE(service()->OnExternalExtensionFileFound(*info)); |
+ EXPECT_TRUE((pending_info = pending->GetById(kGoodId))); |
+ EXPECT_TRUE(pending_info->version().IsValid()); |
+ EXPECT_EQ(pending_info->version(), kVersion124); |
// Adding an older version fails. |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &kVersion123, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_PREF, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
- EXPECT_TRUE((info = pending->GetById(kGoodId))); |
- EXPECT_TRUE(info->version().IsValid()); |
- EXPECT_EQ(info->version(), kVersion124); |
+ info->version.reset(new Version(kVersion123)); |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
+ EXPECT_TRUE((pending_info = pending->GetById(kGoodId))); |
+ EXPECT_TRUE(pending_info->version().IsValid()); |
+ EXPECT_EQ(pending_info->version(), kVersion124); |
// Adding an older version fails even when coming from a higher-priority |
// location. |
- EXPECT_FALSE(service()->OnExternalExtensionFileFound( |
- kGoodId, |
- &kVersion123, |
- kInvalidPathToCrx, |
- Manifest::EXTERNAL_REGISTRY, |
- kCreationFlags, |
- kDontMarkAcknowledged, |
- kDontInstallImmediately)); |
- EXPECT_TRUE((info = pending->GetById(kGoodId))); |
- EXPECT_TRUE(info->version().IsValid()); |
- EXPECT_EQ(info->version(), kVersion124); |
+ info->crx_location = Manifest::EXTERNAL_REGISTRY; |
+ EXPECT_FALSE(service()->OnExternalExtensionFileFound(*info)); |
+ EXPECT_TRUE((pending_info = pending->GetById(kGoodId))); |
+ EXPECT_TRUE(pending_info->version().IsValid()); |
+ EXPECT_EQ(pending_info->version(), kVersion124); |
// Adding the latest version from the webstore overrides a specific version. |
GURL kUpdateUrl("http://example.com/update"); |
- EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound( |
- kGoodId, |
- std::string(), |
- kUpdateUrl, |
- Manifest::EXTERNAL_POLICY_DOWNLOAD, |
- Extension::NO_FLAGS, |
- false)); |
- EXPECT_TRUE((info = pending->GetById(kGoodId))); |
- EXPECT_FALSE(info->version().IsValid()); |
+ scoped_ptr<ExternalInstallInfoUpdateUrl> update_info( |
+ new ExternalInstallInfoUpdateUrl( |
+ kGoodId, std::string(), make_scoped_ptr(new GURL(kUpdateUrl)), |
+ Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS, false)); |
+ EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(*update_info, true)); |
+ EXPECT_TRUE((pending_info = pending->GetById(kGoodId))); |
+ EXPECT_FALSE(pending_info->version().IsValid()); |
} |
// This makes sure we can package and install CRX files that use whitelisted |
@@ -5704,15 +5722,11 @@ class ExtensionSourcePriorityTest : public ExtensionServiceTest { |
// Fake an external file from external_extensions.json. |
bool AddPendingExternalPrefFileInstall() { |
- Version version("1.0.0.0"); |
- |
- return service()->OnExternalExtensionFileFound(crx_id_, |
- &version, |
- crx_path_, |
- Manifest::EXTERNAL_PREF, |
- Extension::NO_FLAGS, |
- false, |
- false); |
+ scoped_ptr<Version> version(new Version("1.0.0.0")); |
+ scoped_ptr<ExternalInstallInfoFile> info(new ExternalInstallInfoFile( |
+ crx_id_, std::move(version), crx_path_, Manifest::EXTERNAL_PREF, |
+ Extension::NO_FLAGS, false, false)); |
+ return service()->OnExternalExtensionFileFound(*info); |
} |
// Fake a request from sync to install an extension. |
@@ -5729,13 +5743,12 @@ class ExtensionSourcePriorityTest : public ExtensionServiceTest { |
// Fake a policy install. |
bool AddPendingPolicyInstall() { |
// Get path to the CRX with id |kGoodId|. |
- return service()->OnExternalExtensionUpdateUrlFound( |
- crx_id_, |
- std::string(), |
- GURL(), |
- Manifest::EXTERNAL_POLICY_DOWNLOAD, |
- Extension::NO_FLAGS, |
- false); |
+ scoped_ptr<GURL> empty_url(new GURL()); |
+ scoped_ptr<ExternalInstallInfoUpdateUrl> info( |
+ new ExternalInstallInfoUpdateUrl( |
+ crx_id_, std::string(), std::move(empty_url), |
+ Manifest::EXTERNAL_POLICY_DOWNLOAD, Extension::NO_FLAGS, false)); |
+ return service()->OnExternalExtensionUpdateUrlFound(*info, true); |
} |
// Get the install source of a pending extension. |