// Copyright (c) 2012 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. #include "chrome/browser/plugins/plugin_installer.h" #include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "chrome/browser/plugins/plugin_installer_observer.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "content/public/browser/download_url_parameters.h" #include "content/public/test/mock_download_item.h" #include "content/public/test/mock_download_manager.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" using ::testing::_; namespace { class PluginInstallerTest : public ChromeRenderViewHostTestHarness { public: PluginInstallerTest(); virtual void SetUp() override; virtual void TearDown() override; PluginInstaller* installer() { return installer_.get(); } scoped_ptr CreateMockDownloadItem(); private: scoped_ptr installer_; }; PluginInstallerTest::PluginInstallerTest() { } void PluginInstallerTest::SetUp() { content::RenderViewHostTestHarness::SetUp(); installer_.reset(new PluginInstaller()); } void PluginInstallerTest::TearDown() { installer_.reset(); content::RenderViewHostTestHarness::TearDown(); } scoped_ptr PluginInstallerTest::CreateMockDownloadItem() { scoped_ptr mock_download_item( new testing::StrictMock()); ON_CALL(*mock_download_item, GetState()) .WillByDefault(testing::Return(content::DownloadItem::IN_PROGRESS)); return mock_download_item.Pass(); } class TestPluginInstallerObserver : public PluginInstallerObserver { public: explicit TestPluginInstallerObserver(PluginInstaller* installer) : PluginInstallerObserver(installer), download_started_(false), download_finished_(false), download_cancelled_(false) {} bool download_started() const { return download_started_; } bool download_finished() const { return download_finished_; } bool download_cancelled() const { return download_cancelled_; } const std::string& download_error() const { return download_error_; } private: void DownloadStarted() override { download_started_ = true; } void DownloadFinished() override { download_finished_ = true; } void DownloadError(const std::string& message) override { download_error_ = message; } void DownloadCancelled() override { download_cancelled_ = true; } bool download_started_; bool download_finished_; std::string download_error_; bool download_cancelled_; }; // Action for invoking the OnStartedCallback of DownloadURLParameters object // which is assumed to be pointed to by arg0. ACTION_P2(InvokeOnStartedCallback, download_item, interrupt_reason) { arg0->callback().Run(download_item, interrupt_reason); } ACTION_P(InvokeClosure, closure) { closure.Run(); } const char kTestUrl[] = "http://example.com/some-url"; } // namespace // Test that DownloadStarted()/DownloadFinished() notifications are sent to // observers when a download initiated by PluginInstaller completes // successfully. TEST_F(PluginInstallerTest, StartInstalling_SuccessfulDownload) { content::MockDownloadManager mock_download_manager; base::RunLoop run_loop; scoped_ptr download_item(CreateMockDownloadItem()); EXPECT_CALL(mock_download_manager, DownloadUrlMock(testing::Property( &content::DownloadUrlParameters::url, GURL(kTestUrl)))) .WillOnce(testing::DoAll( InvokeOnStartedCallback(download_item.get(), content::DOWNLOAD_INTERRUPT_REASON_NONE), InvokeClosure(run_loop.QuitClosure()))); EXPECT_CALL(*download_item, SetOpenWhenComplete(_)); TestPluginInstallerObserver installer_observer(installer()); installer()->StartInstallingWithDownloadManager( GURL(kTestUrl), web_contents(), &mock_download_manager); run_loop.Run(); EXPECT_TRUE(installer_observer.download_started()); EXPECT_FALSE(installer_observer.download_finished()); EXPECT_CALL(*download_item, GetState()) .WillOnce(testing::Return(content::DownloadItem::COMPLETE)); download_item->NotifyObserversDownloadUpdated(); EXPECT_TRUE(installer_observer.download_finished()); } // Test that DownloadStarted()/DownloadError() notifications are sent to // observers when a download initiated by PluginInstaller fails to start. TEST_F(PluginInstallerTest, StartInstalling_FailedStart) { content::MockDownloadManager mock_download_manager; base::RunLoop run_loop; scoped_ptr download_item(CreateMockDownloadItem()); EXPECT_CALL(mock_download_manager, DownloadUrlMock(testing::Property( &content::DownloadUrlParameters::url, GURL(kTestUrl)))) .WillOnce( testing::DoAll(InvokeOnStartedCallback( download_item.get(), content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED), InvokeClosure(run_loop.QuitClosure()))); TestPluginInstallerObserver installer_observer(installer()); installer()->StartInstallingWithDownloadManager( GURL(kTestUrl), web_contents(), &mock_download_manager); run_loop.Run(); EXPECT_TRUE(installer_observer.download_started()); EXPECT_FALSE(installer_observer.download_finished()); EXPECT_EQ("Error 20: NETWORK_FAILED", installer_observer.download_error()); } // Test that DownloadStarted()/DownloadError() notifications are sent to // observers when a download initiated by PluginInstaller starts successfully // but is interrupted later. TEST_F(PluginInstallerTest, StartInstalling_Interrupted) { content::MockDownloadManager mock_download_manager; base::RunLoop run_loop; scoped_ptr download_item(CreateMockDownloadItem()); EXPECT_CALL(mock_download_manager, DownloadUrlMock(testing::Property( &content::DownloadUrlParameters::url, GURL(kTestUrl)))) .WillOnce(testing::DoAll( InvokeOnStartedCallback(download_item.get(), content::DOWNLOAD_INTERRUPT_REASON_NONE), InvokeClosure(run_loop.QuitClosure()))); EXPECT_CALL(*download_item, SetOpenWhenComplete(_)); TestPluginInstallerObserver installer_observer(installer()); installer()->StartInstallingWithDownloadManager( GURL(kTestUrl), web_contents(), &mock_download_manager); run_loop.Run(); EXPECT_TRUE(installer_observer.download_started()); EXPECT_FALSE(installer_observer.download_finished()); EXPECT_CALL(*download_item, GetState()) .WillOnce(testing::Return(content::DownloadItem::INTERRUPTED)); EXPECT_CALL(*download_item, GetLastReason()).WillOnce( testing::Return(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); download_item->NotifyObserversDownloadUpdated(); EXPECT_TRUE(installer_observer.download_started()); EXPECT_FALSE(installer_observer.download_finished()); EXPECT_EQ("NETWORK_FAILED", installer_observer.download_error()); }