| // 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 <memory> |
| #include <string> |
| #include <utility> |
| |
| #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/functional/callback_helpers.h" |
| #include "base/memory/scoped_refptr.h" |
| #include "base/run_loop.h" |
| #include "components/update_client/update_client.h" |
| #include "components/update_client/update_client_errors.h" |
| #include "content/public/test/test_utils.h" |
| #include "extensions/browser/extensions_test.h" |
| #include "extensions/browser/updater/extension_installer.h" |
| #include "extensions/common/extension_id.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace extensions { |
| |
| namespace { |
| |
| class ExtensionInstallerTest : public ExtensionsTest { |
| public: |
| using UpdateClientCallback = |
| extensions::ExtensionInstaller::UpdateClientCallback; |
| using ExtensionInstallerCallback = |
| ExtensionInstaller::ExtensionInstallerCallback; |
| using Result = update_client::CrxInstaller::Result; |
| using InstallError = update_client::InstallError; |
| |
| ExtensionInstallerTest(); |
| |
| ExtensionInstallerTest(const ExtensionInstallerTest&) = delete; |
| ExtensionInstallerTest& operator=(const ExtensionInstallerTest&) = delete; |
| |
| ~ExtensionInstallerTest() override; |
| |
| void InstallCompleteCallback(const Result& result); |
| |
| protected: |
| void RunThreads(); |
| |
| protected: |
| const std::string kExtensionId = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
| const std::string kPublicKey = |
| "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8c4fBSPZ6utYoZ8NiWF/" |
| "DSaimBhihjwgOsskyleFGaurhi3TDClTVSGPxNkgCzrz0wACML7M4aNjpd05qupdbR2d294j" |
| "kDuI7caxEGUucpP7GJRRHnm8Sx+" |
| "y0ury28n8jbN0PnInKKWcxpIXXmNQyC19HBuO3QIeUq9Dqc+7YFQIDAQAB"; |
| |
| base::RunLoop run_loop_; |
| Result result_; |
| bool executed_; |
| }; |
| |
| ExtensionInstallerTest::ExtensionInstallerTest() |
| : result_(-1), executed_(false) {} |
| |
| ExtensionInstallerTest::~ExtensionInstallerTest() = default; |
| |
| void ExtensionInstallerTest::InstallCompleteCallback(const Result& result) { |
| result_ = result; |
| executed_ = true; |
| run_loop_.Quit(); |
| } |
| |
| void ExtensionInstallerTest::RunThreads() { |
| run_loop_.Run(); |
| } |
| |
| TEST_F(ExtensionInstallerTest, GetInstalledFile) { |
| base::ScopedTempDir root_dir; |
| ASSERT_TRUE(root_dir.CreateUniqueTempDir()); |
| ASSERT_FALSE(base::MakeRefCounted<ExtensionInstaller>( |
| kExtensionId, root_dir.GetPath(), |
| false /*install_immediately*/, ExtensionInstallerCallback()) |
| ->GetInstalledFile("f")); |
| } |
| |
| TEST_F(ExtensionInstallerTest, Install_InvalidUnpackedDir) { |
| // The unpacked folder is not valid, the installer will return an error. |
| base::ScopedTempDir root_dir; |
| ASSERT_TRUE(root_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(root_dir.GetPath())); |
| scoped_refptr<ExtensionInstaller> installer = |
| base::MakeRefCounted<ExtensionInstaller>( |
| kExtensionId, root_dir.GetPath(), true /*install_immediately*/, |
| base::BindRepeating( |
| [](const ExtensionId& extension_id, const std::string& public_key, |
| const base::FilePath& unpacked_dir, bool install_immediately, |
| UpdateClientCallback update_client_callback) { |
| // This function should never be executed. |
| EXPECT_TRUE(false); |
| })); |
| |
| // Non-existing unpacked dir |
| base::ScopedTempDir unpacked_dir; |
| ASSERT_TRUE(unpacked_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(unpacked_dir.GetPath())); |
| ASSERT_TRUE(base::DeletePathRecursively(unpacked_dir.GetPath())); |
| ASSERT_FALSE(base::PathExists(unpacked_dir.GetPath())); |
| installer->Install( |
| unpacked_dir.GetPath(), kPublicKey, nullptr, base::DoNothing(), |
| base::BindOnce(&ExtensionInstallerTest::InstallCompleteCallback, |
| base::Unretained(this))); |
| |
| RunThreads(); |
| |
| EXPECT_TRUE(executed_); |
| EXPECT_EQ(static_cast<int>(InstallError::GENERIC_ERROR), result_.result.code); |
| } |
| |
| TEST_F(ExtensionInstallerTest, Install_BasicInstallOperation_Error) { |
| base::ScopedTempDir root_dir; |
| ASSERT_TRUE(root_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(root_dir.GetPath())); |
| scoped_refptr<ExtensionInstaller> installer = |
| base::MakeRefCounted<ExtensionInstaller>( |
| kExtensionId, root_dir.GetPath(), false /*install_immediately*/, |
| base::BindRepeating([](const ExtensionId& extension_id, |
| const std::string& public_key, |
| const base::FilePath& unpacked_dir, |
| bool install_immediately, |
| UpdateClientCallback update_client_callback) { |
| EXPECT_FALSE(install_immediately); |
| std::move(update_client_callback) |
| .Run(Result(InstallError::GENERIC_ERROR)); |
| })); |
| |
| base::ScopedTempDir unpacked_dir; |
| ASSERT_TRUE(unpacked_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(unpacked_dir.GetPath())); |
| |
| installer->Install( |
| unpacked_dir.GetPath(), kPublicKey, nullptr, base::DoNothing(), |
| base::BindOnce(&ExtensionInstallerTest::InstallCompleteCallback, |
| base::Unretained(this))); |
| |
| RunThreads(); |
| |
| EXPECT_TRUE(executed_); |
| EXPECT_EQ(static_cast<int>(InstallError::GENERIC_ERROR), result_.result.code); |
| } |
| |
| TEST_F(ExtensionInstallerTest, Install_BasicInstallOperation_Success) { |
| base::ScopedTempDir root_dir; |
| ASSERT_TRUE(root_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(root_dir.GetPath())); |
| scoped_refptr<ExtensionInstaller> installer = |
| base::MakeRefCounted<ExtensionInstaller>( |
| kExtensionId, root_dir.GetPath(), true /*install_immediately*/, |
| base::BindRepeating([](const ExtensionId& extension_id, |
| const std::string& public_key, |
| const base::FilePath& unpacked_dir, |
| bool install_immediately, |
| UpdateClientCallback update_client_callback) { |
| EXPECT_TRUE(install_immediately); |
| std::move(update_client_callback).Run(Result(InstallError::NONE)); |
| })); |
| |
| base::ScopedTempDir unpacked_dir; |
| ASSERT_TRUE(unpacked_dir.CreateUniqueTempDir()); |
| ASSERT_TRUE(base::PathExists(unpacked_dir.GetPath())); |
| |
| installer->Install( |
| unpacked_dir.GetPath(), kPublicKey, nullptr, base::DoNothing(), |
| base::BindOnce(&ExtensionInstallerTest::InstallCompleteCallback, |
| base::Unretained(this))); |
| |
| RunThreads(); |
| |
| EXPECT_TRUE(executed_); |
| EXPECT_EQ(static_cast<int>(InstallError::NONE), result_.result.code); |
| } |
| |
| } // namespace |
| |
| } // namespace extensions |