Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1049)

Unified Diff: chrome/browser/download/download_target_determiner_unittest.cc

Issue 12850002: Move download filename determintion into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/download/download_target_determiner_unittest.cc
diff --git a/chrome/browser/download/download_target_determiner_unittest.cc b/chrome/browser/download/download_target_determiner_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..315618a7d736b1b32263f75e909cd0452464201c
--- /dev/null
+++ b/chrome/browser/download/download_target_determiner_unittest.cc
@@ -0,0 +1,1323 @@
+// 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 "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop.h"
+#include "base/observer_list.h"
+#include "base/prefs/pref_service.h"
+#include "base/stl_util.h"
+#include "base/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_util.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/extensions/extension.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/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
+#include "content/public/test/mock_download_item.h"
+#include "content/public/test/test_browser_thread.h"
+#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if defined(FULL_SAFE_BROWSING)
+#include "chrome/browser/safe_browsing/download_protection_service.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 {
+
+// No-op delegate.
+class NullWebContentsDelegate : public content::WebContentsDelegate {
+ public:
+ NullWebContentsDelegate() {}
+ ~NullWebContentsDelegate() {}
+};
+
+// Google Mock action that posts a task to the current message loop that invokes
+// the first argument of the mocked method as a callback. Said argument must be
+// a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is
+// bound as that parameter.
+// Example:
+// class FooClass {
+// public:
+// virtual void Foo(base::Callback<void(bool)> callback);
+// };
+// ...
+// EXPECT_CALL(mock_fooclass_instance, Foo(callback))
+// .WillOnce(ScheduleCallback(false));
+ACTION_P(ScheduleCallback, result0) {
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result0));
+}
+
+// Similar to ScheduleCallback, but binds 2 arguments.
+ACTION_P2(ScheduleCallback2, result0, result1) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE, base::Bind(arg0, result0, result1));
+}
+
+// Used with DownloadTestCase. Indicates the type of test case. The expectations
+// for the test is set based on the type.
+enum TestCaseType {
+ SAVE_AS,
+ AUTOMATIC,
+ FORCED // Requires that forced_file_path be non-empty.
+};
+
+// Used with DownloadTestCase. Type of intermediate filename to expect.
+enum TestCaseExpectIntermediate {
+ EXPECT_CRDOWNLOAD, // Expect path/to/target.crdownload.
+ EXPECT_UNCONFIRMED, // Expect path/to/Unconfirmed xxx.crdownload.
+ EXPECT_LOCAL_PATH, // Expect target path.
+};
+
+// Typical download test case. Used with
+// DownloadTargetDeterminerTest::RunTestCase().
+struct DownloadTestCase {
+ // Type of test.
+ TestCaseType test_type;
+
+ // The |expected_danger_type| is the expected danger type for the download as
+ // determined by CDMD. This value is also used to determine the behavior of
+ // DownloadProtectionService::IsSupportedDownload(), CDMD::CheckDownloadUrl()
+ // as necessary for flagging the download with as a dangerous download of type
benjhayden 2013/04/09 15:46:32 with as?
asanka 2013/04/16 20:34:01 Done.
+ // |expected_danger_type|.
+ content::DownloadDangerType expected_danger_type;
+
+ // Value of DownloadItem::GetURL()
+ const char* url;
+
+ // Value of DownloadItem::GetMimeType()
+ const char* mime_type;
+
+ // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath().
+ const base::FilePath::CharType* forced_file_path;
benjhayden 2013/04/09 15:46:32 What are all the spaces for?
asanka 2013/04/16 20:34:01 This was moved from CDMD unit tests. These used to
+
+ // Expected virtual path. Specified relative to the virtual download path. If
+ // empty, assumed to be the same as |expected_local_path|.
+ const base::FilePath::CharType* expected_virtual_path;
+
+ // Expected local path. Specified relative to the test download path.
+ const base::FilePath::CharType* expected_local_path;
+
+ // The path that DownloadTargetDeterminer will generate before handing off to
+ // the ReserveVirtualPath().
+ const base::FilePath::CharType* expected_generated_path;
+
+ // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the
+ // test run will expect ChromeDownloadManagerDelegate to prompt the user for a
+ // download location.
+ DownloadItem::TargetDisposition expected_disposition;
+
+ // Type of intermediate path to expect.
+ TestCaseExpectIntermediate expected_intermediate;
+};
+
+#if defined(FULL_SAFE_BROWSING)
+// DownloadProtectionService with mock methods. Since the SafeBrowsingService is
+// set to NULL, it is not safe to call any non-mocked methods other than
+// SetEnabled() and enabled().
+class TestDownloadProtectionService
+ : public safe_browsing::DownloadProtectionService {
+ public:
+ TestDownloadProtectionService()
+ : safe_browsing::DownloadProtectionService(NULL, NULL) {}
+ MOCK_METHOD2(CheckClientDownload,
+ void(DownloadItem*,
+ const CheckDownloadCallback&));
+ MOCK_METHOD2(CheckDownloadUrl,
+ void(const DownloadItem&,
+ const CheckDownloadCallback&));
+ MOCK_CONST_METHOD2(IsSupportedDownload,
+ bool(const DownloadItem&,
+ const base::FilePath&));
+
+ void SetupDefaults() {
+ ON_CALL(*this, CheckDownloadUrl(_, _))
+ .WillByDefault(WithArg<1>(ScheduleCallback(SAFE)));
+ ON_CALL(*this, IsSupportedDownload(_, _))
+ .WillByDefault(Return(false));
+ }
+};
+#endif
+
+class MockDownloadTargetDeterminerDelegate :
+ public DownloadTargetDeterminerDelegate {
+ public:
+ MOCK_METHOD0(GetDownloadProtectionService,
+ safe_browsing::DownloadProtectionService*());
+ MOCK_METHOD0(GetExtensionEventRouter, ExtensionDownloadsEventRouter*());
+ MOCK_METHOD3(PromptUserForDownloadPath,
+ void(content::DownloadItem*, const base::FilePath&,
+ const DownloadTargetDeterminerDelegate::FileSelectedCallback&));
+ MOCK_METHOD3(DetermineLocalPath,
+ void(DownloadItem*, const base::FilePath&,
+ const DownloadTargetDeterminerDelegate::LocalPathCallback&));
+ MOCK_METHOD4(ReserveVirtualPath,
+ void(DownloadItem*, const base::FilePath&, bool,
+ const DownloadTargetDeterminerDelegate::ReservedPathCallback&));
+
+ void SetupDefaults() {
+ ON_CALL(*this, GetExtensionEventRouter())
+ .WillByDefault(Return(
+ static_cast<ExtensionDownloadsEventRouter*>(NULL)));
+ ON_CALL(*this, GetDownloadProtectionService())
+ .WillByDefault(Return(
+ static_cast<safe_browsing::DownloadProtectionService*>(NULL)));
+ ON_CALL(*this, ReserveVirtualPath(_, _, _, _))
+ .WillByDefault(Invoke(
+ &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath));
+ }
+ private:
+ static void NullReserveVirtualPath(
+ DownloadItem* download,
+ const base::FilePath& virtual_path,
+ bool override,
+ const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback);
+};
+
+class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness {
+ public:
+ DownloadTargetDeterminerTest();
+
+ // ::testing::Test
+ virtual void SetUp() OVERRIDE;
+ virtual void TearDown() OVERRIDE;
+
+ // Creates MockDownloadItem and sets up default expectations.
+ content::MockDownloadItem* CreateActiveDownloadItem(int32 id);
+
+ // Sets the AutoOpenBasedOnExtension user preference for |path|.
+ void EnableAutoOpenBasedOnExtension(const base::FilePath& path);
+
+ // Set the kDownloadDefaultDirectory user preference to |path|.
+ void SetDefaultDownloadPath(const base::FilePath& path);
+
+ // Set the kDownloadDefaultDirectory managed preference to |path|.
+ void SetManagedDownloadPath(const base::FilePath& path);
+
+ // Set the kPromptForDownload user preference to |prompt|.
+ void SetPromptForDownload(bool prompt);
+
+ // Given the relative path |path|, returns the full path under the temporary
+ // downloads directory.
+ base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path);
+
+ // Run |test_case| using |item|.
+ void RunTestCaseWithDownloadItem(const DownloadTestCase& test_case,
+ content::MockDownloadItem* item);
+
+ // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem
+ // will be created for each test case and destroyed when the test case is
+ // complete.
+ void RunTestCases(const DownloadTestCase test_cases[],
+ size_t test_case_count);
+
+ 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();
+ }
+
+ void set_last_selected_directory(const base::FilePath& path) {
+ last_selected_directory_ = path;
+ }
+
+ private:
+ // Verifies that |target_path|, |disposition|, |expected_danger_type| and
+ // |intermediate_path| matches the expectations of |test_case|.
+ void DownloadTargetVerifier(const DownloadTestCase& test_case,
+ const base::FilePath& virtual_path,
+ const base::FilePath& local_path,
+ const base::FilePath& intermediate_path,
+ DownloadItem::TargetDisposition disposition,
+ content::DownloadDangerType danger_type);
+
+ scoped_ptr<DownloadPrefs> download_prefs_;
+ ::testing::StrictMock<MockDownloadTargetDeterminerDelegate> delegate_;
+ NullWebContentsDelegate web_contents_delegate_;
+ base::ScopedTempDir test_download_dir_;
+ base::FilePath test_virtual_dir_;
+ base::FilePath last_selected_directory_;
+ content::TestBrowserThread ui_thread_;
+ content::TestBrowserThread file_thread_;
+};
+
+DownloadTargetDeterminerTest::DownloadTargetDeterminerTest()
+ : ChromeRenderViewHostTestHarness(),
+ ui_thread_(content::BrowserThread::UI, &message_loop_),
+ file_thread_(content::BrowserThread::FILE, &message_loop_) {
+}
+
+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"));
+ SetDefaultDownloadPath(test_download_dir());
+ delegate_.SetupDefaults();
+}
+
+void DownloadTargetDeterminerTest::TearDown() {
+ download_prefs_.reset();
+ message_loop_.RunUntilIdle();
+ ChromeRenderViewHostTestHarness::TearDown();
+}
+
+content::MockDownloadItem*
+ DownloadTargetDeterminerTest::CreateActiveDownloadItem(int32 id) {
+ content::MockDownloadItem* item =
+ new ::testing::NiceMock<content::MockDownloadItem>();
+ ON_CALL(*item, GetDangerType())
+ .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
+ ON_CALL(*item, GetFullPath())
+ .WillByDefault(ReturnRefOfCopy(base::FilePath()));
+ ON_CALL(*item, GetHash())
+ .WillByDefault(ReturnRefOfCopy(std::string()));
+ ON_CALL(*item, GetReferrerUrl())
+ .WillByDefault(ReturnRefOfCopy(GURL()));
+ ON_CALL(*item, GetTargetFilePath())
+ .WillByDefault(ReturnRefOfCopy(base::FilePath()));
+ ON_CALL(*item, GetTransitionType())
+ .WillByDefault(Return(content::PAGE_TRANSITION_LINK));
+ ON_CALL(*item, GetWebContents())
+ .WillByDefault(Return(web_contents()));
+ ON_CALL(*item, HasUserGesture())
+ .WillByDefault(Return(false));
+ ON_CALL(*item, IsDangerous())
+ .WillByDefault(Return(false));
+ ON_CALL(*item, IsInProgress())
+ .WillByDefault(Return(true));
+ ON_CALL(*item, IsTemporary())
+ .WillByDefault(Return(false));
+ EXPECT_CALL(*item, GetBrowserContext())
+ .WillRepeatedly(Return(profile()));
+ EXPECT_CALL(*item, GetId())
+ .WillRepeatedly(Return(id));
+ EXPECT_CALL(*item, GetState())
+ .WillRepeatedly(Return(DownloadItem::IN_PROGRESS));
+ EXPECT_CALL(*item, AddObserver(_)).WillRepeatedly(Return());
+ EXPECT_CALL(*item, RemoveObserver(_)).WillRepeatedly(Return());
+ return item;
+}
+
+void DownloadTargetDeterminerTest::EnableAutoOpenBasedOnExtension(
+ const base::FilePath& path) {
+ EXPECT_TRUE(download_prefs_->EnableAutoOpenBasedOnExtension(path));
+}
+
+void DownloadTargetDeterminerTest::SetDefaultDownloadPath(
+ const base::FilePath& path) {
+ profile()->GetTestingPrefService()->
+ SetFilePath(prefs::kDownloadDefaultDirectory, 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::RunTestCaseWithDownloadItem(
+ const DownloadTestCase& test_case,
+ content::MockDownloadItem* item) {
+ // SetUp DownloadItem
+ GURL download_url(test_case.url);
+ std::vector<GURL> url_chain;
+ url_chain.push_back(download_url);
+ base::FilePath expected_generated_path =
+ GetPathInDownloadDir(test_case.expected_generated_path);
+ base::FilePath forced_file_path =
+ GetPathInDownloadDir(test_case.forced_file_path);
+ base::FilePath expected_virtual_path =
+ GetPathInDownloadDir(test_case.expected_virtual_path);
+ base::FilePath expected_local_path =
+ GetPathInDownloadDir(test_case.expected_local_path);
+ // If the virtual path is empty, we assume it is the same as the local path.
+ if (expected_virtual_path.empty())
+ expected_virtual_path = expected_local_path;
+ if (test_case.test_type == FORCED)
+ ASSERT_FALSE(forced_file_path.empty());
+
+ // Expectations for the DownloadItem:
+ EXPECT_CALL(*item, GetReferrerUrl())
+ .WillRepeatedly(ReturnRef(download_url));
+ EXPECT_CALL(*item, GetURL())
+ .WillRepeatedly(ReturnRef(download_url));
+ EXPECT_CALL(*item, GetUrlChain())
+ .WillRepeatedly(ReturnRef(url_chain));
+ EXPECT_CALL(*item, GetForcedFilePath())
+ .WillRepeatedly(ReturnRef(forced_file_path));
+ EXPECT_CALL(*item, GetMimeType())
+ .WillRepeatedly(Return(test_case.mime_type));
+ DownloadItem::TargetDisposition initial_disposition =
+ (test_case.test_type == SAVE_AS) ?
+ DownloadItem::TARGET_DISPOSITION_PROMPT :
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE;
+ EXPECT_CALL(*item, GetTargetDisposition())
+ .WillRepeatedly(Return(initial_disposition));
+
+ // Expectations for the delegate:
+ if (item->IsInProgress()) {
+ bool will_prompt = (test_case.expected_disposition ==
+ DownloadItem::TARGET_DISPOSITION_PROMPT);
+ bool has_virtual_path = !expected_virtual_path.empty();
+ bool needs_local_path = !will_prompt && has_virtual_path;
+ if (will_prompt) {
+ EXPECT_CALL(*delegate(),
+ PromptUserForDownloadPath(item, expected_generated_path, _))
+ .WillOnce(WithArg<2>(ScheduleCallback2(expected_virtual_path,
+ expected_local_path)));
+ } else {
+ EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
+ .Times(0);
+ }
+ if (needs_local_path) {
+ EXPECT_CALL(*delegate(),
+ DetermineLocalPath(item, expected_virtual_path, _))
+ .WillOnce(WithArg<2>(ScheduleCallback(expected_local_path)));
+ }
+ EXPECT_CALL(*delegate(),
+ ReserveVirtualPath(item, expected_generated_path,
+ forced_file_path.empty(), _));
+ EXPECT_CALL(*delegate(), GetExtensionEventRouter());
+ }
+ EXPECT_CALL(*delegate(), GetDownloadProtectionService())
+ .Times(AnyNumber());
+
+ // Kick off the test.
+ base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this);
+ DownloadTargetDeterminer::Start(
+ item, download_prefs_.get(), last_selected_directory_, delegate(),
+ base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier,
+ factory.GetWeakPtr(), test_case));
+ message_loop_.RunUntilIdle();
+ ::testing::Mock::VerifyAndClearExpectations(delegate());
+}
+
+void DownloadTargetDeterminerTest::RunTestCases(
+ 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));
+ SCOPED_TRACE(testing::Message() << "Running test case " << i);
+ RunTestCaseWithDownloadItem(test_cases[i], item.get());
+ }
+}
+
+void DownloadTargetDeterminerTest::DownloadTargetVerifier(
+ const DownloadTestCase& test_case,
+ const base::FilePath& virtual_path,
+ const base::FilePath& local_path,
+ const base::FilePath& intermediate_path,
+ DownloadItem::TargetDisposition disposition,
+ content::DownloadDangerType danger_type) {
+ base::FilePath expected_local_path(
+ GetPathInDownloadDir(test_case.expected_local_path));
+ base::FilePath expected_virtual_path(
+ GetPathInDownloadDir(test_case.expected_virtual_path));
+ if (expected_virtual_path.empty())
+ expected_virtual_path = expected_local_path;
+ EXPECT_EQ(expected_virtual_path.value(), virtual_path.value());
+ EXPECT_EQ(expected_local_path.value(), local_path.value());
+ EXPECT_EQ(test_case.expected_disposition, disposition);
+ EXPECT_EQ(test_case.expected_danger_type, danger_type);
+
+ switch (test_case.expected_intermediate) {
+ case EXPECT_CRDOWNLOAD:
+ EXPECT_EQ(download_util::GetCrDownloadPath(local_path).value(),
+ intermediate_path.value());
+ break;
+
+ case EXPECT_UNCONFIRMED:
+ // The paths (in English) look like: /path/Unconfirmed xxx.crdownload.
+ // Of this, we only check that the path is:
+ // 1. Not "/path/target.crdownload",
+ // 2. Points to the same directory as the target.
+ // 3. Has extension ".crdownload".
+ EXPECT_NE(download_util::GetCrDownloadPath(expected_local_path).value(),
+ intermediate_path.value());
+ EXPECT_EQ(expected_local_path.DirName().value(),
+ intermediate_path.DirName().value());
+ EXPECT_TRUE(intermediate_path.MatchesExtension(
+ FILE_PATH_LITERAL(".crdownload")));
+ break;
+
+ case EXPECT_LOCAL_PATH:
+ EXPECT_EQ(expected_local_path.value(), intermediate_path.value());
+ break;
+ }
+}
+
+// static
+void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath(
+ DownloadItem* download,
+ const base::FilePath& virtual_path,
+ bool override,
+ const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
+ callback.Run(virtual_path, true);
+}
+
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_Basic) {
+ const DownloadTestCase kBasicTestCases[] = {
+ {
+ // 0: Automatic Safe
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 1: Save_As Safe
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 2: Automatic Dangerous
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
+ "http://example.com/foo.html", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 3: Forced Safe
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "",
+ FILE_PATH_LITERAL("forced-foo.txt"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("forced-foo.txt"),
+ FILE_PATH_LITERAL("forced-foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_LOCAL_PATH
+ },
+ };
+
+ // The test assumes that .html files have a danger level of
+ // AllowOnUserGesture.
+ ASSERT_EQ(download_util::AllowOnUserGesture,
+ download_util::GetFileDangerLevel(
+ base::FilePath(FILE_PATH_LITERAL("foo.html"))));
+ RunTestCases(kBasicTestCases, arraysize(kBasicTestCases));
+}
+
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_CancelSaveAs) {
+ const DownloadTestCase kCancelSaveAsTestCases[] = {
+ {
+ // 2: Save_As Safe, Cancelled.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_LOCAL_PATH
+ }
+ };
+ RunTestCases(kCancelSaveAsTestCases, arraysize(kCancelSaveAsTestCases));
+}
+
+#if defined(FULL_SAFE_BROWSING)
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_MaybeDangerous) {
+ const DownloadTestCase kMaybeDangerousTestCases[] = {
+ // These test cases are run with foo.txt being considered a filetype
+ // supported by safe browsing.
+ {
+ // 0: Forced.
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
+ "http://example.com/foo.txt", "",
+ FILE_PATH_LITERAL("foo.txt"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 1: Save_As.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
+ "http://example.com/foo.txt", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 2: Automatic.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
+ "http://example.com/foo.txt", "",
+ FILE_PATH_LITERAL("foo.txt"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 3: Unsupported filetype.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo-unsupported.txt", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo-unsupported.txt"),
+ FILE_PATH_LITERAL("foo-unsupported.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+ };
+
+ base::FilePath supported_path(
+ GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt")));
+ base::FilePath unsupported_path(
+ GetPathInDownloadDir(FILE_PATH_LITERAL("foo-unsupported.txt")));
+ scoped_ptr<TestDownloadProtectionService> service(
+ new TestDownloadProtectionService);
+ service->SetupDefaults();
+ ON_CALL(*delegate(), GetDownloadProtectionService())
+ .WillByDefault(Return(service.get()));
+ EXPECT_CALL(*service.get(), IsSupportedDownload(_, supported_path))
+ .WillRepeatedly(Return(true));
+ EXPECT_CALL(*service.get(), IsSupportedDownload(_, unsupported_path))
+ .WillRepeatedly(Return(false));
+ EXPECT_CALL(*service.get(), CheckDownloadUrl(_, _))
+ .Times(arraysize(kMaybeDangerousTestCases));
+ RunTestCases(kMaybeDangerousTestCases, arraysize(kMaybeDangerousTestCases));
+}
+
+// The SafeBrowsing URL check is performed early. Make sure that a download item
+// that has been marked as DANGEROUS_URL behaves correctly.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DangerousURL) {
+ const DownloadTestCase kDangerousURLTestCases[] = {
+ {
+ // 0: Automatic Dangerous URL
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+ "http://phishing.example.com/foo.txt", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 1: Save As Dangerous URL
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+ "http://phishing.example.com/foo.txt", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 2: Forced Dangerous URL
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+ "http://phishing.example.com/foo.txt", "",
+ FILE_PATH_LITERAL("forced-foo.txt"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("forced-foo.txt"),
+ FILE_PATH_LITERAL("forced-foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes
+ // precendence.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+ "http://phishing.example.com/foo.html", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 4: Save As Dangerous URL + Dangerous file
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+ "http://phishing.example.com/foo.html", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 5: Forced Dangerous URL + Dangerous file
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
+ "http://phishing.example.com/foo.html", "",
+ FILE_PATH_LITERAL("forced-foo.html"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("forced-foo.html"),
+ FILE_PATH_LITERAL("forced-foo.html"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+ };
+
+ scoped_ptr<TestDownloadProtectionService> service(
+ new ::testing::StrictMock<TestDownloadProtectionService>());
+ service->SetupDefaults();
+ ON_CALL(*delegate(), GetDownloadProtectionService())
+ .WillByDefault(Return(service.get()));
+ EXPECT_CALL(*service.get(), IsSupportedDownload(_, _))
+ .Times(AnyNumber());
+ EXPECT_CALL(*service.get(), CheckDownloadUrl(_, _))
+ .Times(AnyNumber())
+ .WillRepeatedly(WithArg<1>(ScheduleCallback(
+ safe_browsing::DownloadProtectionService::DANGEROUS)));
+ RunTestCases(kDangerousURLTestCases, arraysize(kDangerousURLTestCases));
+}
+#endif // FULL_SAFE_BROWSING
+
+// Test whether the last saved directory is used for 'Save As' downloads.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LastSavePath) {
+ const DownloadTestCase kLastSavePathTestCasesPre[] = {
+ {
+ // 0: If the last save path is empty, then the default download directory
+ // should be used.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("bar.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ }
+ };
+
+ // These test cases are run with a last save path set to a non-emtpy local
+ // download directory.
+ const DownloadTestCase kLastSavePathTestCasesPost[] = {
+ {
+ // 0: This test case is run with the last download directory set to
+ // '<test_download_dir()>/foo'.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo/bar.txt"),
+ FILE_PATH_LITERAL("foo/foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 1: Start an automatic download. This should be saved to the user's
+ // default download directory and not the last used Save As directory.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+ };
+
+ // This test case is run with the last save path set to a non-empty virtual
+ // directory.
+ const DownloadTestCase kLastSavePathTestCasesVirtual[] = {
+ {
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL("virtual/foo/foo.txt"),
+ FILE_PATH_LITERAL("foo/bar.txt"),
+ FILE_PATH_LITERAL("virtual/foo/foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_LOCAL_PATH
+ },
+ };
+
+ {
+ SCOPED_TRACE(testing::Message()
+ << "Running with empty last_selected_directory");
+ RunTestCases(kLastSavePathTestCasesPre,
+ arraysize(kLastSavePathTestCasesPre));
+ }
+
+ // Try with a non-empty last save path.
+ {
+ SCOPED_TRACE(testing::Message()
+ << "Running with local last_selected_directory");
+ set_last_selected_directory(test_download_dir().AppendASCII("foo"));
+ RunTestCases(kLastSavePathTestCasesPost,
+ arraysize(kLastSavePathTestCasesPost));
+ }
+
+ // And again, but this time use a virtual directory.
+ {
+ SCOPED_TRACE(testing::Message()
+ << "Running with virtual last_selected_directory");
+ set_last_selected_directory(test_virtual_dir().AppendASCII("foo"));
+ RunTestCases(kLastSavePathTestCasesVirtual,
+ arraysize(kLastSavePathTestCasesVirtual));
+ }
+}
+
+// These tests are run with the default downloads folder set to a virtual
+// directory.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DefaultVirtual) {
+ const DownloadTestCase kDefaultVirtualTestCases[] = {
+ {
+ // 0: Automatic Safe
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL("virtual/foo.txt"),
+ FILE_PATH_LITERAL("foo-local.txt"),
+ FILE_PATH_LITERAL("virtual/foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_LOCAL_PATH
+ },
+
+ {
+ // 1: Save_As Safe.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ // The response to the download prompt is to choose the 'foo.txt' virtual
+ // path. However, the virtual path shouldn't be passed through
+ // DetermineLocalPath(). So the 'foo-x.txt' local path should make it
+ // through without being modified.
+ FILE_PATH_LITERAL("virtual/foo.txt"),
+ FILE_PATH_LITERAL("foo-x.txt"),
+
+ // The last selected download path is empty. So 'Save As' should default
+ // to using the virtual path for the suggested path.
+ FILE_PATH_LITERAL("virtual/foo.txt"),
+
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_LOCAL_PATH
+ },
+
+ {
+ // 2: Save_As Safe.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ // Response to the 'Save As' is to choose the local path for 'foo-x.txt'.
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo-x.txt"),
+
+ // The last selected download path is empty. So 'Save As' should default
+ // to using the virtual path for the suggested path.
+ FILE_PATH_LITERAL("virtual/foo.txt"),
+
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 3: Forced Safe. Doesn't override forced paths.
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "",
+ FILE_PATH_LITERAL("forced-foo.txt"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("forced-foo.txt"),
+ FILE_PATH_LITERAL("forced-foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_LOCAL_PATH
+ },
+ };
+
+ for (size_t i = 0; i < arraysize(kDefaultVirtualTestCases); ++i) {
+ scoped_ptr<content::MockDownloadItem> item(CreateActiveDownloadItem(i));
+ const DownloadTestCase& test_case = kDefaultVirtualTestCases[i];
+ SCOPED_TRACE(testing::Message() << "Running test case " << i);
+
+ // The default download directory is the virtual path.
+ SetDefaultDownloadPath(test_virtual_dir());
+
+ // The result of calling DetermineLocalPath is 'foo-local.txt' in the local
+ // downloads directory. It should only be called for automatic downloads.
+ if (test_case.test_type == AUTOMATIC) {
+ base::FilePath expected_virtual_path = GetPathInDownloadDir(
+ test_case.expected_virtual_path);
+ EXPECT_CALL(*delegate(), DetermineLocalPath(
+ item.get(), expected_virtual_path, _))
+ .WillRepeatedly(WithArg<2>(ScheduleCallback(
+ GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
+ } else {
+ EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
+ .Times(0);
+ }
+ RunTestCaseWithDownloadItem(test_case, item.get());
+ }
+}
+
+// Test that an inactive download will still get a virtual or local download
+// path.
+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("foo.txt"),
+ 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("foo.txt"),
+ FILE_PATH_LITERAL(""),
+ // Even though this is a SAVE_AS download, no prompt will be displayed to
+ // the user because the download is inactive.
+ FILE_PATH_LITERAL(""),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_LOCAL_PATH
+ }
+ };
+
+ for (size_t i = 0; i < arraysize(kInactiveTestCases); ++i) {
+ scoped_ptr<content::MockDownloadItem> item(CreateActiveDownloadItem(i));
+ SCOPED_TRACE(testing::Message() << "Running test case " << i);
+ EXPECT_CALL(*item.get(), IsInProgress())
+ .WillRepeatedly(Return(false));
+ RunTestCaseWithDownloadItem(kInactiveTestCases[i], item.get());
+ }
+}
+
+// If the reserved path could not be verified, then the user should see a
+// prompt.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) {
+ const DownloadTestCase kReservationFailedCases[] = {
+ {
+ // 0: Automatic download. Since the reservation fails, the disposition of
+ // the target is to prompt. Also the returned reserved path is ignored.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ },
+ };
+
+ // Setup ReserveVirtualPath() to fail.
+ ON_CALL(*delegate(), ReserveVirtualPath(_, _, _, _))
+ .WillByDefault(WithArg<3>(ScheduleCallback2(
+ GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")), false)));
+ RunTestCases(kReservationFailedCases, arraysize(kReservationFailedCases));
+}
+
+// If the local path could not be determined, the download should be cancelled.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LocalPathFailed) {
+ const DownloadTestCase kLocalPathFailedCases[] = {
+ {
+ // 0: Automatic download.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("virtual/foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_LOCAL_PATH
+ },
+ };
+
+ base::FilePath expected_virtual_path(
+ GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")));
+ // The default download directory is the virtual path.
+ SetDefaultDownloadPath(test_virtual_dir());
+ // Simulate failed call to DetermineLocalPath.
+ EXPECT_CALL(*delegate(), DetermineLocalPath(
+ _, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _))
+ .WillOnce(WithArg<2>(ScheduleCallback(base::FilePath())));
+ RunTestCases(kLocalPathFailedCases, arraysize(kLocalPathFailedCases));
+}
+
+// Downloads that have a danger level of AllowOnUserGesture should be marked as
+// safe depending on whether there was a user gesture associated with the
+// download and whether the referrer was visited prior to today.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_VisitedReferrer) {
+ const DownloadTestCase kVisitedReferrerCases[] = {
+ // http://visited.example.com/ is added to the history as a visit that
+ // happened prior to today.
+ {
+ // 0: Safe download due to visiting referrer before.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://visited.example.com/foo.html", "text/html",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 1: Dangerous due to not having visited referrer before.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
+ "http://not-visited.example.com/foo.html", "text/html",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 2: Safe because the user is being prompted.
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://not-visited.example.com/foo.html", "text/html",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 3: Safe because of forced path.
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://not-visited.example.com/foo.html", "text/html",
+ FILE_PATH_LITERAL("foo.html"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.html"),
+ FILE_PATH_LITERAL("foo.html"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_LOCAL_PATH
+ },
+ };
+
+ // This test assumes that the danger level of .html files is
+ // AllowOnUserGesture.
+ ASSERT_EQ(download_util::AllowOnUserGesture,
+ download_util::GetFileDangerLevel(
+ base::FilePath(FILE_PATH_LITERAL("foo.html"))));
+
+ // First the history service must exist.
+ profile()->CreateHistoryService(false, false);
+
+ GURL url("http://visited.example.com/visited-link.html");
+ // The time of visit is picked to be several seconds prior to the most recent
+ // midnight.
+ 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);
+
+ RunTestCases(kVisitedReferrerCases, arraysize(kVisitedReferrerCases));
+}
+
+// These test cases are run with "Prompt for download" user preference set to
+// true. Even with the preference set, some of these downloads should not cause
+// a prompt to appear.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways) {
+ const DownloadTestCase kPromptingTestCases[] = {
+ {
+ // 0: Safe Automatic - Should prompt because of "Prompt for download"
+ // preference setting.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_PROMPT,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 1: Automatic Browser Extension download. - Shouldn't prompt for browser
+ // extension downloads even if "Prompt for download" preference is set.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
+ "http://example.com/foo.crx",
+ extensions::Extension::kMimeType,
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.crx"),
+ FILE_PATH_LITERAL("foo.crx"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_UNCONFIRMED
+ },
+
+ {
+ // 2: Safe Forced - Shouldn't prompt.
+ FORCED,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL("foo.txt"),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_LOCAL_PATH
+ },
+
+ {
+ // 3: Automatic User Script - Shouldn't prompt for user script downloads
+ // even if "Prompt for download" preference is set.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.user.js", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.user.js"),
+ FILE_PATH_LITERAL("foo.user.js"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 4: Automatic - The filename extension is marked as one that we will
+ // open automatically. Shouldn't prompt.
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.dummy", "",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.dummy"),
+ FILE_PATH_LITERAL("foo.dummy"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+ };
+
+ SetPromptForDownload(true);
+ EnableAutoOpenBasedOnExtension(
+ base::FilePath(FILE_PATH_LITERAL("dummy.dummy")));
+ RunTestCases(kPromptingTestCases, arraysize(kPromptingTestCases));
+}
+
+// If the download path is managed, then we don't show any prompts.
+// Note that if the download path is managed, then PromptForDownload() is false.
+TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ManagedPath) {
+ const DownloadTestCase kManagedPathTestCases[] = {
+ {
+ // 0: Automatic Safe
+ AUTOMATIC,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+
+ {
+ // 1: Save_As Safe
+ SAVE_AS,
+ content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
+ "http://example.com/foo.txt", "text/plain",
+ FILE_PATH_LITERAL(""),
+
+ FILE_PATH_LITERAL(""),
+ FILE_PATH_LITERAL("foo.txt"),
+ FILE_PATH_LITERAL("foo.txt"),
+ DownloadItem::TARGET_DISPOSITION_OVERWRITE,
+
+ EXPECT_CRDOWNLOAD
+ },
+ };
+
+ SetManagedDownloadPath(test_download_dir());
+ ASSERT_TRUE(download_prefs()->IsDownloadPathManaged());
+ RunTestCases(kManagedPathTestCases, arraysize(kManagedPathTestCases));
+}
+
+} // namespace

Powered by Google App Engine
This is Rietveld 408576698