| // Copyright 2017 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/browser/updater/update_data_provider.h" |
| |
| #include <map> |
| #include <memory> |
| #include <optional> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/containers/contains.h" |
| #include "base/containers/flat_set.h" |
| #include "base/files/file_path.h" |
| #include "base/files/file_util.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/functional/bind.h" |
| #include "base/run_loop.h" |
| #include "base/test/bind.h" |
| #include "components/update_client/update_client.h" |
| #include "extensions/browser/disable_reason.h" |
| #include "extensions/browser/extension_prefs.h" |
| #include "extensions/browser/extension_registry.h" |
| #include "extensions/browser/extension_system.h" |
| #include "extensions/browser/extensions_test.h" |
| #include "extensions/browser/test_extensions_browser_client.h" |
| #include "extensions/browser/updater/extension_installer.h" |
| #include "extensions/common/extension_builder.h" |
| #include "extensions/common/extension_id.h" |
| |
| using extensions::mojom::ManifestLocation; |
| |
| namespace extensions { |
| |
| class UpdateDataProviderExtensionsBrowserClient |
| : public TestExtensionsBrowserClient { |
| public: |
| explicit UpdateDataProviderExtensionsBrowserClient( |
| content::BrowserContext* context) |
| : TestExtensionsBrowserClient(context) {} |
| |
| UpdateDataProviderExtensionsBrowserClient( |
| const UpdateDataProviderExtensionsBrowserClient&) = delete; |
| UpdateDataProviderExtensionsBrowserClient& operator=( |
| const UpdateDataProviderExtensionsBrowserClient&) = delete; |
| |
| ~UpdateDataProviderExtensionsBrowserClient() override = default; |
| |
| bool IsExtensionEnabled(const std::string& id, |
| content::BrowserContext* context) const override { |
| return base::Contains(enabled_ids_, id); |
| } |
| |
| void AddEnabledExtension(const std::string& id) { enabled_ids_.insert(id); } |
| |
| private: |
| std::set<std::string> enabled_ids_; |
| }; |
| |
| class UpdateDataProviderTest : public ExtensionsTest { |
| public: |
| using UpdateClientCallback = UpdateDataProvider::UpdateClientCallback; |
| |
| UpdateDataProviderTest() = default; |
| ~UpdateDataProviderTest() override = default; |
| |
| void SetUp() override { |
| SetExtensionsBrowserClient( |
| std::make_unique<UpdateDataProviderExtensionsBrowserClient>( |
| browser_context())); |
| ExtensionsTest::SetUp(); |
| } |
| |
| protected: |
| ExtensionSystem* extension_system() { |
| return ExtensionSystem::Get(browser_context()); |
| } |
| |
| ExtensionRegistry* extension_registry() { |
| return ExtensionRegistry::Get(browser_context()); |
| } |
| |
| // Helper function that creates a file at |relative_path| within |directory| |
| // and fills it with |content|. |
| bool AddFileToDirectory(const base::FilePath& directory, |
| const base::FilePath& relative_path, |
| const std::string& content) const { |
| const base::FilePath full_path = directory.Append(relative_path); |
| return base::CreateDirectory(full_path.DirName()) && |
| base::WriteFile(full_path, content); |
| } |
| |
| void AddExtension(const ExtensionId& extension_id, |
| const std::string& version, |
| bool enabled, |
| const base::flat_set<int>& disable_reasons, |
| ManifestLocation location) { |
| AddExtension(extension_id, version, "", enabled, disable_reasons, location); |
| } |
| |
| void AddExtension(const ExtensionId& extension_id, |
| const std::string& version, |
| const std::string& fingerprint, |
| bool enabled, |
| const base::flat_set<int>& disable_reasons, |
| ManifestLocation location) { |
| base::ScopedTempDir temp_dir; |
| ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(temp_dir.GetPath())); |
| |
| base::FilePath foo_js(FILE_PATH_LITERAL("foo.js")); |
| base::FilePath bar_html(FILE_PATH_LITERAL("bar/bar.html")); |
| ASSERT_TRUE(AddFileToDirectory(temp_dir.GetPath(), foo_js, "hello")) |
| << "Failed to write " << temp_dir.GetPath().value() << "/" |
| << foo_js.value(); |
| ASSERT_TRUE(AddFileToDirectory(temp_dir.GetPath(), bar_html, "world")); |
| |
| ExtensionBuilder builder; |
| auto manifest_builder = base::Value::Dict() |
| .Set("name", "My First Extension") |
| .Set("version", version) |
| .Set("manifest_version", 2); |
| if (!fingerprint.empty()) { |
| manifest_builder.Set("differential_fingerprint", fingerprint); |
| } |
| builder.SetManifest(std::move(manifest_builder)); |
| builder.SetID(extension_id); |
| builder.SetPath(temp_dir.GetPath()); |
| builder.SetLocation(location); |
| |
| auto* test_browser_client = |
| static_cast<UpdateDataProviderExtensionsBrowserClient*>( |
| extensions_browser_client()); |
| if (enabled) { |
| extension_registry()->AddEnabled(builder.Build()); |
| test_browser_client->AddEnabledExtension(extension_id); |
| } else { |
| extension_registry()->AddDisabled(builder.Build()); |
| |
| if (!disable_reasons.empty()) { |
| // Some tests (e.g. GetData_DisabledExtension_WithNoReason) disable an |
| // extension with no disable reasons. In this case we shouldn't call |
| // `AddDisableReasons` because it expects at least one disable reason. |
| // TODO(crbug.com/40554334): We can clean this up after |
| // `Extension::State` is removed. |
| // |
| // Use raw manipulation passkey to add disable reasons because some |
| // tests pass unknown reasons in the `disable_reasons` set. |
| ExtensionPrefs::DisableReasonRawManipulationPasskey passkey; |
| ExtensionPrefs::Get(browser_context()) |
| ->AddRawDisableReasons(passkey, extension_id, disable_reasons); |
| } |
| } |
| |
| const Extension* extension = |
| extension_registry()->GetInstalledExtension(extension_id); |
| ASSERT_NE(nullptr, extension); |
| ASSERT_EQ(version, extension->VersionString()); |
| } |
| |
| const std::string kExtensionId1 = "adbncddmehfkgipkidpdiheffobcpfma"; |
| const std::string kExtensionId2 = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
| }; |
| |
| TEST_F(UpdateDataProviderTest, GetData_NoDataAdded) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(nullptr); |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, ExtensionUpdateDataMap(), {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(data[0], std::nullopt); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_Fingerprint) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| const std::string fingerprint = "1.0123456789abcdef"; |
| AddExtension(kExtensionId1, version, true, |
| /*disable_reasons=*/{}, ManifestLocation::kInternal); |
| AddExtension(kExtensionId2, version, fingerprint, true, |
| /*disable_reasons=*/{}, ManifestLocation::kInternal); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| update_data[kExtensionId2] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, |
| {kExtensionId1, kExtensionId2}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(2UL, data.size()); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_EQ(version, data[1]->version.GetString()); |
| EXPECT_EQ("2." + version, data[0]->fingerprint); |
| EXPECT_EQ(fingerprint, data[1]->fingerprint); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_EnabledExtension) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, true, |
| /*disable_reasons=*/{}, ManifestLocation::kInternal); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| EXPECT_EQ(0UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ("internal", data[0]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_EnabledExtensionWithData) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, true, |
| /*disable_reasons=*/{}, ManifestLocation::kExternalPref); |
| |
| ExtensionUpdateDataMap update_data; |
| auto& info = update_data[kExtensionId1]; |
| info.is_corrupt_reinstall = true; |
| info.install_source = "webstore"; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| true /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ("0.0.0.0", data[0]->version.GetString()); |
| EXPECT_EQ("reinstall", data[0]->install_source); |
| EXPECT_EQ("external", data[0]->install_location); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| EXPECT_EQ(0UL, data[0]->disabled_reasons.size()); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithNoReason) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, false, |
| /*disable_reasons=*/{}, ManifestLocation::kExternalRegistry); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| ASSERT_EQ(1UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_NONE, |
| data[0]->disabled_reasons[0]); |
| EXPECT_EQ("external", data[0]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_UnknownReason) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, false, |
| {disable_reason::DisableReason::DISABLE_REASON_LAST}, |
| ManifestLocation::kCommandLine); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| true /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| ASSERT_EQ(1UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_NONE, |
| data[0]->disabled_reasons[0]); |
| EXPECT_EQ("other", data[0]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_DisabledExtension_WithReasons) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, false, |
| {disable_reason::DisableReason::DISABLE_USER_ACTION, |
| disable_reason::DisableReason::DISABLE_CORRUPTED}, |
| ManifestLocation::kExternalPolicyDownload); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| ASSERT_EQ(2UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_USER_ACTION, |
| data[0]->disabled_reasons[0]); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_CORRUPTED, |
| data[0]->disabled_reasons[1]); |
| EXPECT_EQ("policy", data[0]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, |
| GetData_DisabledExtension_WithReasonsAndUnknownReason) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, false, |
| {disable_reason::DisableReason::DISABLE_USER_ACTION, |
| disable_reason::DisableReason::DISABLE_CORRUPTED, |
| disable_reason::DisableReason::DISABLE_REASON_LAST}, |
| ManifestLocation::kExternalPrefDownload); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| true /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| ASSERT_EQ(3UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_NONE, |
| data[0]->disabled_reasons[0]); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_USER_ACTION, |
| data[0]->disabled_reasons[1]); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_CORRUPTED, |
| data[0]->disabled_reasons[2]); |
| EXPECT_EQ("external", data[0]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions) { |
| // GetData with more than 1 extension. |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version1 = "0.1.2.3"; |
| const std::string version2 = "9.8.7.6"; |
| AddExtension(kExtensionId1, version1, true, |
| /*disable_reasons=*/{}, ManifestLocation::kExternalRegistry); |
| AddExtension(kExtensionId2, version2, true, |
| /*disable_reasons=*/{}, ManifestLocation::kUnpacked); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| update_data[kExtensionId2] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, |
| {kExtensionId1, kExtensionId2}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(2UL, data.size()); |
| EXPECT_EQ(version1, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| EXPECT_EQ(0UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ("external", data[0]->install_location); |
| EXPECT_EQ(version2, data[1]->version.GetString()); |
| EXPECT_NE(nullptr, data[1]->installer.get()); |
| EXPECT_EQ(0UL, data[1]->disabled_reasons.size()); |
| EXPECT_EQ("other", data[1]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_DisabledExtension) { |
| // One extension is disabled. |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version1 = "0.1.2.3"; |
| const std::string version2 = "9.8.7.6"; |
| AddExtension(kExtensionId1, version1, false, |
| {disable_reason::DisableReason::DISABLE_CORRUPTED}, |
| ManifestLocation::kInternal); |
| AddExtension(kExtensionId2, version2, true, |
| /*disable_reasons=*/{}, ManifestLocation::kExternalPrefDownload); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| update_data[kExtensionId2] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| true /*install_immediately*/, update_data, {kExtensionId1, kExtensionId2}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(2UL, data.size()); |
| EXPECT_EQ(version1, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| ASSERT_EQ(1UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ(disable_reason::DisableReason::DISABLE_CORRUPTED, |
| data[0]->disabled_reasons[0]); |
| EXPECT_EQ("internal", data[0]->install_location); |
| |
| EXPECT_EQ(version2, data[1]->version.GetString()); |
| EXPECT_NE(nullptr, data[1]->installer.get()); |
| EXPECT_EQ(0UL, data[1]->disabled_reasons.size()); |
| EXPECT_EQ("external", data[1]->install_location); |
| } |
| |
| TEST_F(UpdateDataProviderTest, |
| GetData_MultipleExtensions_NotInstalledExtension) { |
| // One extension is not installed. |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| AddExtension(kExtensionId1, version, true, |
| /*disable_reasons=*/{}, ManifestLocation::kComponent); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| update_data[kExtensionId2] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, |
| {kExtensionId1, kExtensionId2}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(2UL, data.size()); |
| ASSERT_NE(std::nullopt, data[0]); |
| EXPECT_EQ(version, data[0]->version.GetString()); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| EXPECT_EQ(0UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ("other", data[0]->install_location); |
| |
| EXPECT_EQ(std::nullopt, data[1]); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_MultipleExtensions_CorruptExtension) { |
| // With non-default data, one extension is corrupted: |
| // is_corrupt_reinstall=true. |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version1 = "0.1.2.3"; |
| const std::string version2 = "9.8.7.6"; |
| const std::string initial_version = "0.0.0.0"; |
| AddExtension(kExtensionId1, version1, true, |
| /*disable_reasons=*/{}, ManifestLocation::kExternalComponent); |
| AddExtension(kExtensionId2, version2, true, |
| /*disable_reasons=*/{}, ManifestLocation::kExternalPolicy); |
| |
| ExtensionUpdateDataMap update_data; |
| auto& info1 = update_data[kExtensionId1]; |
| auto& info2 = update_data[kExtensionId2]; |
| |
| info1.install_source = "webstore"; |
| info2.is_corrupt_reinstall = true; |
| info2.install_source = "sideload"; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| true /*install_immediately*/, update_data, {kExtensionId1, kExtensionId2}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(2UL, data.size()); |
| EXPECT_EQ(version1, data[0]->version.GetString()); |
| EXPECT_EQ("webstore", data[0]->install_source); |
| EXPECT_EQ("other", data[0]->install_location); |
| EXPECT_NE(nullptr, data[0]->installer.get()); |
| EXPECT_EQ(0UL, data[0]->disabled_reasons.size()); |
| EXPECT_EQ(initial_version, data[1]->version.GetString()); |
| EXPECT_EQ("reinstall", data[1]->install_source); |
| EXPECT_EQ("policy", data[1]->install_location); |
| EXPECT_NE(nullptr, data[1]->installer.get()); |
| EXPECT_EQ(0UL, data[1]->disabled_reasons.size()); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_InstallImmediately) { |
| // Verify that GetData propagtes install_immediately correctly to the crx |
| // installer. |
| AddExtension(kExtensionId1, "0.1.1.3", true, |
| /*disable_reasons=*/{}, ManifestLocation::kInternal); |
| |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data1; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data1 = output; })); |
| ASSERT_EQ(1UL, data1.size()); |
| ASSERT_NE(nullptr, data1[0]->installer.get()); |
| const ExtensionInstaller* installer1 = |
| static_cast<ExtensionInstaller*>(data1[0]->installer.get()); |
| EXPECT_FALSE(installer1->install_immediately()); |
| |
| std::vector<std::optional<update_client::CrxComponent>> data2; |
| data_provider->GetData( |
| true /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data2 = output; })); |
| ASSERT_EQ(1UL, data2.size()); |
| ASSERT_NE(nullptr, data2[0]->installer.get()); |
| const ExtensionInstaller* installer2 = |
| static_cast<ExtensionInstaller*>(data2[0]->installer.get()); |
| EXPECT_TRUE(installer2->install_immediately()); |
| } |
| |
| TEST_F(UpdateDataProviderTest, GetData_Pending_Version) { |
| scoped_refptr<UpdateDataProvider> data_provider = |
| base::MakeRefCounted<UpdateDataProvider>(browser_context()); |
| |
| const std::string version = "0.1.2.3"; |
| const std::string pending_version = "0.1.2.4"; |
| const std::string pending_fingerprint = "fingerprint"; |
| |
| AddExtension(kExtensionId1, version, true, |
| /*disable_reasons=*/{}, ManifestLocation::kInternal); |
| |
| ExtensionUpdateDataMap update_data; |
| update_data[kExtensionId1] = {}; |
| update_data[kExtensionId1].pending_version = pending_version; |
| update_data[kExtensionId1].pending_fingerprint = pending_fingerprint; |
| |
| std::vector<std::optional<update_client::CrxComponent>> data; |
| data_provider->GetData( |
| false /*install_immediately*/, update_data, {kExtensionId1}, |
| base::BindLambdaForTesting( |
| [&](const std::vector<std::optional<update_client::CrxComponent>>& |
| output) { data = output; })); |
| |
| ASSERT_EQ(1UL, data.size()); |
| EXPECT_EQ(pending_version, data[0]->version.GetString()); |
| EXPECT_EQ(pending_fingerprint, data[0]->fingerprint); |
| } |
| |
| } // namespace extensions |