This source file includes following definitions.
- ACTION_P
- ACTION_P2
- SetupDefaults
- test_download_dir
- test_virtual_dir
- delegate
- download_prefs
- SetUp
- TearDown
- CreateActiveDownloadItem
- EnableAutoOpenBasedOnExtension
- SetManagedDownloadPath
- SetPromptForDownload
- GetPathInDownloadDir
- RunTestCase
- CompletionCallbackWrapper
- RunDownloadTargetDeterminer
- RunTestCasesWithActiveItem
- VerifyDownloadTarget
- NullReserveVirtualPath
- NullPromptUser
- NullDetermineLocalPath
- NotifyExtensionsOverridePath
- CheckDownloadUrlCheckExes
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- DummyGetPluginsCallback
- ForceRefreshOfPlugins
- IsPluginAvailable
- CanLoadPlugin
- plugin_path_
- path
- SetUp
- TearDown
- TEST_F
- TEST_F
#include "base/at_exit.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/observer_list.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/value_conversions.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_extensions.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/download/download_target_determiner.h"
#include "chrome/browser/download/download_target_info.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/browser/history/history_types.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "chrome/test/base/testing_pref_service_syncable.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/download_interrupt_reasons.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "extensions/common/extension.h"
#include "net/base/mime_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#if defined(ENABLE_PLUGINS)
#include "content/public/browser/plugin_service.h"
#include "content/public/browser/plugin_service_filter.h"
#include "content/public/common/webplugininfo.h"
#endif
using ::testing::AnyNumber;
using ::testing::Invoke;
using ::testing::Ref;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::ReturnRefOfCopy;
using ::testing::Truly;
using ::testing::WithArg;
using ::testing::_;
using content::DownloadItem;
namespace {
class NullWebContentsDelegate : public content::WebContentsDelegate {
public:
NullWebContentsDelegate() {}
virtual ~NullWebContentsDelegate() {}
};
ACTION_P(ScheduleCallback, result0) {
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result0));
}
ACTION_P2(ScheduleCallback2, result0, result1) {
base::MessageLoop::current()->PostTask(
FROM_HERE, base::Bind(arg0, result0, result1));
}
enum TestCaseType {
SAVE_AS,
AUTOMATIC,
FORCED
};
enum TestCaseExpectIntermediate {
EXPECT_CRDOWNLOAD,
EXPECT_UNCONFIRMED,
EXPECT_LOCAL_PATH,
};
struct DownloadTestCase {
TestCaseType test_type;
content::DownloadDangerType expected_danger_type;
const char* url;
const char* mime_type;
const base::FilePath::CharType* forced_file_path;
const base::FilePath::CharType* expected_local_path;
DownloadItem::TargetDisposition expected_disposition;
TestCaseExpectIntermediate expected_intermediate;
};
class MockDownloadTargetDeterminerDelegate
: public DownloadTargetDeterminerDelegate {
public:
MOCK_METHOD3(CheckDownloadUrl,
void(content::DownloadItem*, const base::FilePath&,
const CheckDownloadUrlCallback&));
MOCK_METHOD3(NotifyExtensions,
void(content::DownloadItem*, const base::FilePath&,
const NotifyExtensionsCallback&));
MOCK_METHOD3(PromptUserForDownloadPath,
void(content::DownloadItem*, const base::FilePath&,
const FileSelectedCallback&));
MOCK_METHOD3(DetermineLocalPath,
void(DownloadItem*, const base::FilePath&,
const LocalPathCallback&));
MOCK_METHOD5(ReserveVirtualPath,
void(DownloadItem*, const base::FilePath&, bool,
DownloadPathReservationTracker::FilenameConflictAction,
const ReservedPathCallback&));
MOCK_METHOD2(GetFileMimeType,
void(const base::FilePath&,
const GetFileMimeTypeCallback&));
void SetupDefaults() {
ON_CALL(*this, CheckDownloadUrl(_, _, _))
.WillByDefault(WithArg<2>(
ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)));
ON_CALL(*this, NotifyExtensions(_, _, _))
.WillByDefault(WithArg<2>(
ScheduleCallback2(base::FilePath(),
DownloadPathReservationTracker::UNIQUIFY)));
ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _))
.WillByDefault(Invoke(
&MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath));
ON_CALL(*this, PromptUserForDownloadPath(_, _, _))
.WillByDefault(Invoke(
&MockDownloadTargetDeterminerDelegate::NullPromptUser));
ON_CALL(*this, DetermineLocalPath(_, _, _))
.WillByDefault(Invoke(
&MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath));
ON_CALL(*this, GetFileMimeType(_, _))
.WillByDefault(WithArg<1>(
ScheduleCallback("")));
}
private:
static void NullReserveVirtualPath(
DownloadItem* download,
const base::FilePath& virtual_path,
bool create_directory,
DownloadPathReservationTracker::FilenameConflictAction conflict_action,
const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback);
static void NullPromptUser(
DownloadItem* download, const base::FilePath& suggested_path,
const FileSelectedCallback& callback);
static void NullDetermineLocalPath(
DownloadItem* download, const base::FilePath& virtual_path,
const LocalPathCallback& callback);
};
class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness {
public:
virtual void SetUp() OVERRIDE;
virtual void TearDown() OVERRIDE;
content::MockDownloadItem* CreateActiveDownloadItem(
int32 id,
const DownloadTestCase& test_case);
void EnableAutoOpenBasedOnExtension(const base::FilePath& path);
void SetManagedDownloadPath(const base::FilePath& path);
void SetPromptForDownload(bool prompt);
base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path);
void RunTestCase(const DownloadTestCase& test_case,
const base::FilePath& initial_virtual_path,
content::MockDownloadItem* item);
scoped_ptr<DownloadTargetInfo> RunDownloadTargetDeterminer(
const base::FilePath& initial_virtual_path,
content::MockDownloadItem* item);
void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[],
size_t test_case_count);
void VerifyDownloadTarget(const DownloadTestCase& test_case,
const DownloadTargetInfo* target_info);
const base::FilePath& test_download_dir() const {
return test_download_dir_.path();
}
const base::FilePath& test_virtual_dir() const {
return test_virtual_dir_;
}
MockDownloadTargetDeterminerDelegate* delegate() {
return &delegate_;
}
DownloadPrefs* download_prefs() {
return download_prefs_.get();
}
private:
scoped_ptr<DownloadPrefs> download_prefs_;
::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_;
NullWebContentsDelegate web_contents_delegate_;
base::ScopedTempDir test_download_dir_;
base::FilePath test_virtual_dir_;
};
void DownloadTargetDeterminerTest::SetUp() {
ChromeRenderViewHostTestHarness::SetUp();
CHECK(profile());
download_prefs_.reset(new DownloadPrefs(profile()));
web_contents()->SetDelegate(&web_contents_delegate_);
ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual"));
download_prefs_->SetDownloadPath(test_download_dir());
delegate_.SetupDefaults();
}
void DownloadTargetDeterminerTest::TearDown() {
download_prefs_.reset();
ChromeRenderViewHostTestHarness::TearDown();
}
content::MockDownloadItem*
DownloadTargetDeterminerTest::CreateActiveDownloadItem(
int32 id,
const DownloadTestCase& test_case) {
content::MockDownloadItem* item =
new ::testing::NiceMock<content::MockDownloadItem>();
GURL download_url(test_case.url);
std::vector<GURL> url_chain;
url_chain.push_back(download_url);
base::FilePath forced_file_path =
GetPathInDownloadDir(test_case.forced_file_path);
DownloadItem::TargetDisposition initial_disposition =
(test_case.test_type == SAVE_AS) ?
DownloadItem::TARGET_DISPOSITION_PROMPT :
DownloadItem::TARGET_DISPOSITION_OVERWRITE;
EXPECT_EQ(test_case.test_type == FORCED,
!forced_file_path.empty());
ON_CALL(*item, GetBrowserContext())
.WillByDefault(Return(profile()));
ON_CALL(*item, GetDangerType())
.WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
ON_CALL(*item, GetForcedFilePath())
.WillByDefault(ReturnRefOfCopy(forced_file_path));
ON_CALL(*item, GetFullPath())
.WillByDefault(ReturnRefOfCopy(base::FilePath()));
ON_CALL(*item, GetHash())
.WillByDefault(ReturnRefOfCopy(std::string()));
ON_CALL(*item, GetId())
.WillByDefault(Return(id));
ON_CALL(*item, GetLastReason())
.WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_NONE));
ON_CALL(*item, GetMimeType())
.WillByDefault(Return(test_case.mime_type));
ON_CALL(*item, GetReferrerUrl())
.WillByDefault(ReturnRefOfCopy(download_url));
ON_CALL(*item, GetState())
.WillByDefault(Return(DownloadItem::IN_PROGRESS));
ON_CALL(*item, GetTargetDisposition())
.WillByDefault(Return(initial_disposition));
ON_CALL(*item, GetTargetFilePath())
.WillByDefault(ReturnRefOfCopy(base::FilePath()));
ON_CALL(*item, GetTransitionType())
.WillByDefault(Return(content::PAGE_TRANSITION_LINK));
ON_CALL(*item, GetURL())
.WillByDefault(ReturnRefOfCopy(download_url));
ON_CALL(*item, GetUrlChain())
.WillByDefault(ReturnRefOfCopy(url_chain));
ON_CALL(*item, GetWebContents())
.WillByDefault(Return(web_contents()));
ON_CALL(*item, HasUserGesture())
.WillByDefault(Return(true));
ON_CALL(*item, IsDangerous())
.WillByDefault(Return(false));
ON_CALL(*item, IsTemporary())
.WillByDefault(Return(false));
return item;
}
void DownloadTargetDeterminerTest::EnableAutoOpenBasedOnExtension(
const base::FilePath& path) {
EXPECT_TRUE(download_prefs_->EnableAutoOpenBasedOnExtension(path));
}
void DownloadTargetDeterminerTest::SetManagedDownloadPath(
const base::FilePath& path) {
profile()->GetTestingPrefService()->
SetManagedPref(prefs::kDownloadDefaultDirectory,
base::CreateFilePathValue(path));
}
void DownloadTargetDeterminerTest::SetPromptForDownload(bool prompt) {
profile()->GetTestingPrefService()->
SetBoolean(prefs::kPromptForDownload, prompt);
}
base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir(
const base::FilePath::StringType& relative_path) {
if (relative_path.empty())
return base::FilePath();
base::FilePath full_path(test_download_dir().Append(relative_path));
return full_path.NormalizePathSeparators();
}
void DownloadTargetDeterminerTest::RunTestCase(
const DownloadTestCase& test_case,
const base::FilePath& initial_virtual_path,
content::MockDownloadItem* item) {
scoped_ptr<DownloadTargetInfo> target_info =
RunDownloadTargetDeterminer(initial_virtual_path, item);
VerifyDownloadTarget(test_case, target_info.get());
}
void CompletionCallbackWrapper(
const base::Closure& closure,
scoped_ptr<DownloadTargetInfo>* target_info_receiver,
scoped_ptr<DownloadTargetInfo> target_info) {
target_info_receiver->swap(target_info);
base::MessageLoop::current()->PostTask(FROM_HERE, closure);
}
scoped_ptr<DownloadTargetInfo>
DownloadTargetDeterminerTest::RunDownloadTargetDeterminer(
const base::FilePath& initial_virtual_path,
content::MockDownloadItem* item) {
scoped_ptr<DownloadTargetInfo> target_info;
base::RunLoop run_loop;
DownloadTargetDeterminer::Start(
item, initial_virtual_path, download_prefs_.get(), delegate(),
base::Bind(&CompletionCallbackWrapper,
run_loop.QuitClosure(),
&target_info));
run_loop.Run();
::testing::Mock::VerifyAndClearExpectations(delegate());
return target_info.Pass();
}
void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem(
const DownloadTestCase test_cases[],
size_t test_case_count) {
for (size_t i = 0; i < test_case_count; ++i) {
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(i, test_cases[i]));
SCOPED_TRACE(testing::Message() << "Running test case " << i);
RunTestCase(test_cases[i], base::FilePath(), item.get());
}
}
void DownloadTargetDeterminerTest::VerifyDownloadTarget(
const DownloadTestCase& test_case,
const DownloadTargetInfo* target_info) {
base::FilePath expected_local_path(
GetPathInDownloadDir(test_case.expected_local_path));
EXPECT_EQ(expected_local_path.value(), target_info->target_path.value());
EXPECT_EQ(test_case.expected_disposition, target_info->target_disposition);
EXPECT_EQ(test_case.expected_danger_type, target_info->danger_type);
switch (test_case.expected_intermediate) {
case EXPECT_CRDOWNLOAD:
EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath(
target_info->target_path).value(),
target_info->intermediate_path.value());
break;
case EXPECT_UNCONFIRMED:
EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path)
.value(),
target_info->intermediate_path.value());
EXPECT_EQ(expected_local_path.DirName().value(),
target_info->intermediate_path.DirName().value());
EXPECT_TRUE(target_info->intermediate_path.MatchesExtension(
FILE_PATH_LITERAL(".crdownload")));
EXPECT_EQ(0u,
target_info->intermediate_path.BaseName().value().find(
FILE_PATH_LITERAL("Unconfirmed ")));
break;
case EXPECT_LOCAL_PATH:
EXPECT_EQ(expected_local_path.value(),
target_info->intermediate_path.value());
break;
}
}
void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath(
DownloadItem* download,
const base::FilePath& virtual_path,
bool create_directory,
DownloadPathReservationTracker::FilenameConflictAction conflict_action,
const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
callback.Run(virtual_path, true);
}
void MockDownloadTargetDeterminerDelegate::NullPromptUser(
DownloadItem* download, const base::FilePath& suggested_path,
const FileSelectedCallback& callback) {
callback.Run(suggested_path);
}
void MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath(
DownloadItem* download, const base::FilePath& virtual_path,
const LocalPathCallback& callback) {
callback.Run(virtual_path);
}
void NotifyExtensionsOverridePath(
content::DownloadItem* download,
const base::FilePath& path,
const DownloadTargetDeterminerDelegate::NotifyExtensionsCallback&
callback) {
base::FilePath new_path =
base::FilePath()
.AppendASCII("overridden")
.Append(path.BaseName());
if (new_path.MatchesExtension(FILE_PATH_LITERAL(".remove")))
new_path = new_path.RemoveExtension();
callback.Run(new_path, DownloadPathReservationTracker::UNIQUIFY);
}
void CheckDownloadUrlCheckExes(
content::DownloadItem* download,
const base::FilePath& path,
const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback&
callback) {
if (path.MatchesExtension(FILE_PATH_LITERAL(".exe")))
callback.Run(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT);
else
callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_Basic) {
const DownloadTestCase kBasicTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
};
ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
download_util::GetFileDangerLevel(
base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
RunTestCasesWithActiveItem(kBasicTestCases, arraysize(kBasicTestCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_CancelSaveAs) {
const DownloadTestCase kCancelSaveAsTestCases[] = {
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL(""),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_LOCAL_PATH
}
};
ON_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
.WillByDefault(WithArg<2>(ScheduleCallback(base::FilePath())));
RunTestCasesWithActiveItem(kCancelSaveAsTestCases,
arraysize(kCancelSaveAsTestCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DangerousUrl) {
const DownloadTestCase kSafeBrowsingTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
"http://phishing.example.com/foo.txt", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
"http://phishing.example.com/foo.txt", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_UNCONFIRMED
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
"http://phishing.example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
"http://phishing.example.com/foo.html", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.html"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
"http://phishing.example.com/foo.html", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.html"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_UNCONFIRMED
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
"http://phishing.example.com/foo.html", "",
FILE_PATH_LITERAL("forced-foo.html"),
FILE_PATH_LITERAL("forced-foo.html"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
};
ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
.WillByDefault(WithArg<2>(ScheduleCallback(
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL)));
RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
arraysize(kSafeBrowsingTestCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_MaybeDangerousContent) {
const DownloadTestCase kSafeBrowsingTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
"http://phishing.example.com/foo.exe", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.exe"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
"http://phishing.example.com/foo.exe", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.exe"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_UNCONFIRMED
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
"http://phishing.example.com/foo.exe", "",
FILE_PATH_LITERAL("forced-foo.exe"),
FILE_PATH_LITERAL("forced-foo.exe"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
};
ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
.WillByDefault(WithArg<2>(ScheduleCallback(
content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)));
RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
arraysize(kSafeBrowsingTestCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LastSavePath) {
const DownloadTestCase kLastSavePathTestCasesPre[] = {
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
}
};
const DownloadTestCase kLastSavePathTestCasesPost[] = {
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo/foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
};
const DownloadTestCase kLastSavePathTestCasesVirtual[] = {
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("bar.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_LOCAL_PATH
},
};
{
SCOPED_TRACE(testing::Message()
<< "Running with default download path");
base::FilePath prompt_path =
GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt"));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _));
RunTestCasesWithActiveItem(kLastSavePathTestCasesPre,
arraysize(kLastSavePathTestCasesPre));
}
{
SCOPED_TRACE(testing::Message()
<< "Running with local last_selected_directory");
download_prefs()->SetSaveFilePath(test_download_dir().AppendASCII("foo"));
base::FilePath prompt_path =
GetPathInDownloadDir(FILE_PATH_LITERAL("foo/foo.txt"));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _));
RunTestCasesWithActiveItem(kLastSavePathTestCasesPost,
arraysize(kLastSavePathTestCasesPost));
}
{
SCOPED_TRACE(testing::Message()
<< "Running with virtual last_selected_directory");
base::FilePath last_selected_dir = test_virtual_dir().AppendASCII("foo");
base::FilePath virtual_path = last_selected_dir.AppendASCII("foo.txt");
download_prefs()->SetSaveFilePath(last_selected_dir);
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
_, last_selected_dir.AppendASCII("foo.txt"), _));
EXPECT_CALL(*delegate(), DetermineLocalPath(_, virtual_path, _))
.WillOnce(WithArg<2>(ScheduleCallback(
GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")))));
RunTestCasesWithActiveItem(kLastSavePathTestCasesVirtual,
arraysize(kLastSavePathTestCasesVirtual));
}
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DefaultVirtual) {
download_prefs()->SetDownloadPath(test_virtual_dir());
{
SCOPED_TRACE(testing::Message() << "Automatic Safe Download");
const DownloadTestCase kAutomaticDownloadToVirtualDir = {
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo-local.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
};
EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
.WillOnce(WithArg<2>(ScheduleCallback(
GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
RunTestCasesWithActiveItem(&kAutomaticDownloadToVirtualDir, 1);
}
{
SCOPED_TRACE(testing::Message() << "Save As to virtual directory");
const DownloadTestCase kSaveAsToVirtualDir = {
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/bar.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo-local.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_LOCAL_PATH
};
EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
.WillOnce(WithArg<2>(ScheduleCallback(
GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
_, test_virtual_dir().AppendASCII("bar.txt"), _))
.WillOnce(WithArg<2>(ScheduleCallback(
test_virtual_dir().AppendASCII("prompted.txt"))));
RunTestCasesWithActiveItem(&kSaveAsToVirtualDir, 1);
}
{
SCOPED_TRACE(testing::Message() << "Save As to local directory");
const DownloadTestCase kSaveAsToLocalDir = {
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/bar.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo-x.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
};
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
_, test_virtual_dir().AppendASCII("bar.txt"), _))
.WillOnce(WithArg<2>(ScheduleCallback(
GetPathInDownloadDir(FILE_PATH_LITERAL("foo-x.txt")))));
RunTestCasesWithActiveItem(&kSaveAsToLocalDir, 1);
}
{
SCOPED_TRACE(testing::Message() << "Forced safe download");
const DownloadTestCase kForcedSafe = {
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
};
RunTestCasesWithActiveItem(&kForcedSafe, 1);
}
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_InactiveDownload) {
const DownloadTestCase kInactiveTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL(""),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL(""),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_LOCAL_PATH
}
};
for (size_t i = 0; i < arraysize(kInactiveTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "Running test case " << i);
const DownloadTestCase& test_case = kInactiveTestCases[i];
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(i, test_case));
EXPECT_CALL(*item.get(), GetState())
.WillRepeatedly(Return(content::DownloadItem::CANCELLED));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
.Times(0);
RunTestCase(test_case, base::FilePath(), item.get());
}
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) {
const DownloadTestCase kReservationFailedCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("bar.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
};
ON_CALL(*delegate(), ReserveVirtualPath(_, _, _, _, _))
.WillByDefault(WithArg<4>(ScheduleCallback2(
GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")), false)));
RunTestCasesWithActiveItem(kReservationFailedCases,
arraysize(kReservationFailedCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LocalPathFailed) {
const DownloadTestCase kLocalPathFailedCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL(""),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
};
download_prefs()->SetDownloadPath(test_virtual_dir());
EXPECT_CALL(*delegate(), DetermineLocalPath(
_, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _))
.WillOnce(WithArg<2>(ScheduleCallback(base::FilePath())));
RunTestCasesWithActiveItem(kLocalPathFailedCases,
arraysize(kLocalPathFailedCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_VisitedReferrer) {
const DownloadTestCase kVisitedReferrerCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://visited.example.com/foo.crx", "application/xml",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://not-visited.example.com/foo.crx", "application/xml",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://not-visited.example.com/foo.crx", "application/xml",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://not-visited.example.com/foo.crx", "application/xml",
FILE_PATH_LITERAL("foo.crx"),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
};
ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
download_util::GetFileDangerLevel(
base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
ASSERT_TRUE(profile()->CreateHistoryService(false, false));
GURL url("http://visited.example.com/visited-link.html");
base::Time time_of_visit(
base::Time::Now().LocalMidnight() - base::TimeDelta::FromSeconds(10));
HistoryService* history_service =
HistoryServiceFactory::GetForProfile(profile(), Profile::EXPLICIT_ACCESS);
ASSERT_TRUE(history_service);
history_service->AddPage(url, time_of_visit, history::SOURCE_BROWSED);
RunTestCasesWithActiveItem(kVisitedReferrerCases,
arraysize(kVisitedReferrerCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways) {
const DownloadTestCase kPromptingTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL("foo.txt"),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.dummy", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.dummy"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
};
SetPromptForDownload(true);
EnableAutoOpenBasedOnExtension(
base::FilePath(FILE_PATH_LITERAL("dummy.dummy")));
RunTestCasesWithActiveItem(kPromptingTestCases,
arraysize(kPromptingTestCases));
}
#if !defined(OS_ANDROID)
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways_Extension) {
const DownloadTestCase kPromptingTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx",
extensions::Extension::kMimeType,
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
#if defined(OS_WIN)
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.user.js", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.user.js"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
#else
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.user.js", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.user.js"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
#endif
};
SetPromptForDownload(true);
RunTestCasesWithActiveItem(kPromptingTestCases,
arraysize(kPromptingTestCases));
}
#endif
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ManagedPath) {
const DownloadTestCase kManagedPathTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
};
SetManagedDownloadPath(test_download_dir());
ASSERT_TRUE(download_prefs()->IsDownloadPathManaged());
RunTestCasesWithActiveItem(kManagedPathTestCases,
arraysize(kManagedPathTestCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsSafe) {
const DownloadTestCase kNotifyExtensionsTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
};
ON_CALL(*delegate(), NotifyExtensions(_, _, _))
.WillByDefault(Invoke(&NotifyExtensionsOverridePath));
RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
arraysize(kNotifyExtensionsTestCases));
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsUnsafe) {
const DownloadTestCase kNotifyExtensionsTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx.remove", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
"http://example.com/foo.exe.remove", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.exe"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
};
ON_CALL(*delegate(), NotifyExtensions(_, _, _))
.WillByDefault(Invoke(&NotifyExtensionsOverridePath));
ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
.WillByDefault(Invoke(&CheckDownloadUrlCheckExes));
RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
arraysize(kNotifyExtensionsTestCases));
}
TEST_F(DownloadTargetDeterminerTest,
TargetDeterminer_NotifyExtensionsConflict) {
const DownloadTestCase kNotifyExtensionsTestCase = {
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
};
const DownloadTestCase& test_case = kNotifyExtensionsTestCase;
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(0, test_case));
base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt"));
base::FilePath full_overridden_path =
GetPathInDownloadDir(overridden_path.value());
EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
.WillOnce(WithArg<2>(
ScheduleCallback2(overridden_path,
DownloadPathReservationTracker::OVERWRITE)));
EXPECT_CALL(*delegate(), ReserveVirtualPath(
_, full_overridden_path, true, DownloadPathReservationTracker::OVERWRITE,
_)).WillOnce(WithArg<4>(
ScheduleCallback2(full_overridden_path, true)));
RunTestCase(test_case, base::FilePath(), item.get());
EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
.WillOnce(WithArg<2>(
ScheduleCallback2(overridden_path,
DownloadPathReservationTracker::PROMPT)));
EXPECT_CALL(*delegate(), ReserveVirtualPath(
_, full_overridden_path, true, DownloadPathReservationTracker::PROMPT, _))
.WillOnce(WithArg<4>(
ScheduleCallback2(full_overridden_path, true)));
RunTestCase(test_case, base::FilePath(), item.get());
}
TEST_F(DownloadTargetDeterminerTest,
TargetDeterminer_NotifyExtensionsDefaultPath) {
const DownloadTestCase kNotifyExtensionsTestCase = {
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("overridden/foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
};
const DownloadTestCase& test_case = kNotifyExtensionsTestCase;
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(0, test_case));
base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt"));
base::FilePath full_overridden_path =
GetPathInDownloadDir(overridden_path.value());
download_prefs()->SetSaveFilePath(GetPathInDownloadDir(
FILE_PATH_LITERAL("last_selected")));
EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
.WillOnce(WithArg<2>(
ScheduleCallback2(overridden_path,
DownloadPathReservationTracker::UNIQUIFY)));
EXPECT_CALL(*delegate(),
PromptUserForDownloadPath(_, full_overridden_path, _))
.WillOnce(WithArg<2>(
ScheduleCallback(full_overridden_path)));
RunTestCase(test_case, base::FilePath(), item.get());
}
TEST_F(DownloadTargetDeterminerTest,
TargetDeterminer_InitialVirtualPathUnsafe) {
const base::FilePath::CharType* kInitialPath =
FILE_PATH_LITERAL("some_path/bar.html");
const DownloadTestCase kInitialPathTestCase = {
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
kInitialPath,
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
};
const DownloadTestCase& test_case = kInitialPathTestCase;
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(1, test_case));
EXPECT_CALL(*item, GetLastReason())
.WillRepeatedly(Return(
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
EXPECT_CALL(*item, GetTargetDisposition())
.WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT));
RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedNoPrompt) {
const base::FilePath::CharType* kInitialPath =
FILE_PATH_LITERAL("some_path/bar.txt");
const DownloadTestCase kResumedTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
kInitialPath,
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
};
ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
download_util::GetFileDangerLevel(
base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "Running test case " << i);
const DownloadTestCase& test_case = kResumedTestCases[i];
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(i, test_case));
base::FilePath expected_path =
GetPathInDownloadDir(test_case.expected_local_path);
ON_CALL(*item.get(), GetLastReason())
.WillByDefault(Return(
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
.Times(test_case.test_type == AUTOMATIC ? 1 : 0);
EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _))
.Times(0);
EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _));
EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _));
RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
}
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedForcedDownload) {
const base::FilePath::CharType* kInitialPath =
FILE_PATH_LITERAL("some_path/bar.txt");
const DownloadTestCase kResumedForcedDownload = {
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
};
const DownloadTestCase& test_case = kResumedForcedDownload;
base::FilePath expected_path =
GetPathInDownloadDir(test_case.expected_local_path);
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(0, test_case));
ON_CALL(*item.get(), GetLastReason())
.WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
.Times(test_case.test_type == AUTOMATIC ? 1 : 0);
EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
.Times(0);
EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _));
EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _));
RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
}
TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedWithPrompt) {
const base::FilePath::CharType* kInitialPath =
FILE_PATH_LITERAL("some_path/bar.txt");
const DownloadTestCase kResumedTestCases[] = {
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
kInitialPath,
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.crx", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
};
ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
download_util::GetFileDangerLevel(
base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "Running test case " << i);
download_prefs()->SetSaveFilePath(test_download_dir());
const DownloadTestCase& test_case = kResumedTestCases[i];
base::FilePath expected_path =
GetPathInDownloadDir(test_case.expected_local_path);
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(i, test_case));
ON_CALL(*item.get(), GetLastReason())
.WillByDefault(Return(
content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
.Times(test_case.test_type == AUTOMATIC ? 1 : 0);
EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _));
EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _));
EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _));
EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _));
RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
}
}
TEST_F(DownloadTargetDeterminerTest,
TargetDeterminer_IntermediateNameForResumed) {
const base::FilePath::CharType kInitialPath[] =
FILE_PATH_LITERAL("some_path/bar.txt");
struct IntermediateNameTestCase {
DownloadTestCase general;
const base::FilePath::CharType* initial_intermediate_path;
const base::FilePath::CharType* expected_intermediate_path;
} kIntermediateNameTestCases[] = {
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
FILE_PATH_LITERAL("bar.txt.crdownload"),
FILE_PATH_LITERAL("foo.txt.crdownload")
},
{
{
SAVE_AS,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "text/plain",
FILE_PATH_LITERAL(""),
kInitialPath,
DownloadItem::TARGET_DISPOSITION_PROMPT,
EXPECT_CRDOWNLOAD
},
FILE_PATH_LITERAL("foo.txt.crdownload"),
FILE_PATH_LITERAL("some_path/bar.txt.crdownload")
},
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
FILE_PATH_LITERAL("Unconfirmed abcd.crdownload"),
FILE_PATH_LITERAL("Unconfirmed abcd.crdownload")
},
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
"http://example.com/foo.crx", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.crx"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_UNCONFIRMED
},
FILE_PATH_LITERAL("other_path/Unconfirmed abcd.crdownload"),
FILE_PATH_LITERAL("")
},
{
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.txt", "",
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_LOCAL_PATH
},
FILE_PATH_LITERAL("forced-foo.txt"),
FILE_PATH_LITERAL("forced-foo.txt")
},
};
ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
download_util::GetFileDangerLevel(
base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kIntermediateNameTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "Running test case " << i);
const IntermediateNameTestCase& test_case = kIntermediateNameTestCases[i];
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(i, test_case.general));
ON_CALL(*item.get(), GetLastReason())
.WillByDefault(Return(
content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
ON_CALL(*item.get(), GetFullPath())
.WillByDefault(ReturnRefOfCopy(
GetPathInDownloadDir(test_case.initial_intermediate_path)));
ON_CALL(*item.get(), GetDangerType())
.WillByDefault(Return(test_case.general.expected_danger_type));
scoped_ptr<DownloadTargetInfo> target_info =
RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
item.get());
VerifyDownloadTarget(test_case.general, target_info.get());
base::FilePath expected_intermediate_path =
GetPathInDownloadDir(test_case.expected_intermediate_path);
if (!expected_intermediate_path.empty())
EXPECT_EQ(expected_intermediate_path, target_info->intermediate_path);
}
}
TEST_F(DownloadTargetDeterminerTest,
TargetDeterminer_MIMETypeDetermination) {
const base::FilePath::CharType kInitialPath[] =
FILE_PATH_LITERAL("some_path/bar.txt");
struct MIMETypeTestCase {
DownloadTestCase general;
const char* expected_mime_type;
} kMIMETypeTestCases[] = {
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.png", "image/png",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.png"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
"image/png"
},
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.png", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.png"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
"image/png"
},
{
{
FORCED,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.abc", "",
FILE_PATH_LITERAL("foo.png"),
FILE_PATH_LITERAL("foo.png"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
"image/png"
},
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.notarealext", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.notarealext"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
""
},
{
{
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.notarealext", "image/png",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.notarealext"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
},
""
},
};
ON_CALL(*delegate(), GetFileMimeType(
GetPathInDownloadDir(FILE_PATH_LITERAL("foo.png")), _))
.WillByDefault(WithArg<1>(
ScheduleCallback("image/png")));
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kMIMETypeTestCases); ++i) {
SCOPED_TRACE(testing::Message() << "Running test case " << i);
const MIMETypeTestCase& test_case = kMIMETypeTestCases[i];
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(i, test_case.general));
scoped_ptr<DownloadTargetInfo> target_info =
RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
item.get());
EXPECT_EQ(test_case.expected_mime_type, target_info->mime_type);
}
}
#if defined(ENABLE_PLUGINS)
void DummyGetPluginsCallback(
const base::Closure& closure,
const std::vector<content::WebPluginInfo>& plugins) {
closure.Run();
}
void ForceRefreshOfPlugins() {
#if !defined(OS_WIN)
content::RenderProcessHost::SetRunRendererInProcess(true);
#endif
base::RunLoop run_loop;
content::PluginService::GetInstance()->GetPlugins(
base::Bind(&DummyGetPluginsCallback, run_loop.QuitClosure()));
run_loop.Run();
#if !defined(OS_WIN)
content::RenderProcessHost::SetRunRendererInProcess(false);
#endif
}
class MockPluginServiceFilter : public content::PluginServiceFilter {
public:
MOCK_METHOD1(MockPluginAvailable, bool(const base::FilePath&));
virtual bool IsPluginAvailable(int render_process_id,
int render_view_id,
const void* context,
const GURL& url,
const GURL& policy_url,
content::WebPluginInfo* plugin) OVERRIDE {
return MockPluginAvailable(plugin->path);
}
virtual bool CanLoadPlugin(int render_process_id,
const base::FilePath& path) OVERRIDE {
return true;
}
};
class ScopedRegisterInternalPlugin {
public:
ScopedRegisterInternalPlugin(content::PluginService* plugin_service,
content::WebPluginInfo::PluginType type,
const base::FilePath& path,
const char* mime_type,
const char* extension)
: plugin_service_(plugin_service),
plugin_path_(path) {
content::WebPluginMimeType plugin_mime_type(mime_type,
extension,
"Test file");
content::WebPluginInfo plugin_info(base::string16(),
path,
base::string16(),
base::string16());
plugin_info.mime_types.push_back(plugin_mime_type);
plugin_info.type = type;
plugin_service->RegisterInternalPlugin(plugin_info, true);
plugin_service->RefreshPlugins();
ForceRefreshOfPlugins();
}
~ScopedRegisterInternalPlugin() {
plugin_service_->UnregisterInternalPlugin(plugin_path_);
plugin_service_->RefreshPlugins();
ForceRefreshOfPlugins();
}
const base::FilePath& path() { return plugin_path_; }
private:
content::PluginService* plugin_service_;
base::FilePath plugin_path_;
};
class DownloadTargetDeterminerTestWithPlugin
: public DownloadTargetDeterminerTest {
public:
DownloadTargetDeterminerTestWithPlugin()
: old_plugin_service_filter_(NULL) {}
virtual void SetUp() OVERRIDE {
content::PluginService* plugin_service =
content::PluginService::GetInstance();
plugin_service->Init();
plugin_service->DisablePluginsDiscoveryForTesting();
old_plugin_service_filter_ = plugin_service->GetFilter();
plugin_service->SetFilter(&mock_plugin_filter_);
DownloadTargetDeterminerTest::SetUp();
}
virtual void TearDown() OVERRIDE {
content::PluginService::GetInstance()->SetFilter(
old_plugin_service_filter_);
DownloadTargetDeterminerTest::TearDown();
}
protected:
content::PluginServiceFilter* old_plugin_service_filter_;
testing::StrictMock<MockPluginServiceFilter> mock_plugin_filter_;
base::ShadowingAtExitManager at_exit_manager_;
};
TEST_F(DownloadTargetDeterminerTestWithPlugin,
TargetDeterminer_CheckForSecureHandling_PPAPI) {
const base::FilePath::CharType kInitialPath[] =
FILE_PATH_LITERAL("some_path/bar.txt");
const char kTestMIMEType[] = "application/x-example-should-not-exist";
DownloadTestCase kSecureHandlingTestCase = {
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.fakeext", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.fakeext"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
};
content::PluginService* plugin_service =
content::PluginService::GetInstance();
{
ForceRefreshOfPlugins();
std::vector<content::WebPluginInfo> info;
ASSERT_FALSE(plugin_service->GetPluginInfoArray(
GURL(), kTestMIMEType, false, &info, NULL));
ASSERT_EQ(0u, info.size())
<< "Name: " << info[0].name << ", Path: " << info[0].path.value();
}
ON_CALL(*delegate(), GetFileMimeType(
GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _))
.WillByDefault(WithArg<1>(
ScheduleCallback(kTestMIMEType)));
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(1, kSecureHandlingTestCase));
scoped_ptr<DownloadTargetInfo> target_info =
RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
item.get());
EXPECT_FALSE(target_info->is_filetype_handled_safely);
ScopedRegisterInternalPlugin ppapi_plugin(
plugin_service,
content::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS,
test_download_dir().AppendASCII("ppapi"),
kTestMIMEType,
"fakeext");
EXPECT_CALL(mock_plugin_filter_, MockPluginAvailable(ppapi_plugin.path()))
.WillRepeatedly(Return(true));
target_info = RunDownloadTargetDeterminer(
GetPathInDownloadDir(kInitialPath), item.get());
EXPECT_TRUE(target_info->is_filetype_handled_safely);
EXPECT_CALL(mock_plugin_filter_, MockPluginAvailable(ppapi_plugin.path()))
.WillRepeatedly(Return(false));
target_info = RunDownloadTargetDeterminer(
GetPathInDownloadDir(kInitialPath), item.get());
EXPECT_FALSE(target_info->is_filetype_handled_safely);
ScopedRegisterInternalPlugin ppapi_unsandboxed_plugin(
plugin_service,
content::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED,
test_download_dir().AppendASCII("ppapi-nosandbox"),
kTestMIMEType,
"fakeext");
EXPECT_CALL(mock_plugin_filter_,
MockPluginAvailable(ppapi_unsandboxed_plugin.path()))
.WillRepeatedly(Return(true));
target_info = RunDownloadTargetDeterminer(
GetPathInDownloadDir(kInitialPath), item.get());
EXPECT_FALSE(target_info->is_filetype_handled_safely);
}
TEST_F(DownloadTargetDeterminerTestWithPlugin,
TargetDeterminer_CheckForSecureHandling_NPAPI) {
const base::FilePath::CharType kInitialPath[] =
FILE_PATH_LITERAL("some_path/bar.txt");
const char kTestMIMEType[] = "application/x-example-should-not-exist";
DownloadTestCase kSecureHandlingTestCase = {
AUTOMATIC,
content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
"http://example.com/foo.fakeext", "",
FILE_PATH_LITERAL(""),
FILE_PATH_LITERAL("foo.fakeext"),
DownloadItem::TARGET_DISPOSITION_OVERWRITE,
EXPECT_CRDOWNLOAD
};
content::PluginService* plugin_service =
content::PluginService::GetInstance();
if (!plugin_service->NPAPIPluginsSupported())
return;
{
ForceRefreshOfPlugins();
std::vector<content::WebPluginInfo> info;
ASSERT_FALSE(plugin_service->GetPluginInfoArray(
GURL(), kTestMIMEType, false, &info, NULL));
ASSERT_EQ(0u, info.size())
<< "Name: " << info[0].name << ", Path: " << info[0].path.value();
}
ON_CALL(*delegate(), GetFileMimeType(
GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _))
.WillByDefault(WithArg<1>(
ScheduleCallback(kTestMIMEType)));
scoped_ptr<content::MockDownloadItem> item(
CreateActiveDownloadItem(1, kSecureHandlingTestCase));
scoped_ptr<DownloadTargetInfo> target_info =
RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
item.get());
EXPECT_FALSE(target_info->is_filetype_handled_safely);
ScopedRegisterInternalPlugin npapi_plugin(
plugin_service,
content::WebPluginInfo::PLUGIN_TYPE_NPAPI,
test_download_dir().AppendASCII("npapi"),
kTestMIMEType,
"fakeext");
EXPECT_CALL(mock_plugin_filter_, MockPluginAvailable(npapi_plugin.path()))
.WillRepeatedly(Return(true));
target_info = RunDownloadTargetDeterminer(
GetPathInDownloadDir(kInitialPath), item.get());
EXPECT_FALSE(target_info->is_filetype_handled_safely);
}
#endif
}