Home | History | Annotate | Download | only in download
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/at_exit.h"
      6 #include "base/files/file_path.h"
      7 #include "base/files/scoped_temp_dir.h"
      8 #include "base/message_loop/message_loop.h"
      9 #include "base/observer_list.h"
     10 #include "base/prefs/pref_service.h"
     11 #include "base/run_loop.h"
     12 #include "base/stl_util.h"
     13 #include "base/strings/string_util.h"
     14 #include "base/value_conversions.h"
     15 #include "chrome/browser/download/chrome_download_manager_delegate.h"
     16 #include "chrome/browser/download/download_extensions.h"
     17 #include "chrome/browser/download/download_prefs.h"
     18 #include "chrome/browser/download/download_target_determiner.h"
     19 #include "chrome/browser/download/download_target_info.h"
     20 #include "chrome/browser/history/history_service.h"
     21 #include "chrome/browser/history/history_service_factory.h"
     22 #include "chrome/browser/history/history_types.h"
     23 #include "chrome/common/pref_names.h"
     24 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
     25 #include "chrome/test/base/testing_pref_service_syncable.h"
     26 #include "chrome/test/base/testing_profile.h"
     27 #include "content/public/browser/download_interrupt_reasons.h"
     28 #include "content/public/browser/render_process_host.h"
     29 #include "content/public/browser/web_contents.h"
     30 #include "content/public/browser/web_contents_delegate.h"
     31 #include "content/public/test/mock_download_item.h"
     32 #include "content/public/test/test_browser_thread.h"
     33 #include "content/public/test/test_renderer_host.h"
     34 #include "content/public/test/web_contents_tester.h"
     35 #include "extensions/common/extension.h"
     36 #include "net/base/mime_util.h"
     37 #include "testing/gmock/include/gmock/gmock.h"
     38 #include "testing/gtest/include/gtest/gtest.h"
     39 
     40 #if defined(ENABLE_PLUGINS)
     41 #include "chrome/browser/plugins/plugin_prefs.h"
     42 #include "content/public/browser/plugin_service.h"
     43 #include "content/public/common/webplugininfo.h"
     44 #endif
     45 
     46 using ::testing::AnyNumber;
     47 using ::testing::Invoke;
     48 using ::testing::Ref;
     49 using ::testing::Return;
     50 using ::testing::ReturnRef;
     51 using ::testing::ReturnRefOfCopy;
     52 using ::testing::Truly;
     53 using ::testing::WithArg;
     54 using ::testing::_;
     55 using content::DownloadItem;
     56 
     57 namespace {
     58 
     59 // No-op delegate.
     60 class NullWebContentsDelegate : public content::WebContentsDelegate {
     61  public:
     62   NullWebContentsDelegate() {}
     63   virtual ~NullWebContentsDelegate() {}
     64 };
     65 
     66 // Google Mock action that posts a task to the current message loop that invokes
     67 // the first argument of the mocked method as a callback. Said argument must be
     68 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is
     69 // bound as that parameter.
     70 // Example:
     71 //   class FooClass {
     72 //    public:
     73 //     virtual void Foo(base::Callback<void(bool)> callback);
     74 //   };
     75 //   ...
     76 //   EXPECT_CALL(mock_fooclass_instance, Foo(callback))
     77 //     .WillOnce(ScheduleCallback(false));
     78 ACTION_P(ScheduleCallback, result0) {
     79   base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result0));
     80 }
     81 
     82 // Similar to ScheduleCallback, but binds 2 arguments.
     83 ACTION_P2(ScheduleCallback2, result0, result1) {
     84   base::MessageLoop::current()->PostTask(
     85       FROM_HERE, base::Bind(arg0, result0, result1));
     86 }
     87 
     88 // Used with DownloadTestCase. Indicates the type of test case. The expectations
     89 // for the test is set based on the type.
     90 enum TestCaseType {
     91   SAVE_AS,
     92   AUTOMATIC,
     93   FORCED  // Requires that forced_file_path be non-empty.
     94 };
     95 
     96 // Used with DownloadTestCase. Type of intermediate filename to expect.
     97 enum TestCaseExpectIntermediate {
     98   EXPECT_CRDOWNLOAD,   // Expect path/to/target.crdownload.
     99   EXPECT_UNCONFIRMED,  // Expect path/to/Unconfirmed xxx.crdownload.
    100   EXPECT_LOCAL_PATH,   // Expect target path.
    101 };
    102 
    103 // Typical download test case. Used with
    104 // DownloadTargetDeterminerTest::RunTestCase().
    105 struct DownloadTestCase {
    106   // Type of test.
    107   TestCaseType test_type;
    108 
    109   // Expected danger type. Verified at the end of target determination.
    110   content::DownloadDangerType expected_danger_type;
    111 
    112   // Value of DownloadItem::GetURL()
    113   const char* url;
    114 
    115   // Value of DownloadItem::GetMimeType()
    116   const char* mime_type;
    117 
    118   // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath().
    119   const base::FilePath::CharType* forced_file_path;
    120 
    121   // Expected virtual path. Specified relative to the virtual download path. If
    122   // empty, assumed to be the same as |expected_local_path|.
    123   const base::FilePath::CharType* expected_virtual_path;
    124 
    125   // Expected local path. Specified relative to the test download path.
    126   const base::FilePath::CharType* expected_local_path;
    127 
    128   // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the
    129   // test run will expect ChromeDownloadManagerDelegate to prompt the user for a
    130   // download location.
    131   DownloadItem::TargetDisposition expected_disposition;
    132 
    133   // Type of intermediate path to expect.
    134   TestCaseExpectIntermediate expected_intermediate;
    135 };
    136 
    137 class MockDownloadTargetDeterminerDelegate
    138     : public DownloadTargetDeterminerDelegate {
    139  public:
    140   MOCK_METHOD3(CheckDownloadUrl,
    141                void(content::DownloadItem*, const base::FilePath&,
    142                     const CheckDownloadUrlCallback&));
    143   MOCK_METHOD3(NotifyExtensions,
    144                void(content::DownloadItem*, const base::FilePath&,
    145                     const NotifyExtensionsCallback&));
    146   MOCK_METHOD3(PromptUserForDownloadPath,
    147                void(content::DownloadItem*, const base::FilePath&,
    148                     const FileSelectedCallback&));
    149   MOCK_METHOD3(DetermineLocalPath,
    150                void(DownloadItem*, const base::FilePath&,
    151                     const LocalPathCallback&));
    152   MOCK_METHOD5(ReserveVirtualPath,
    153                void(DownloadItem*, const base::FilePath&, bool,
    154                     DownloadPathReservationTracker::FilenameConflictAction,
    155                     const ReservedPathCallback&));
    156   MOCK_METHOD2(GetFileMimeType,
    157                void(const base::FilePath&,
    158                     const GetFileMimeTypeCallback&));
    159 
    160   void SetupDefaults() {
    161     ON_CALL(*this, CheckDownloadUrl(_, _, _))
    162         .WillByDefault(WithArg<2>(
    163             ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS)));
    164     ON_CALL(*this, NotifyExtensions(_, _, _))
    165         .WillByDefault(WithArg<2>(
    166             ScheduleCallback2(base::FilePath(),
    167                               DownloadPathReservationTracker::UNIQUIFY)));
    168     ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _))
    169         .WillByDefault(Invoke(
    170             &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath));
    171     ON_CALL(*this, PromptUserForDownloadPath(_, _, _))
    172         .WillByDefault(Invoke(
    173             &MockDownloadTargetDeterminerDelegate::NullPromptUser));
    174     ON_CALL(*this, DetermineLocalPath(_, _, _))
    175         .WillByDefault(Invoke(
    176             &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath));
    177     ON_CALL(*this, GetFileMimeType(_, _))
    178         .WillByDefault(WithArg<1>(
    179             ScheduleCallback("")));
    180   }
    181  private:
    182   static void NullReserveVirtualPath(
    183       DownloadItem* download,
    184       const base::FilePath& virtual_path,
    185       bool create_directory,
    186       DownloadPathReservationTracker::FilenameConflictAction conflict_action,
    187       const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback);
    188   static void NullPromptUser(
    189       DownloadItem* download, const base::FilePath& suggested_path,
    190       const FileSelectedCallback& callback);
    191   static void NullDetermineLocalPath(
    192       DownloadItem* download, const base::FilePath& virtual_path,
    193       const LocalPathCallback& callback);
    194 };
    195 
    196 class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness {
    197  public:
    198   // ::testing::Test
    199   virtual void SetUp() OVERRIDE;
    200   virtual void TearDown() OVERRIDE;
    201 
    202   // Creates MockDownloadItem and sets up default expectations.
    203   content::MockDownloadItem* CreateActiveDownloadItem(
    204       int32 id,
    205       const DownloadTestCase& test_case);
    206 
    207   // Sets the AutoOpenBasedOnExtension user preference for |path|.
    208   void EnableAutoOpenBasedOnExtension(const base::FilePath& path);
    209 
    210   // Set the kDownloadDefaultDirectory managed preference to |path|.
    211   void SetManagedDownloadPath(const base::FilePath& path);
    212 
    213   // Set the kPromptForDownload user preference to |prompt|.
    214   void SetPromptForDownload(bool prompt);
    215 
    216   // Given the relative path |path|, returns the full path under the temporary
    217   // downloads directory.
    218   base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path);
    219 
    220   // Run |test_case| using |item|.
    221   void RunTestCase(const DownloadTestCase& test_case,
    222                    const base::FilePath& initial_virtual_path,
    223                    content::MockDownloadItem* item);
    224 
    225   // Runs |test_case| with |item|. When the DownloadTargetDeterminer is done,
    226   // returns the resulting DownloadTargetInfo.
    227   scoped_ptr<DownloadTargetInfo> RunDownloadTargetDeterminer(
    228       const base::FilePath& initial_virtual_path,
    229       content::MockDownloadItem* item);
    230 
    231   // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem
    232   // will be created for each test case and destroyed when the test case is
    233   // complete.
    234   void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[],
    235                                   size_t test_case_count);
    236 
    237   // Verifies that |target_path|, |disposition|, |expected_danger_type| and
    238   // |intermediate_path| matches the expectations of |test_case|. Posts
    239   // |closure| to the current message loop when done.
    240   void VerifyDownloadTarget(const DownloadTestCase& test_case,
    241                             const DownloadTargetInfo* target_info);
    242 
    243   const base::FilePath& test_download_dir() const {
    244     return test_download_dir_.path();
    245   }
    246 
    247   const base::FilePath& test_virtual_dir() const {
    248     return test_virtual_dir_;
    249   }
    250 
    251   MockDownloadTargetDeterminerDelegate* delegate() {
    252     return &delegate_;
    253   }
    254 
    255   DownloadPrefs* download_prefs() {
    256     return download_prefs_.get();
    257   }
    258 
    259  private:
    260   scoped_ptr<DownloadPrefs> download_prefs_;
    261   ::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_;
    262   NullWebContentsDelegate web_contents_delegate_;
    263   base::ScopedTempDir test_download_dir_;
    264   base::FilePath test_virtual_dir_;
    265 };
    266 
    267 void DownloadTargetDeterminerTest::SetUp() {
    268   ChromeRenderViewHostTestHarness::SetUp();
    269   CHECK(profile());
    270   download_prefs_.reset(new DownloadPrefs(profile()));
    271   web_contents()->SetDelegate(&web_contents_delegate_);
    272   ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
    273   test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual"));
    274   download_prefs_->SetDownloadPath(test_download_dir());
    275   delegate_.SetupDefaults();
    276 }
    277 
    278 void DownloadTargetDeterminerTest::TearDown() {
    279   download_prefs_.reset();
    280   ChromeRenderViewHostTestHarness::TearDown();
    281 }
    282 
    283 content::MockDownloadItem*
    284 DownloadTargetDeterminerTest::CreateActiveDownloadItem(
    285     int32 id,
    286     const DownloadTestCase& test_case) {
    287   content::MockDownloadItem* item =
    288       new ::testing::NiceMock<content::MockDownloadItem>();
    289   GURL download_url(test_case.url);
    290   std::vector<GURL> url_chain;
    291   url_chain.push_back(download_url);
    292   base::FilePath forced_file_path =
    293       GetPathInDownloadDir(test_case.forced_file_path);
    294   DownloadItem::TargetDisposition initial_disposition =
    295       (test_case.test_type == SAVE_AS) ?
    296       DownloadItem::TARGET_DISPOSITION_PROMPT :
    297       DownloadItem::TARGET_DISPOSITION_OVERWRITE;
    298   EXPECT_EQ(test_case.test_type == FORCED,
    299             !forced_file_path.empty());
    300 
    301   ON_CALL(*item, GetBrowserContext())
    302       .WillByDefault(Return(profile()));
    303   ON_CALL(*item, GetDangerType())
    304       .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
    305   ON_CALL(*item, GetForcedFilePath())
    306       .WillByDefault(ReturnRefOfCopy(forced_file_path));
    307   ON_CALL(*item, GetFullPath())
    308       .WillByDefault(ReturnRefOfCopy(base::FilePath()));
    309   ON_CALL(*item, GetHash())
    310       .WillByDefault(ReturnRefOfCopy(std::string()));
    311   ON_CALL(*item, GetId())
    312       .WillByDefault(Return(id));
    313   ON_CALL(*item, GetLastReason())
    314       .WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_NONE));
    315   ON_CALL(*item, GetMimeType())
    316       .WillByDefault(Return(test_case.mime_type));
    317   ON_CALL(*item, GetReferrerUrl())
    318       .WillByDefault(ReturnRefOfCopy(download_url));
    319   ON_CALL(*item, GetState())
    320       .WillByDefault(Return(DownloadItem::IN_PROGRESS));
    321   ON_CALL(*item, GetTargetDisposition())
    322       .WillByDefault(Return(initial_disposition));
    323   ON_CALL(*item, GetTargetFilePath())
    324       .WillByDefault(ReturnRefOfCopy(base::FilePath()));
    325   ON_CALL(*item, GetTransitionType())
    326       .WillByDefault(Return(content::PAGE_TRANSITION_LINK));
    327   ON_CALL(*item, GetURL())
    328       .WillByDefault(ReturnRefOfCopy(download_url));
    329   ON_CALL(*item, GetUrlChain())
    330       .WillByDefault(ReturnRefOfCopy(url_chain));
    331   ON_CALL(*item, GetWebContents())
    332       .WillByDefault(Return(web_contents()));
    333   ON_CALL(*item, HasUserGesture())
    334       .WillByDefault(Return(true));
    335   ON_CALL(*item, IsDangerous())
    336       .WillByDefault(Return(false));
    337   ON_CALL(*item, IsTemporary())
    338       .WillByDefault(Return(false));
    339   return item;
    340 }
    341 
    342 void DownloadTargetDeterminerTest::EnableAutoOpenBasedOnExtension(
    343     const base::FilePath& path) {
    344   EXPECT_TRUE(download_prefs_->EnableAutoOpenBasedOnExtension(path));
    345 }
    346 
    347 void DownloadTargetDeterminerTest::SetManagedDownloadPath(
    348     const base::FilePath& path) {
    349   profile()->GetTestingPrefService()->
    350       SetManagedPref(prefs::kDownloadDefaultDirectory,
    351                      base::CreateFilePathValue(path));
    352 }
    353 
    354 void DownloadTargetDeterminerTest::SetPromptForDownload(bool prompt) {
    355   profile()->GetTestingPrefService()->
    356       SetBoolean(prefs::kPromptForDownload, prompt);
    357 }
    358 
    359 base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir(
    360     const base::FilePath::StringType& relative_path) {
    361   if (relative_path.empty())
    362     return base::FilePath();
    363   base::FilePath full_path(test_download_dir().Append(relative_path));
    364   return full_path.NormalizePathSeparators();
    365 }
    366 
    367 void DownloadTargetDeterminerTest::RunTestCase(
    368     const DownloadTestCase& test_case,
    369     const base::FilePath& initial_virtual_path,
    370     content::MockDownloadItem* item) {
    371   scoped_ptr<DownloadTargetInfo> target_info =
    372       RunDownloadTargetDeterminer(initial_virtual_path, item);
    373   VerifyDownloadTarget(test_case, target_info.get());
    374 }
    375 
    376 void CompletionCallbackWrapper(
    377     const base::Closure& closure,
    378     scoped_ptr<DownloadTargetInfo>* target_info_receiver,
    379     scoped_ptr<DownloadTargetInfo> target_info) {
    380   target_info_receiver->swap(target_info);
    381   base::MessageLoop::current()->PostTask(FROM_HERE, closure);
    382 }
    383 
    384 scoped_ptr<DownloadTargetInfo>
    385 DownloadTargetDeterminerTest::RunDownloadTargetDeterminer(
    386     const base::FilePath& initial_virtual_path,
    387     content::MockDownloadItem* item) {
    388   scoped_ptr<DownloadTargetInfo> target_info;
    389   base::RunLoop run_loop;
    390   DownloadTargetDeterminer::Start(
    391       item, initial_virtual_path, download_prefs_.get(), delegate(),
    392       base::Bind(&CompletionCallbackWrapper,
    393                  run_loop.QuitClosure(),
    394                  &target_info));
    395   run_loop.Run();
    396   ::testing::Mock::VerifyAndClearExpectations(delegate());
    397   return target_info.Pass();
    398 }
    399 
    400 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem(
    401     const DownloadTestCase test_cases[],
    402     size_t test_case_count) {
    403   for (size_t i = 0; i < test_case_count; ++i) {
    404     scoped_ptr<content::MockDownloadItem> item(
    405         CreateActiveDownloadItem(i, test_cases[i]));
    406     SCOPED_TRACE(testing::Message() << "Running test case " << i);
    407     RunTestCase(test_cases[i], base::FilePath(), item.get());
    408   }
    409 }
    410 
    411 void DownloadTargetDeterminerTest::VerifyDownloadTarget(
    412     const DownloadTestCase& test_case,
    413     const DownloadTargetInfo* target_info) {
    414   base::FilePath expected_local_path(
    415       GetPathInDownloadDir(test_case.expected_local_path));
    416   EXPECT_EQ(expected_local_path.value(), target_info->target_path.value());
    417   EXPECT_EQ(test_case.expected_disposition, target_info->target_disposition);
    418   EXPECT_EQ(test_case.expected_danger_type, target_info->danger_type);
    419 
    420   switch (test_case.expected_intermediate) {
    421     case EXPECT_CRDOWNLOAD:
    422       EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath(
    423                     target_info->target_path).value(),
    424                 target_info->intermediate_path.value());
    425       break;
    426 
    427     case EXPECT_UNCONFIRMED:
    428       // The paths (in English) look like: /path/Unconfirmed xxx.crdownload.
    429       // Of this, we only check that the path is:
    430       // 1. Not "/path/target.crdownload",
    431       // 2. Points to the same directory as the target.
    432       // 3. Has extension ".crdownload".
    433       // 4. Basename starts with "Unconfirmed ".
    434       EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path)
    435                     .value(),
    436                 target_info->intermediate_path.value());
    437       EXPECT_EQ(expected_local_path.DirName().value(),
    438                 target_info->intermediate_path.DirName().value());
    439       EXPECT_TRUE(target_info->intermediate_path.MatchesExtension(
    440           FILE_PATH_LITERAL(".crdownload")));
    441       EXPECT_EQ(0u,
    442                 target_info->intermediate_path.BaseName().value().find(
    443                     FILE_PATH_LITERAL("Unconfirmed ")));
    444       break;
    445 
    446     case EXPECT_LOCAL_PATH:
    447       EXPECT_EQ(expected_local_path.value(),
    448                 target_info->intermediate_path.value());
    449       break;
    450   }
    451 }
    452 
    453 // static
    454 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath(
    455     DownloadItem* download,
    456     const base::FilePath& virtual_path,
    457     bool create_directory,
    458     DownloadPathReservationTracker::FilenameConflictAction conflict_action,
    459     const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
    460   callback.Run(virtual_path, true);
    461 }
    462 
    463 // static
    464 void MockDownloadTargetDeterminerDelegate::NullPromptUser(
    465     DownloadItem* download, const base::FilePath& suggested_path,
    466     const FileSelectedCallback& callback) {
    467   callback.Run(suggested_path);
    468 }
    469 
    470 // static
    471 void MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath(
    472     DownloadItem* download, const base::FilePath& virtual_path,
    473     const LocalPathCallback& callback) {
    474   callback.Run(virtual_path);
    475 }
    476 
    477 // NotifyExtensions implementation that overrides the path so that the target
    478 // file is in a subdirectory called 'overridden'. If the extension is '.remove',
    479 // the extension is removed.
    480 void NotifyExtensionsOverridePath(
    481     content::DownloadItem* download,
    482     const base::FilePath& path,
    483     const DownloadTargetDeterminerDelegate::NotifyExtensionsCallback&
    484         callback) {
    485   base::FilePath new_path =
    486       base::FilePath()
    487       .AppendASCII("overridden")
    488       .Append(path.BaseName());
    489   if (new_path.MatchesExtension(FILE_PATH_LITERAL(".remove")))
    490     new_path = new_path.RemoveExtension();
    491   callback.Run(new_path, DownloadPathReservationTracker::UNIQUIFY);
    492 }
    493 
    494 void CheckDownloadUrlCheckExes(
    495     content::DownloadItem* download,
    496     const base::FilePath& path,
    497     const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback&
    498         callback) {
    499   if (path.MatchesExtension(FILE_PATH_LITERAL(".exe")))
    500     callback.Run(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT);
    501   else
    502     callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
    503 }
    504 
    505 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_Basic) {
    506   const DownloadTestCase kBasicTestCases[] = {
    507     {
    508       // 0: Automatic Safe
    509       AUTOMATIC,
    510       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    511       "http://example.com/foo.txt", "text/plain",
    512       FILE_PATH_LITERAL(""),
    513 
    514       FILE_PATH_LITERAL(""),
    515       FILE_PATH_LITERAL("foo.txt"),
    516       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    517 
    518       EXPECT_CRDOWNLOAD
    519     },
    520 
    521     {
    522       // 1: Save_As Safe
    523       SAVE_AS,
    524       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    525       "http://example.com/foo.txt", "text/plain",
    526       FILE_PATH_LITERAL(""),
    527 
    528       FILE_PATH_LITERAL(""),
    529       FILE_PATH_LITERAL("foo.txt"),
    530       DownloadItem::TARGET_DISPOSITION_PROMPT,
    531 
    532       EXPECT_CRDOWNLOAD
    533     },
    534 
    535     {
    536       // 2: Automatic Dangerous
    537       AUTOMATIC,
    538       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
    539       "http://example.com/foo.crx", "",
    540       FILE_PATH_LITERAL(""),
    541 
    542       FILE_PATH_LITERAL(""),
    543       FILE_PATH_LITERAL("foo.crx"),
    544       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    545 
    546       EXPECT_UNCONFIRMED
    547     },
    548 
    549     {
    550       // 3: Forced Safe
    551       FORCED,
    552       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    553       "http://example.com/foo.txt", "",
    554       FILE_PATH_LITERAL("forced-foo.txt"),
    555 
    556       FILE_PATH_LITERAL(""),
    557       FILE_PATH_LITERAL("forced-foo.txt"),
    558       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    559 
    560       EXPECT_LOCAL_PATH
    561     },
    562   };
    563 
    564   // The test assumes that .crx files have a danger level of
    565   // ALLOW_ON_USER_GESTURE.
    566   ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
    567             download_util::GetFileDangerLevel(
    568                 base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
    569   RunTestCasesWithActiveItem(kBasicTestCases, arraysize(kBasicTestCases));
    570 }
    571 
    572 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_CancelSaveAs) {
    573   const DownloadTestCase kCancelSaveAsTestCases[] = {
    574     {
    575       // 0: Save_As Safe, Cancelled.
    576       SAVE_AS,
    577       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    578       "http://example.com/foo.txt", "text/plain",
    579       FILE_PATH_LITERAL(""),
    580 
    581       FILE_PATH_LITERAL(""),
    582       FILE_PATH_LITERAL(""),
    583       DownloadItem::TARGET_DISPOSITION_PROMPT,
    584 
    585       EXPECT_LOCAL_PATH
    586     }
    587   };
    588   ON_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
    589       .WillByDefault(WithArg<2>(ScheduleCallback(base::FilePath())));
    590   RunTestCasesWithActiveItem(kCancelSaveAsTestCases,
    591                              arraysize(kCancelSaveAsTestCases));
    592 }
    593 
    594 // The SafeBrowsing check is performed early. Make sure that a download item
    595 // that has been marked as DANGEROUS_URL behaves correctly.
    596 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DangerousUrl) {
    597   const DownloadTestCase kSafeBrowsingTestCases[] = {
    598     {
    599       // 0: Automatic Dangerous URL
    600       AUTOMATIC,
    601       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
    602       "http://phishing.example.com/foo.txt", "",
    603       FILE_PATH_LITERAL(""),
    604 
    605       FILE_PATH_LITERAL(""),
    606       FILE_PATH_LITERAL("foo.txt"),
    607       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    608 
    609       EXPECT_UNCONFIRMED
    610     },
    611 
    612     {
    613       // 1: Save As Dangerous URL
    614       SAVE_AS,
    615       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
    616       "http://phishing.example.com/foo.txt", "",
    617       FILE_PATH_LITERAL(""),
    618 
    619       FILE_PATH_LITERAL(""),
    620       FILE_PATH_LITERAL("foo.txt"),
    621       DownloadItem::TARGET_DISPOSITION_PROMPT,
    622 
    623       EXPECT_UNCONFIRMED
    624     },
    625 
    626     {
    627       // 2: Forced Dangerous URL
    628       FORCED,
    629       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
    630       "http://phishing.example.com/foo.txt", "",
    631       FILE_PATH_LITERAL("forced-foo.txt"),
    632 
    633       FILE_PATH_LITERAL(""),
    634       FILE_PATH_LITERAL("forced-foo.txt"),
    635       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    636 
    637       EXPECT_UNCONFIRMED
    638     },
    639 
    640     {
    641       // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes
    642       // precendence.
    643       AUTOMATIC,
    644       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
    645       "http://phishing.example.com/foo.html", "",
    646       FILE_PATH_LITERAL(""),
    647 
    648       FILE_PATH_LITERAL(""),
    649       FILE_PATH_LITERAL("foo.html"),
    650       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    651 
    652       EXPECT_UNCONFIRMED
    653     },
    654 
    655     {
    656       // 4: Save As Dangerous URL + Dangerous file
    657       SAVE_AS,
    658       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
    659       "http://phishing.example.com/foo.html", "",
    660       FILE_PATH_LITERAL(""),
    661 
    662       FILE_PATH_LITERAL(""),
    663       FILE_PATH_LITERAL("foo.html"),
    664       DownloadItem::TARGET_DISPOSITION_PROMPT,
    665 
    666       EXPECT_UNCONFIRMED
    667     },
    668 
    669     {
    670       // 5: Forced Dangerous URL + Dangerous file
    671       FORCED,
    672       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
    673       "http://phishing.example.com/foo.html", "",
    674       FILE_PATH_LITERAL("forced-foo.html"),
    675 
    676       FILE_PATH_LITERAL(""),
    677       FILE_PATH_LITERAL("forced-foo.html"),
    678       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    679 
    680       EXPECT_UNCONFIRMED
    681     },
    682   };
    683 
    684   ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
    685       .WillByDefault(WithArg<2>(ScheduleCallback(
    686           content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL)));
    687   RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
    688                              arraysize(kSafeBrowsingTestCases));
    689 }
    690 
    691 // The SafeBrowsing check is performed early. Make sure that a download item
    692 // that has been marked as MAYBE_DANGEROUS_CONTENT behaves correctly.
    693 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_MaybeDangerousContent) {
    694   const DownloadTestCase kSafeBrowsingTestCases[] = {
    695     {
    696       // 0: Automatic Maybe dangerous content
    697       AUTOMATIC,
    698       content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
    699       "http://phishing.example.com/foo.exe", "",
    700       FILE_PATH_LITERAL(""),
    701 
    702       FILE_PATH_LITERAL(""),
    703       FILE_PATH_LITERAL("foo.exe"),
    704       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    705 
    706       EXPECT_UNCONFIRMED
    707     },
    708 
    709     {
    710       // 1: Save As Maybe dangerous content
    711       SAVE_AS,
    712       content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
    713       "http://phishing.example.com/foo.exe", "",
    714       FILE_PATH_LITERAL(""),
    715 
    716       FILE_PATH_LITERAL(""),
    717       FILE_PATH_LITERAL("foo.exe"),
    718       DownloadItem::TARGET_DISPOSITION_PROMPT,
    719 
    720       EXPECT_UNCONFIRMED
    721     },
    722 
    723     {
    724       // 2: Forced Maybe dangerous content
    725       FORCED,
    726       content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
    727       "http://phishing.example.com/foo.exe", "",
    728       FILE_PATH_LITERAL("forced-foo.exe"),
    729 
    730       FILE_PATH_LITERAL(""),
    731       FILE_PATH_LITERAL("forced-foo.exe"),
    732       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    733 
    734       EXPECT_UNCONFIRMED
    735     },
    736   };
    737 
    738   ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
    739       .WillByDefault(WithArg<2>(ScheduleCallback(
    740           content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)));
    741   RunTestCasesWithActiveItem(kSafeBrowsingTestCases,
    742                              arraysize(kSafeBrowsingTestCases));
    743 }
    744 
    745 // Test whether the last saved directory is used for 'Save As' downloads.
    746 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LastSavePath) {
    747   const DownloadTestCase kLastSavePathTestCasesPre[] = {
    748     {
    749       // 0: If the last save path is empty, then the default download directory
    750       //    should be used.
    751       SAVE_AS,
    752       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    753       "http://example.com/foo.txt", "text/plain",
    754       FILE_PATH_LITERAL(""),
    755 
    756       FILE_PATH_LITERAL(""),
    757       FILE_PATH_LITERAL("foo.txt"),
    758       DownloadItem::TARGET_DISPOSITION_PROMPT,
    759 
    760       EXPECT_CRDOWNLOAD
    761     }
    762   };
    763 
    764   // These test cases are run with a last save path set to a non-emtpy local
    765   // download directory.
    766   const DownloadTestCase kLastSavePathTestCasesPost[] = {
    767     {
    768       // 0: This test case is run with the last download directory set to
    769       //    '<test_download_dir()>/foo'.
    770       SAVE_AS,
    771       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    772       "http://example.com/foo.txt", "text/plain",
    773       FILE_PATH_LITERAL(""),
    774 
    775       FILE_PATH_LITERAL(""),
    776       FILE_PATH_LITERAL("foo/foo.txt"),
    777       DownloadItem::TARGET_DISPOSITION_PROMPT,
    778 
    779       EXPECT_CRDOWNLOAD
    780     },
    781 
    782     {
    783       // 1: Start an automatic download. This should be saved to the user's
    784       //    default download directory and not the last used Save As directory.
    785       AUTOMATIC,
    786       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    787       "http://example.com/foo.txt", "text/plain",
    788       FILE_PATH_LITERAL(""),
    789 
    790       FILE_PATH_LITERAL(""),
    791       FILE_PATH_LITERAL("foo.txt"),
    792       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    793 
    794       EXPECT_CRDOWNLOAD
    795     },
    796   };
    797 
    798   // This test case is run with the last save path set to a non-empty virtual
    799   // directory.
    800   const DownloadTestCase kLastSavePathTestCasesVirtual[] = {
    801     {
    802       SAVE_AS,
    803       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    804       "http://example.com/foo.txt", "text/plain",
    805       FILE_PATH_LITERAL(""),
    806 
    807       FILE_PATH_LITERAL("virtual/foo/foo.txt"),
    808       FILE_PATH_LITERAL("bar.txt"),
    809       DownloadItem::TARGET_DISPOSITION_PROMPT,
    810 
    811       EXPECT_LOCAL_PATH
    812     },
    813   };
    814 
    815   {
    816     SCOPED_TRACE(testing::Message()
    817                  << "Running with default download path");
    818     base::FilePath prompt_path =
    819         GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt"));
    820     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _));
    821     RunTestCasesWithActiveItem(kLastSavePathTestCasesPre,
    822                                arraysize(kLastSavePathTestCasesPre));
    823   }
    824 
    825   // Try with a non-empty last save path.
    826   {
    827     SCOPED_TRACE(testing::Message()
    828                  << "Running with local last_selected_directory");
    829     download_prefs()->SetSaveFilePath(test_download_dir().AppendASCII("foo"));
    830     base::FilePath prompt_path =
    831         GetPathInDownloadDir(FILE_PATH_LITERAL("foo/foo.txt"));
    832     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _));
    833     RunTestCasesWithActiveItem(kLastSavePathTestCasesPost,
    834                                arraysize(kLastSavePathTestCasesPost));
    835   }
    836 
    837   // And again, but this time use a virtual directory.
    838   {
    839     SCOPED_TRACE(testing::Message()
    840                  << "Running with virtual last_selected_directory");
    841     base::FilePath last_selected_dir = test_virtual_dir().AppendASCII("foo");
    842     base::FilePath virtual_path = last_selected_dir.AppendASCII("foo.txt");
    843     download_prefs()->SetSaveFilePath(last_selected_dir);
    844     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
    845         _, last_selected_dir.AppendASCII("foo.txt"), _));
    846     EXPECT_CALL(*delegate(), DetermineLocalPath(_, virtual_path, _))
    847         .WillOnce(WithArg<2>(ScheduleCallback(
    848             GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")))));
    849     RunTestCasesWithActiveItem(kLastSavePathTestCasesVirtual,
    850                                arraysize(kLastSavePathTestCasesVirtual));
    851   }
    852 }
    853 
    854 // These tests are run with the default downloads folder set to a virtual
    855 // directory.
    856 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DefaultVirtual) {
    857   // The default download directory is the virutal path.
    858   download_prefs()->SetDownloadPath(test_virtual_dir());
    859 
    860   {
    861     SCOPED_TRACE(testing::Message() << "Automatic Safe Download");
    862     const DownloadTestCase kAutomaticDownloadToVirtualDir = {
    863       AUTOMATIC,
    864       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    865       "http://example.com/foo.txt", "text/plain",
    866       FILE_PATH_LITERAL(""),
    867 
    868       // Downloaded to default virtual directory.
    869       FILE_PATH_LITERAL("virtual/foo.txt"),
    870       FILE_PATH_LITERAL("foo-local.txt"),
    871       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    872 
    873       EXPECT_LOCAL_PATH
    874     };
    875     EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
    876         .WillOnce(WithArg<2>(ScheduleCallback(
    877             GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
    878     RunTestCasesWithActiveItem(&kAutomaticDownloadToVirtualDir, 1);
    879   }
    880 
    881   {
    882     SCOPED_TRACE(testing::Message() << "Save As to virtual directory");
    883     const DownloadTestCase kSaveAsToVirtualDir = {
    884       SAVE_AS,
    885       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    886       "http://example.com/bar.txt", "text/plain",
    887       FILE_PATH_LITERAL(""),
    888 
    889       // The response to the download prompt is to choose the 'prompted.txt'
    890       // virtual path.
    891       FILE_PATH_LITERAL("virtual/prompted.txt"),
    892       FILE_PATH_LITERAL("foo-local.txt"),
    893       DownloadItem::TARGET_DISPOSITION_PROMPT,
    894 
    895       EXPECT_LOCAL_PATH
    896     };
    897     EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _))
    898         .WillOnce(WithArg<2>(ScheduleCallback(
    899             GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt")))));
    900     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
    901         _, test_virtual_dir().AppendASCII("bar.txt"), _))
    902         .WillOnce(WithArg<2>(ScheduleCallback(
    903             test_virtual_dir().AppendASCII("prompted.txt"))));
    904     RunTestCasesWithActiveItem(&kSaveAsToVirtualDir, 1);
    905   }
    906 
    907   {
    908     SCOPED_TRACE(testing::Message() << "Save As to local directory");
    909     const DownloadTestCase kSaveAsToLocalDir = {
    910       SAVE_AS,
    911       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    912       "http://example.com/bar.txt", "text/plain",
    913       FILE_PATH_LITERAL(""),
    914 
    915       // Response to the 'Save As' is to choose the local path for 'foo-x.txt'.
    916       FILE_PATH_LITERAL(""),
    917       FILE_PATH_LITERAL("foo-x.txt"),
    918       DownloadItem::TARGET_DISPOSITION_PROMPT,
    919 
    920       EXPECT_CRDOWNLOAD
    921     };
    922     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(
    923         _, test_virtual_dir().AppendASCII("bar.txt"), _))
    924         .WillOnce(WithArg<2>(ScheduleCallback(
    925             GetPathInDownloadDir(FILE_PATH_LITERAL("foo-x.txt")))));
    926     RunTestCasesWithActiveItem(&kSaveAsToLocalDir, 1);
    927   }
    928 
    929   {
    930     SCOPED_TRACE(testing::Message() << "Forced safe download");
    931     const DownloadTestCase kForcedSafe = {
    932       FORCED,
    933       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    934       "http://example.com/foo.txt", "",
    935       FILE_PATH_LITERAL("forced-foo.txt"),
    936 
    937       // Forced paths should be left as-is.
    938       FILE_PATH_LITERAL(""),
    939       FILE_PATH_LITERAL("forced-foo.txt"),
    940       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    941 
    942       EXPECT_LOCAL_PATH
    943     };
    944     RunTestCasesWithActiveItem(&kForcedSafe, 1);
    945   }
    946 }
    947 
    948 // Test that an inactive download will still get a virtual or local download
    949 // path.
    950 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_InactiveDownload) {
    951   const DownloadTestCase kInactiveTestCases[] = {
    952     {
    953       AUTOMATIC,
    954       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    955       "http://example.com/foo.txt", "text/plain",
    956       FILE_PATH_LITERAL(""),
    957 
    958       FILE_PATH_LITERAL("foo.txt"),
    959       FILE_PATH_LITERAL(""),
    960       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
    961 
    962       EXPECT_LOCAL_PATH
    963     },
    964 
    965     {
    966       SAVE_AS,
    967       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
    968       "http://example.com/foo.txt", "text/plain",
    969       FILE_PATH_LITERAL(""),
    970 
    971       FILE_PATH_LITERAL("foo.txt"),
    972       FILE_PATH_LITERAL(""),
    973       DownloadItem::TARGET_DISPOSITION_PROMPT,
    974 
    975       EXPECT_LOCAL_PATH
    976     }
    977   };
    978 
    979   for (size_t i = 0; i < arraysize(kInactiveTestCases); ++i) {
    980     SCOPED_TRACE(testing::Message() << "Running test case " << i);
    981     const DownloadTestCase& test_case = kInactiveTestCases[i];
    982     scoped_ptr<content::MockDownloadItem> item(
    983         CreateActiveDownloadItem(i, test_case));
    984     EXPECT_CALL(*item.get(), GetState())
    985         .WillRepeatedly(Return(content::DownloadItem::CANCELLED));
    986     // Even though one is a SAVE_AS download, no prompt will be displayed to
    987     // the user because the download is inactive.
    988     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
    989         .Times(0);
    990     RunTestCase(test_case, base::FilePath(), item.get());
    991   }
    992 }
    993 
    994 // If the reserved path could not be verified, then the user should see a
    995 // prompt.
    996 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) {
    997   const DownloadTestCase kReservationFailedCases[] = {
    998     {
    999       // 0: Automatic download. Since the reservation fails, the disposition of
   1000       // the target is to prompt, but the returned path is used.
   1001       AUTOMATIC,
   1002       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1003       "http://example.com/foo.txt", "text/plain",
   1004       FILE_PATH_LITERAL(""),
   1005 
   1006       FILE_PATH_LITERAL(""),
   1007       FILE_PATH_LITERAL("bar.txt"),
   1008       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1009 
   1010       EXPECT_CRDOWNLOAD
   1011     },
   1012   };
   1013 
   1014   // Setup ReserveVirtualPath() to fail.
   1015   ON_CALL(*delegate(), ReserveVirtualPath(_, _, _, _, _))
   1016       .WillByDefault(WithArg<4>(ScheduleCallback2(
   1017           GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")), false)));
   1018   RunTestCasesWithActiveItem(kReservationFailedCases,
   1019                              arraysize(kReservationFailedCases));
   1020 }
   1021 
   1022 // If the local path could not be determined, the download should be cancelled.
   1023 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LocalPathFailed) {
   1024   const DownloadTestCase kLocalPathFailedCases[] = {
   1025     {
   1026       // 0: Automatic download.
   1027       AUTOMATIC,
   1028       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1029       "http://example.com/foo.txt", "text/plain",
   1030       FILE_PATH_LITERAL(""),
   1031 
   1032       FILE_PATH_LITERAL(""),
   1033       FILE_PATH_LITERAL(""),
   1034       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1035 
   1036       EXPECT_LOCAL_PATH
   1037     },
   1038   };
   1039 
   1040   base::FilePath expected_virtual_path(
   1041       GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")));
   1042   // The default download directory is the virtual path.
   1043   download_prefs()->SetDownloadPath(test_virtual_dir());
   1044   // Simulate failed call to DetermineLocalPath.
   1045   EXPECT_CALL(*delegate(), DetermineLocalPath(
   1046       _, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _))
   1047       .WillOnce(WithArg<2>(ScheduleCallback(base::FilePath())));
   1048   RunTestCasesWithActiveItem(kLocalPathFailedCases,
   1049                              arraysize(kLocalPathFailedCases));
   1050 }
   1051 
   1052 // Downloads that have a danger level of ALLOW_ON_USER_GESTURE should be marked
   1053 // as safe depending on whether there was a user gesture associated with the
   1054 // download and whether the referrer was visited prior to today.
   1055 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_VisitedReferrer) {
   1056   const DownloadTestCase kVisitedReferrerCases[] = {
   1057     // http://visited.example.com/ is added to the history as a visit that
   1058     // happened prior to today.
   1059     {
   1060       // 0: Safe download due to visiting referrer before.
   1061       AUTOMATIC,
   1062       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1063       "http://visited.example.com/foo.crx", "application/xml",
   1064       FILE_PATH_LITERAL(""),
   1065 
   1066       FILE_PATH_LITERAL(""),
   1067       FILE_PATH_LITERAL("foo.crx"),
   1068       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1069 
   1070       EXPECT_CRDOWNLOAD
   1071     },
   1072 
   1073     {
   1074       // 1: Dangerous due to not having visited referrer before.
   1075       AUTOMATIC,
   1076       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1077       "http://not-visited.example.com/foo.crx", "application/xml",
   1078       FILE_PATH_LITERAL(""),
   1079 
   1080       FILE_PATH_LITERAL(""),
   1081       FILE_PATH_LITERAL("foo.crx"),
   1082       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1083 
   1084       EXPECT_UNCONFIRMED
   1085     },
   1086 
   1087     {
   1088       // 2: Safe because the user is being prompted.
   1089       SAVE_AS,
   1090       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1091       "http://not-visited.example.com/foo.crx", "application/xml",
   1092       FILE_PATH_LITERAL(""),
   1093 
   1094       FILE_PATH_LITERAL(""),
   1095       FILE_PATH_LITERAL("foo.crx"),
   1096       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1097 
   1098       EXPECT_CRDOWNLOAD
   1099     },
   1100 
   1101     {
   1102       // 3: Safe because of forced path.
   1103       FORCED,
   1104       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1105       "http://not-visited.example.com/foo.crx", "application/xml",
   1106       FILE_PATH_LITERAL("foo.crx"),
   1107 
   1108       FILE_PATH_LITERAL(""),
   1109       FILE_PATH_LITERAL("foo.crx"),
   1110       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1111 
   1112       EXPECT_LOCAL_PATH
   1113     },
   1114   };
   1115 
   1116   // This test assumes that the danger level of .crx files is
   1117   // ALLOW_ON_USER_GESTURE.
   1118   ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
   1119             download_util::GetFileDangerLevel(
   1120                 base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
   1121 
   1122   // First the history service must exist.
   1123   ASSERT_TRUE(profile()->CreateHistoryService(false, false));
   1124 
   1125   GURL url("http://visited.example.com/visited-link.html");
   1126   // The time of visit is picked to be several seconds prior to the most recent
   1127   // midnight.
   1128   base::Time time_of_visit(
   1129       base::Time::Now().LocalMidnight() - base::TimeDelta::FromSeconds(10));
   1130   HistoryService* history_service =
   1131       HistoryServiceFactory::GetForProfile(profile(), Profile::EXPLICIT_ACCESS);
   1132   ASSERT_TRUE(history_service);
   1133   history_service->AddPage(url, time_of_visit, history::SOURCE_BROWSED);
   1134 
   1135   RunTestCasesWithActiveItem(kVisitedReferrerCases,
   1136                              arraysize(kVisitedReferrerCases));
   1137 }
   1138 
   1139 // These test cases are run with "Prompt for download" user preference set to
   1140 // true.
   1141 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways) {
   1142   const DownloadTestCase kPromptingTestCases[] = {
   1143     {
   1144       // 0: Safe Automatic - Should prompt because of "Prompt for download"
   1145       //    preference setting.
   1146       AUTOMATIC,
   1147       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1148       "http://example.com/foo.txt", "text/plain",
   1149       FILE_PATH_LITERAL(""),
   1150 
   1151       FILE_PATH_LITERAL(""),
   1152       FILE_PATH_LITERAL("foo.txt"),
   1153       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1154 
   1155       EXPECT_CRDOWNLOAD
   1156     },
   1157 
   1158     {
   1159       // 1: Safe Forced - Shouldn't prompt.
   1160       FORCED,
   1161       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1162       "http://example.com/foo.txt", "text/plain",
   1163       FILE_PATH_LITERAL("foo.txt"),
   1164 
   1165       FILE_PATH_LITERAL(""),
   1166       FILE_PATH_LITERAL("foo.txt"),
   1167       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1168 
   1169       EXPECT_LOCAL_PATH
   1170     },
   1171 
   1172     {
   1173       // 2: Automatic - The filename extension is marked as one that we will
   1174       //    open automatically. Shouldn't prompt.
   1175       AUTOMATIC,
   1176       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1177       "http://example.com/foo.dummy", "",
   1178       FILE_PATH_LITERAL(""),
   1179 
   1180       FILE_PATH_LITERAL(""),
   1181       FILE_PATH_LITERAL("foo.dummy"),
   1182       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1183 
   1184       EXPECT_CRDOWNLOAD
   1185     },
   1186   };
   1187 
   1188   SetPromptForDownload(true);
   1189   EnableAutoOpenBasedOnExtension(
   1190       base::FilePath(FILE_PATH_LITERAL("dummy.dummy")));
   1191   RunTestCasesWithActiveItem(kPromptingTestCases,
   1192                              arraysize(kPromptingTestCases));
   1193 }
   1194 
   1195 #if !defined(OS_ANDROID)
   1196 // These test cases are run with "Prompt for download" user preference set to
   1197 // true. Automatic extension downloads shouldn't cause prompting.
   1198 // Android doesn't support extensions.
   1199 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways_Extension) {
   1200   const DownloadTestCase kPromptingTestCases[] = {
   1201     {
   1202       // 0: Automatic Browser Extension download. - Shouldn't prompt for browser
   1203       //    extension downloads even if "Prompt for download" preference is set.
   1204       AUTOMATIC,
   1205       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1206       "http://example.com/foo.crx",
   1207       extensions::Extension::kMimeType,
   1208       FILE_PATH_LITERAL(""),
   1209 
   1210       FILE_PATH_LITERAL(""),
   1211       FILE_PATH_LITERAL("foo.crx"),
   1212       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1213 
   1214       EXPECT_UNCONFIRMED
   1215     },
   1216 
   1217 #if defined(OS_WIN)
   1218     {
   1219       // 1: Automatic User Script - Shouldn't prompt for user script downloads
   1220       //    even if "Prompt for download" preference is set. ".js" files are
   1221       //    considered dangerous on Windows.
   1222       AUTOMATIC,
   1223       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1224       "http://example.com/foo.user.js", "",
   1225       FILE_PATH_LITERAL(""),
   1226 
   1227       FILE_PATH_LITERAL(""),
   1228       FILE_PATH_LITERAL("foo.user.js"),
   1229       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1230 
   1231       EXPECT_UNCONFIRMED
   1232     },
   1233 #else
   1234     {
   1235       // 1: Automatic User Script - Shouldn't prompt for user script downloads
   1236       //    even if "Prompt for download" preference is set.
   1237       AUTOMATIC,
   1238       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1239       "http://example.com/foo.user.js", "",
   1240       FILE_PATH_LITERAL(""),
   1241 
   1242       FILE_PATH_LITERAL(""),
   1243       FILE_PATH_LITERAL("foo.user.js"),
   1244       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1245 
   1246       EXPECT_CRDOWNLOAD
   1247     },
   1248 #endif
   1249   };
   1250 
   1251   SetPromptForDownload(true);
   1252   RunTestCasesWithActiveItem(kPromptingTestCases,
   1253                              arraysize(kPromptingTestCases));
   1254 }
   1255 #endif
   1256 
   1257 // If the download path is managed, then we don't show any prompts.
   1258 // Note that if the download path is managed, then PromptForDownload() is false.
   1259 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ManagedPath) {
   1260   const DownloadTestCase kManagedPathTestCases[] = {
   1261     {
   1262       // 0: Automatic Safe
   1263       AUTOMATIC,
   1264       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1265       "http://example.com/foo.txt", "text/plain",
   1266       FILE_PATH_LITERAL(""),
   1267 
   1268       FILE_PATH_LITERAL(""),
   1269       FILE_PATH_LITERAL("foo.txt"),
   1270       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1271 
   1272       EXPECT_CRDOWNLOAD
   1273     },
   1274 
   1275     {
   1276       // 1: Save_As Safe
   1277       SAVE_AS,
   1278       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1279       "http://example.com/foo.txt", "text/plain",
   1280       FILE_PATH_LITERAL(""),
   1281 
   1282       FILE_PATH_LITERAL(""),
   1283       FILE_PATH_LITERAL("foo.txt"),
   1284       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1285 
   1286       EXPECT_CRDOWNLOAD
   1287     },
   1288   };
   1289 
   1290   SetManagedDownloadPath(test_download_dir());
   1291   ASSERT_TRUE(download_prefs()->IsDownloadPathManaged());
   1292   RunTestCasesWithActiveItem(kManagedPathTestCases,
   1293                              arraysize(kManagedPathTestCases));
   1294 }
   1295 
   1296 // Test basic functionality supporting extensions that want to override download
   1297 // filenames.
   1298 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsSafe) {
   1299   const DownloadTestCase kNotifyExtensionsTestCases[] = {
   1300     {
   1301       // 0: Automatic Safe
   1302       AUTOMATIC,
   1303       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1304       "http://example.com/foo.txt", "text/plain",
   1305       FILE_PATH_LITERAL(""),
   1306 
   1307       FILE_PATH_LITERAL(""),
   1308       FILE_PATH_LITERAL("overridden/foo.txt"),
   1309       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1310 
   1311       EXPECT_CRDOWNLOAD
   1312     },
   1313 
   1314     {
   1315       // 1: Save_As Safe
   1316       SAVE_AS,
   1317       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1318       "http://example.com/foo.txt", "text/plain",
   1319       FILE_PATH_LITERAL(""),
   1320 
   1321       FILE_PATH_LITERAL(""),
   1322       FILE_PATH_LITERAL("overridden/foo.txt"),
   1323       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1324 
   1325       EXPECT_CRDOWNLOAD
   1326     },
   1327 
   1328     {
   1329       // 2: Automatic Dangerous
   1330       AUTOMATIC,
   1331       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1332       "http://example.com/foo.crx", "",
   1333       FILE_PATH_LITERAL(""),
   1334 
   1335       FILE_PATH_LITERAL(""),
   1336       FILE_PATH_LITERAL("overridden/foo.crx"),
   1337       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1338 
   1339       EXPECT_UNCONFIRMED
   1340     },
   1341 
   1342     {
   1343       // 3: Forced Safe
   1344       FORCED,
   1345       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1346       "http://example.com/foo.txt", "",
   1347       FILE_PATH_LITERAL("forced-foo.txt"),
   1348 
   1349       FILE_PATH_LITERAL(""),
   1350       FILE_PATH_LITERAL("forced-foo.txt"),
   1351       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1352 
   1353       EXPECT_LOCAL_PATH
   1354     },
   1355   };
   1356 
   1357   ON_CALL(*delegate(), NotifyExtensions(_, _, _))
   1358       .WillByDefault(Invoke(&NotifyExtensionsOverridePath));
   1359   RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
   1360                              arraysize(kNotifyExtensionsTestCases));
   1361 }
   1362 
   1363 // Test that filenames provided by extensions are passed into SafeBrowsing
   1364 // checks and dangerous download checks.
   1365 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsUnsafe) {
   1366   const DownloadTestCase kNotifyExtensionsTestCases[] = {
   1367     {
   1368       // 0: Automatic Safe : Later overridden by a dangerous filetype.
   1369       AUTOMATIC,
   1370       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1371       "http://example.com/foo.crx.remove", "text/plain",
   1372       FILE_PATH_LITERAL(""),
   1373 
   1374       FILE_PATH_LITERAL(""),
   1375       FILE_PATH_LITERAL("overridden/foo.crx"),
   1376       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1377 
   1378       EXPECT_UNCONFIRMED
   1379     },
   1380 
   1381     {
   1382       // 1: Automatic Safe : Later overridden by a potentially dangerous
   1383       // filetype.
   1384       AUTOMATIC,
   1385       content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
   1386       "http://example.com/foo.exe.remove", "text/plain",
   1387       FILE_PATH_LITERAL(""),
   1388 
   1389       FILE_PATH_LITERAL(""),
   1390       FILE_PATH_LITERAL("overridden/foo.exe"),
   1391       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1392 
   1393       EXPECT_UNCONFIRMED
   1394     },
   1395   };
   1396 
   1397   ON_CALL(*delegate(), NotifyExtensions(_, _, _))
   1398       .WillByDefault(Invoke(&NotifyExtensionsOverridePath));
   1399   ON_CALL(*delegate(), CheckDownloadUrl(_, _, _))
   1400       .WillByDefault(Invoke(&CheckDownloadUrlCheckExes));
   1401   RunTestCasesWithActiveItem(kNotifyExtensionsTestCases,
   1402                              arraysize(kNotifyExtensionsTestCases));
   1403 }
   1404 
   1405 // Test that conflict actions set by extensions are passed correctly into
   1406 // ReserveVirtualPath.
   1407 TEST_F(DownloadTargetDeterminerTest,
   1408        TargetDeterminer_NotifyExtensionsConflict) {
   1409   const DownloadTestCase kNotifyExtensionsTestCase = {
   1410     AUTOMATIC,
   1411     content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1412     "http://example.com/foo.txt", "text/plain",
   1413     FILE_PATH_LITERAL(""),
   1414 
   1415     FILE_PATH_LITERAL(""),
   1416     FILE_PATH_LITERAL("overridden/foo.txt"),
   1417     DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1418 
   1419     EXPECT_CRDOWNLOAD
   1420   };
   1421 
   1422   const DownloadTestCase& test_case = kNotifyExtensionsTestCase;
   1423   scoped_ptr<content::MockDownloadItem> item(
   1424       CreateActiveDownloadItem(0, test_case));
   1425   base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt"));
   1426   base::FilePath full_overridden_path =
   1427       GetPathInDownloadDir(overridden_path.value());
   1428 
   1429   // First case: An extension sets the conflict_action to OVERWRITE.
   1430   EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
   1431       .WillOnce(WithArg<2>(
   1432           ScheduleCallback2(overridden_path,
   1433                             DownloadPathReservationTracker::OVERWRITE)));
   1434   EXPECT_CALL(*delegate(), ReserveVirtualPath(
   1435       _, full_overridden_path, true, DownloadPathReservationTracker::OVERWRITE,
   1436       _)).WillOnce(WithArg<4>(
   1437           ScheduleCallback2(full_overridden_path, true)));
   1438 
   1439   RunTestCase(test_case, base::FilePath(), item.get());
   1440 
   1441   // Second case: An extension sets the conflict_action to PROMPT.
   1442   EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
   1443       .WillOnce(WithArg<2>(
   1444           ScheduleCallback2(overridden_path,
   1445                             DownloadPathReservationTracker::PROMPT)));
   1446   EXPECT_CALL(*delegate(), ReserveVirtualPath(
   1447       _, full_overridden_path, true, DownloadPathReservationTracker::PROMPT, _))
   1448       .WillOnce(WithArg<4>(
   1449           ScheduleCallback2(full_overridden_path, true)));
   1450   RunTestCase(test_case, base::FilePath(), item.get());
   1451 }
   1452 
   1453 // Test that relative paths returned by extensions are always relative to the
   1454 // default downloads path.
   1455 TEST_F(DownloadTargetDeterminerTest,
   1456        TargetDeterminer_NotifyExtensionsDefaultPath) {
   1457   const DownloadTestCase kNotifyExtensionsTestCase = {
   1458     SAVE_AS,
   1459     content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1460     "http://example.com/foo.txt", "text/plain",
   1461     FILE_PATH_LITERAL(""),
   1462 
   1463     FILE_PATH_LITERAL(""),
   1464     FILE_PATH_LITERAL("overridden/foo.txt"),
   1465     DownloadItem::TARGET_DISPOSITION_PROMPT,
   1466 
   1467     EXPECT_CRDOWNLOAD
   1468   };
   1469 
   1470   const DownloadTestCase& test_case = kNotifyExtensionsTestCase;
   1471   scoped_ptr<content::MockDownloadItem> item(
   1472       CreateActiveDownloadItem(0, test_case));
   1473   base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt"));
   1474   base::FilePath full_overridden_path =
   1475       GetPathInDownloadDir(overridden_path.value());
   1476 
   1477   download_prefs()->SetSaveFilePath(GetPathInDownloadDir(
   1478       FILE_PATH_LITERAL("last_selected")));
   1479 
   1480   EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
   1481       .WillOnce(WithArg<2>(
   1482           ScheduleCallback2(overridden_path,
   1483                             DownloadPathReservationTracker::UNIQUIFY)));
   1484   EXPECT_CALL(*delegate(),
   1485               PromptUserForDownloadPath(_, full_overridden_path, _))
   1486       .WillOnce(WithArg<2>(
   1487           ScheduleCallback(full_overridden_path)));
   1488   RunTestCase(test_case, base::FilePath(), item.get());
   1489 }
   1490 
   1491 TEST_F(DownloadTargetDeterminerTest,
   1492        TargetDeterminer_InitialVirtualPathUnsafe) {
   1493   const base::FilePath::CharType* kInitialPath =
   1494       FILE_PATH_LITERAL("some_path/bar.html");
   1495 
   1496   const DownloadTestCase kInitialPathTestCase = {
   1497     // 0: Save As Save. The path generated based on the DownloadItem is safe,
   1498     // but the initial path is unsafe. However, the download is not considered
   1499     // dangerous since the user has been prompted.
   1500     SAVE_AS,
   1501     content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1502     "http://example.com/foo.txt", "text/plain",
   1503     FILE_PATH_LITERAL(""),
   1504 
   1505     FILE_PATH_LITERAL(""),
   1506     kInitialPath,
   1507     DownloadItem::TARGET_DISPOSITION_PROMPT,
   1508 
   1509     EXPECT_CRDOWNLOAD
   1510   };
   1511 
   1512   const DownloadTestCase& test_case = kInitialPathTestCase;
   1513   scoped_ptr<content::MockDownloadItem> item(
   1514       CreateActiveDownloadItem(1, test_case));
   1515   EXPECT_CALL(*item, GetLastReason())
   1516       .WillRepeatedly(Return(
   1517           content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
   1518   EXPECT_CALL(*item, GetTargetDisposition())
   1519       .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT));
   1520   RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
   1521 }
   1522 
   1523 // Prompting behavior for resumed downloads is based on the last interrupt
   1524 // reason. If the reason indicates that the target path may not be suitable for
   1525 // the download (ACCESS_DENIED, NO_SPACE, etc..), then the user should be
   1526 // prompted, and not otherwise. These test cases shouldn't result in prompting
   1527 // since the error is set to NETWORK_FAILED.
   1528 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedNoPrompt) {
   1529   // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital
   1530   // path.
   1531   const base::FilePath::CharType* kInitialPath =
   1532       FILE_PATH_LITERAL("some_path/bar.txt");
   1533 
   1534   const DownloadTestCase kResumedTestCases[] = {
   1535     {
   1536       // 0: Automatic Safe: Initial path is ignored since the user has not been
   1537       // prompted before.
   1538       AUTOMATIC,
   1539       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1540       "http://example.com/foo.txt", "text/plain",
   1541       FILE_PATH_LITERAL(""),
   1542 
   1543       FILE_PATH_LITERAL(""),
   1544       FILE_PATH_LITERAL("foo.txt"),
   1545       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1546 
   1547       EXPECT_CRDOWNLOAD
   1548     },
   1549 
   1550     {
   1551       // 1: Save_As Safe: Initial path used.
   1552       SAVE_AS,
   1553       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1554       "http://example.com/foo.txt", "text/plain",
   1555       FILE_PATH_LITERAL(""),
   1556 
   1557       FILE_PATH_LITERAL(""),
   1558       kInitialPath,
   1559       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1560 
   1561       EXPECT_CRDOWNLOAD
   1562     },
   1563 
   1564     {
   1565       // 2: Automatic Dangerous: Initial path is ignored since the user hasn't
   1566       // been prompted before.
   1567       AUTOMATIC,
   1568       content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1569       "http://example.com/foo.crx", "",
   1570       FILE_PATH_LITERAL(""),
   1571 
   1572       FILE_PATH_LITERAL(""),
   1573       FILE_PATH_LITERAL("foo.crx"),
   1574       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1575 
   1576       EXPECT_UNCONFIRMED
   1577     },
   1578 
   1579     {
   1580       // 3: Forced Safe: Initial path is ignored due to the forced path.
   1581       FORCED,
   1582       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1583       "http://example.com/foo.txt", "",
   1584       FILE_PATH_LITERAL("forced-foo.txt"),
   1585 
   1586       FILE_PATH_LITERAL(""),
   1587       FILE_PATH_LITERAL("forced-foo.txt"),
   1588       DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1589 
   1590       EXPECT_LOCAL_PATH
   1591     },
   1592   };
   1593 
   1594   // The test assumes that .crx files have a danger level of
   1595   // ALLOW_ON_USER_GESTURE.
   1596   ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
   1597             download_util::GetFileDangerLevel(
   1598                 base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
   1599   for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) {
   1600     SCOPED_TRACE(testing::Message() << "Running test case " << i);
   1601     const DownloadTestCase& test_case = kResumedTestCases[i];
   1602     scoped_ptr<content::MockDownloadItem> item(
   1603         CreateActiveDownloadItem(i, test_case));
   1604     base::FilePath expected_path =
   1605         GetPathInDownloadDir(test_case.expected_local_path);
   1606     ON_CALL(*item.get(), GetLastReason())
   1607         .WillByDefault(Return(
   1608             content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
   1609     // Extensions should be notified if a new path is being generated and there
   1610     // is no forced path. In the test cases above, this is true for tests with
   1611     // type == AUTOMATIC.
   1612     EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
   1613         .Times(test_case.test_type == AUTOMATIC ? 1 : 0);
   1614     EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _));
   1615     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _))
   1616         .Times(0);
   1617     EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _));
   1618     EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _));
   1619     RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
   1620   }
   1621 
   1622 }
   1623 
   1624 // Test that a forced download doesn't prompt, even if the interrupt reason
   1625 // suggests that the target path may not be suitable for downloads.
   1626 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedForcedDownload) {
   1627   const base::FilePath::CharType* kInitialPath =
   1628       FILE_PATH_LITERAL("some_path/bar.txt");
   1629   const DownloadTestCase kResumedForcedDownload = {
   1630     // 3: Forced Safe
   1631     FORCED,
   1632     content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1633     "http://example.com/foo.txt", "",
   1634     FILE_PATH_LITERAL("forced-foo.txt"),
   1635 
   1636     FILE_PATH_LITERAL(""),
   1637     FILE_PATH_LITERAL("forced-foo.txt"),
   1638     DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1639 
   1640     EXPECT_LOCAL_PATH
   1641   };
   1642 
   1643   const DownloadTestCase& test_case = kResumedForcedDownload;
   1644   base::FilePath expected_path =
   1645       GetPathInDownloadDir(test_case.expected_local_path);
   1646   scoped_ptr<content::MockDownloadItem> item(
   1647       CreateActiveDownloadItem(0, test_case));
   1648   ON_CALL(*item.get(), GetLastReason())
   1649       .WillByDefault(Return(content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
   1650   EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
   1651       .Times(test_case.test_type == AUTOMATIC ? 1 : 0);
   1652   EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _));
   1653   EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _))
   1654       .Times(0);
   1655   EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _));
   1656   EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _));
   1657   RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
   1658 }
   1659 
   1660 // Prompting behavior for resumed downloads is based on the last interrupt
   1661 // reason. If the reason indicates that the target path may not be suitable for
   1662 // the download (ACCESS_DENIED, NO_SPACE, etc..), then the user should be
   1663 // prompted, and not otherwise. These test cases result in prompting since the
   1664 // error is set to NO_SPACE.
   1665 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ResumedWithPrompt) {
   1666   // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital
   1667   // path.
   1668   const base::FilePath::CharType* kInitialPath =
   1669       FILE_PATH_LITERAL("some_path/bar.txt");
   1670 
   1671   const DownloadTestCase kResumedTestCases[] = {
   1672     {
   1673       // 0: Automatic Safe
   1674       AUTOMATIC,
   1675       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1676       "http://example.com/foo.txt", "text/plain",
   1677       FILE_PATH_LITERAL(""),
   1678 
   1679       FILE_PATH_LITERAL(""),
   1680       FILE_PATH_LITERAL("foo.txt"),
   1681       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1682 
   1683       EXPECT_CRDOWNLOAD
   1684     },
   1685 
   1686     {
   1687       // 1: Save_As Safe
   1688       SAVE_AS,
   1689       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1690       "http://example.com/foo.txt", "text/plain",
   1691       FILE_PATH_LITERAL(""),
   1692 
   1693       FILE_PATH_LITERAL(""),
   1694       kInitialPath,
   1695       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1696 
   1697       EXPECT_CRDOWNLOAD
   1698     },
   1699 
   1700     {
   1701       // 2: Automatic Dangerous
   1702       AUTOMATIC,
   1703       content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1704       "http://example.com/foo.crx", "",
   1705       FILE_PATH_LITERAL(""),
   1706 
   1707       FILE_PATH_LITERAL(""),
   1708       FILE_PATH_LITERAL("foo.crx"),
   1709       DownloadItem::TARGET_DISPOSITION_PROMPT,
   1710 
   1711       EXPECT_CRDOWNLOAD
   1712     },
   1713   };
   1714 
   1715   // The test assumes that .xml files have a danger level of
   1716   // ALLOW_ON_USER_GESTURE.
   1717   ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
   1718             download_util::GetFileDangerLevel(
   1719                 base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
   1720   for (size_t i = 0; i < arraysize(kResumedTestCases); ++i) {
   1721     SCOPED_TRACE(testing::Message() << "Running test case " << i);
   1722     download_prefs()->SetSaveFilePath(test_download_dir());
   1723     const DownloadTestCase& test_case = kResumedTestCases[i];
   1724     base::FilePath expected_path =
   1725         GetPathInDownloadDir(test_case.expected_local_path);
   1726     scoped_ptr<content::MockDownloadItem> item(
   1727         CreateActiveDownloadItem(i, test_case));
   1728     ON_CALL(*item.get(), GetLastReason())
   1729         .WillByDefault(Return(
   1730             content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE));
   1731     EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _))
   1732         .Times(test_case.test_type == AUTOMATIC ? 1 : 0);
   1733     EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _));
   1734     EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _));
   1735     EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _));
   1736     EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _));
   1737     RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get());
   1738   }
   1739 }
   1740 
   1741 // Test intermediate filename generation for resumed downloads.
   1742 TEST_F(DownloadTargetDeterminerTest,
   1743        TargetDeterminer_IntermediateNameForResumed) {
   1744   // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital
   1745   // path.
   1746   const base::FilePath::CharType kInitialPath[] =
   1747       FILE_PATH_LITERAL("some_path/bar.txt");
   1748 
   1749   struct IntermediateNameTestCase {
   1750     // General test case settings.
   1751     DownloadTestCase general;
   1752 
   1753     // Value of DownloadItem::GetFullPath() during test run, relative
   1754     // to test download path.
   1755     const base::FilePath::CharType* initial_intermediate_path;
   1756 
   1757     // Expected intermediate path relatvie to the test download path. An exact
   1758     // match is performed if this string is non-empty. Ignored otherwise.
   1759     const base::FilePath::CharType* expected_intermediate_path;
   1760   } kIntermediateNameTestCases[] = {
   1761     {
   1762       {
   1763         // 0: Automatic Safe
   1764         AUTOMATIC,
   1765         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1766         "http://example.com/foo.txt", "text/plain",
   1767         FILE_PATH_LITERAL(""),
   1768 
   1769         FILE_PATH_LITERAL(""),
   1770         FILE_PATH_LITERAL("foo.txt"),
   1771         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1772 
   1773         EXPECT_CRDOWNLOAD
   1774       },
   1775       FILE_PATH_LITERAL("bar.txt.crdownload"),
   1776       FILE_PATH_LITERAL("foo.txt.crdownload")
   1777     },
   1778 
   1779     {
   1780       {
   1781         // 1: Save_As Safe
   1782         SAVE_AS,
   1783         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1784         "http://example.com/foo.txt", "text/plain",
   1785         FILE_PATH_LITERAL(""),
   1786 
   1787         FILE_PATH_LITERAL(""),
   1788         kInitialPath,
   1789         DownloadItem::TARGET_DISPOSITION_PROMPT,
   1790 
   1791         EXPECT_CRDOWNLOAD
   1792       },
   1793       FILE_PATH_LITERAL("foo.txt.crdownload"),
   1794       FILE_PATH_LITERAL("some_path/bar.txt.crdownload")
   1795     },
   1796 
   1797     {
   1798       {
   1799         // 2: Automatic Dangerous
   1800         AUTOMATIC,
   1801         content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1802         "http://example.com/foo.crx", "",
   1803         FILE_PATH_LITERAL(""),
   1804 
   1805         FILE_PATH_LITERAL(""),
   1806         FILE_PATH_LITERAL("foo.crx"),
   1807         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1808 
   1809         EXPECT_UNCONFIRMED
   1810       },
   1811       FILE_PATH_LITERAL("Unconfirmed abcd.crdownload"),
   1812       FILE_PATH_LITERAL("Unconfirmed abcd.crdownload")
   1813     },
   1814 
   1815     {
   1816       {
   1817         // 3: Automatic Dangerous
   1818         AUTOMATIC,
   1819         content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
   1820         "http://example.com/foo.crx", "",
   1821         FILE_PATH_LITERAL(""),
   1822 
   1823         FILE_PATH_LITERAL(""),
   1824         FILE_PATH_LITERAL("foo.crx"),
   1825         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1826 
   1827         EXPECT_UNCONFIRMED
   1828       },
   1829       FILE_PATH_LITERAL("other_path/Unconfirmed abcd.crdownload"),
   1830       // Rely on the EXPECT_UNCONFIRMED check in the general test settings. A
   1831       // new intermediate path of the form "Unconfirmed <number>.crdownload"
   1832       // should be generated for this case since the initial intermediate path
   1833       // is in the wrong directory.
   1834       FILE_PATH_LITERAL("")
   1835     },
   1836 
   1837     {
   1838       {
   1839         // 3: Forced Safe: Initial path is ignored due to the forced path.
   1840         FORCED,
   1841         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1842         "http://example.com/foo.txt", "",
   1843         FILE_PATH_LITERAL("forced-foo.txt"),
   1844 
   1845         FILE_PATH_LITERAL(""),
   1846         FILE_PATH_LITERAL("forced-foo.txt"),
   1847         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1848 
   1849         EXPECT_LOCAL_PATH
   1850       },
   1851       FILE_PATH_LITERAL("forced-foo.txt"),
   1852       FILE_PATH_LITERAL("forced-foo.txt")
   1853     },
   1854   };
   1855 
   1856   // The test assumes that .crx files have a danger level of
   1857   // ALLOW_ON_USER_GESTURE.
   1858   ASSERT_EQ(download_util::ALLOW_ON_USER_GESTURE,
   1859             download_util::GetFileDangerLevel(
   1860                 base::FilePath(FILE_PATH_LITERAL("foo.crx"))));
   1861 
   1862   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kIntermediateNameTestCases); ++i) {
   1863     SCOPED_TRACE(testing::Message() << "Running test case " << i);
   1864     const IntermediateNameTestCase& test_case = kIntermediateNameTestCases[i];
   1865     scoped_ptr<content::MockDownloadItem> item(
   1866         CreateActiveDownloadItem(i, test_case.general));
   1867 
   1868     ON_CALL(*item.get(), GetLastReason())
   1869         .WillByDefault(Return(
   1870             content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED));
   1871     ON_CALL(*item.get(), GetFullPath())
   1872         .WillByDefault(ReturnRefOfCopy(
   1873             GetPathInDownloadDir(test_case.initial_intermediate_path)));
   1874     ON_CALL(*item.get(), GetDangerType())
   1875         .WillByDefault(Return(test_case.general.expected_danger_type));
   1876 
   1877     scoped_ptr<DownloadTargetInfo> target_info =
   1878         RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
   1879                                     item.get());
   1880     VerifyDownloadTarget(test_case.general, target_info.get());
   1881     base::FilePath expected_intermediate_path =
   1882         GetPathInDownloadDir(test_case.expected_intermediate_path);
   1883     if (!expected_intermediate_path.empty())
   1884       EXPECT_EQ(expected_intermediate_path, target_info->intermediate_path);
   1885   }
   1886 }
   1887 
   1888 // Test MIME type determination based on the target filename.
   1889 TEST_F(DownloadTargetDeterminerTest,
   1890        TargetDeterminer_MIMETypeDetermination) {
   1891   // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital
   1892   // path.
   1893   const base::FilePath::CharType kInitialPath[] =
   1894       FILE_PATH_LITERAL("some_path/bar.txt");
   1895 
   1896   struct MIMETypeTestCase {
   1897     // General test case settings.
   1898     DownloadTestCase general;
   1899 
   1900     // Expected MIME type for test case.
   1901     const char* expected_mime_type;
   1902   } kMIMETypeTestCases[] = {
   1903     {
   1904       {
   1905         // 0:
   1906         AUTOMATIC,
   1907         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1908         "http://example.com/foo.png", "image/png",
   1909         FILE_PATH_LITERAL(""),
   1910 
   1911         FILE_PATH_LITERAL(""),
   1912         FILE_PATH_LITERAL("foo.png"),
   1913         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1914 
   1915         EXPECT_CRDOWNLOAD
   1916       },
   1917       "image/png"
   1918     },
   1919     {
   1920       {
   1921         // 1: Empty MIME type in response.
   1922         AUTOMATIC,
   1923         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1924         "http://example.com/foo.png", "",
   1925         FILE_PATH_LITERAL(""),
   1926 
   1927         FILE_PATH_LITERAL(""),
   1928         FILE_PATH_LITERAL("foo.png"),
   1929         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1930 
   1931         EXPECT_CRDOWNLOAD
   1932       },
   1933       "image/png"
   1934     },
   1935     {
   1936       {
   1937         // 2: Forced path.
   1938         FORCED,
   1939         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1940         "http://example.com/foo.abc", "",
   1941         FILE_PATH_LITERAL("foo.png"),
   1942 
   1943         FILE_PATH_LITERAL(""),
   1944         FILE_PATH_LITERAL("foo.png"),
   1945         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1946 
   1947         EXPECT_CRDOWNLOAD
   1948       },
   1949       "image/png"
   1950     },
   1951     {
   1952       {
   1953         // 3: Unknown file type.
   1954         AUTOMATIC,
   1955         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1956         "http://example.com/foo.notarealext", "",
   1957         FILE_PATH_LITERAL(""),
   1958 
   1959         FILE_PATH_LITERAL(""),
   1960         FILE_PATH_LITERAL("foo.notarealext"),
   1961         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1962 
   1963         EXPECT_CRDOWNLOAD
   1964       },
   1965       ""
   1966     },
   1967     {
   1968       {
   1969         // 4: Unknown file type.
   1970         AUTOMATIC,
   1971         content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   1972         "http://example.com/foo.notarealext", "image/png",
   1973         FILE_PATH_LITERAL(""),
   1974 
   1975         FILE_PATH_LITERAL(""),
   1976         FILE_PATH_LITERAL("foo.notarealext"),
   1977         DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   1978 
   1979         EXPECT_CRDOWNLOAD
   1980       },
   1981       ""
   1982     },
   1983   };
   1984 
   1985   ON_CALL(*delegate(), GetFileMimeType(
   1986       GetPathInDownloadDir(FILE_PATH_LITERAL("foo.png")), _))
   1987       .WillByDefault(WithArg<1>(
   1988           ScheduleCallback("image/png")));
   1989 
   1990   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kMIMETypeTestCases); ++i) {
   1991     SCOPED_TRACE(testing::Message() << "Running test case " << i);
   1992     const MIMETypeTestCase& test_case = kMIMETypeTestCases[i];
   1993     scoped_ptr<content::MockDownloadItem> item(
   1994         CreateActiveDownloadItem(i, test_case.general));
   1995     scoped_ptr<DownloadTargetInfo> target_info =
   1996         RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
   1997                                     item.get());
   1998     EXPECT_EQ(test_case.expected_mime_type, target_info->mime_type);
   1999   }
   2000 }
   2001 
   2002 #if defined(ENABLE_PLUGINS)
   2003 
   2004 void DummyGetPluginsCallback(
   2005     const base::Closure& closure,
   2006     const std::vector<content::WebPluginInfo>& plugins) {
   2007   closure.Run();
   2008 }
   2009 
   2010 void ForceRefreshOfPlugins() {
   2011 #if !defined(OS_WIN)
   2012   // Prevent creation of a utility process for loading plugins. Doing so breaks
   2013   // unit_tests since /proc/self/exe can't be run as a utility process.
   2014   content::RenderProcessHost::SetRunRendererInProcess(true);
   2015 #endif
   2016   base::RunLoop run_loop;
   2017   content::PluginService::GetInstance()->GetPlugins(
   2018       base::Bind(&DummyGetPluginsCallback, run_loop.QuitClosure()));
   2019   run_loop.Run();
   2020 #if !defined(OS_WIN)
   2021   content::RenderProcessHost::SetRunRendererInProcess(false);
   2022 #endif
   2023 }
   2024 
   2025 void PluginEnabledCallback(const base::Closure& closure,
   2026                            bool result) {
   2027   EXPECT_TRUE(result);
   2028   closure.Run();
   2029 }
   2030 
   2031 void EnablePlugin(bool enable, PluginPrefs* prefs, const base::FilePath& path) {
   2032   base::RunLoop run_loop;
   2033   prefs->EnablePlugin(enable, path,
   2034                       base::Bind(&PluginEnabledCallback,
   2035                                  run_loop.QuitClosure()));
   2036   run_loop.Run();
   2037 }
   2038 
   2039 class ScopedRegisterInternalPlugin {
   2040  public:
   2041   ScopedRegisterInternalPlugin(content::PluginService* plugin_service,
   2042                                content::WebPluginInfo::PluginType type,
   2043                                const base::FilePath& path,
   2044                                const char* mime_type,
   2045                                const char* extension)
   2046       : plugin_service_(plugin_service),
   2047         plugin_path_(path) {
   2048     content::WebPluginMimeType plugin_mime_type(mime_type,
   2049                                                 extension,
   2050                                                 "Test file");
   2051     content::WebPluginInfo plugin_info(base::string16(),
   2052                                        path,
   2053                                        base::string16(),
   2054                                        base::string16());
   2055     plugin_info.mime_types.push_back(plugin_mime_type);
   2056     plugin_info.type = type;
   2057 
   2058     plugin_service->RegisterInternalPlugin(plugin_info, true);
   2059     plugin_service->RefreshPlugins();
   2060     ForceRefreshOfPlugins();
   2061   }
   2062 
   2063   ~ScopedRegisterInternalPlugin() {
   2064     plugin_service_->UnregisterInternalPlugin(plugin_path_);
   2065     plugin_service_->RefreshPlugins();
   2066     ForceRefreshOfPlugins();
   2067   }
   2068 
   2069   const base::FilePath& path() { return plugin_path_; }
   2070 
   2071  private:
   2072   content::PluginService* plugin_service_;
   2073   base::FilePath plugin_path_;
   2074 };
   2075 
   2076 // We use a slightly different test fixture for tests that touch plugins. SetUp
   2077 // needs to disable plugin discovery and we need to use a
   2078 // ShadowingAtExitManager to discard the tainted PluginService. Unfortunately,
   2079 // PluginService carries global state.
   2080 class DownloadTargetDeterminerTestWithPlugin :
   2081   public DownloadTargetDeterminerTest {
   2082  public:
   2083   virtual void SetUp() OVERRIDE {
   2084     content::PluginService::GetInstance()->Init();
   2085     content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
   2086     DownloadTargetDeterminerTest::SetUp();
   2087   }
   2088 
   2089  protected:
   2090   // The ShadowingAtExitManager destroys the tainted PluginService instance.
   2091   base::ShadowingAtExitManager at_exit_manager_;
   2092 };
   2093 
   2094 // Check if secure handling of filetypes is determined correctly for PPAPI
   2095 // plugins.
   2096 TEST_F(DownloadTargetDeterminerTestWithPlugin,
   2097        TargetDeterminer_CheckForSecureHandling_PPAPI) {
   2098   // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital
   2099   // path.
   2100   const base::FilePath::CharType kInitialPath[] =
   2101       FILE_PATH_LITERAL("some_path/bar.txt");
   2102   const char kTestMIMEType[] = "application/x-example-should-not-exist";
   2103 
   2104   DownloadTestCase kSecureHandlingTestCase = {
   2105     AUTOMATIC,
   2106     content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   2107     "http://example.com/foo.fakeext", "",
   2108     FILE_PATH_LITERAL(""),
   2109 
   2110     FILE_PATH_LITERAL(""),
   2111     FILE_PATH_LITERAL("foo.fakeext"),
   2112     DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   2113 
   2114     EXPECT_CRDOWNLOAD
   2115   };
   2116 
   2117   content::PluginService* plugin_service =
   2118       content::PluginService::GetInstance();
   2119   // This creates a PluginPrefs for our TestingProfile.
   2120   scoped_refptr<PluginPrefs> plugin_prefs =
   2121       PluginPrefs::GetForTestingProfile(profile());
   2122 
   2123   // Verify our test assumptions.
   2124   {
   2125     ForceRefreshOfPlugins();
   2126     std::vector<content::WebPluginInfo> info;
   2127     ASSERT_FALSE(plugin_service->GetPluginInfoArray(
   2128         GURL(), kTestMIMEType, false, &info, NULL));
   2129     ASSERT_EQ(0u, info.size())
   2130         << "Name: " << info[0].name << ", Path: " << info[0].path.value();
   2131   }
   2132 
   2133   ON_CALL(*delegate(), GetFileMimeType(
   2134       GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _))
   2135       .WillByDefault(WithArg<1>(
   2136           ScheduleCallback(kTestMIMEType)));
   2137   scoped_ptr<content::MockDownloadItem> item(
   2138       CreateActiveDownloadItem(1, kSecureHandlingTestCase));
   2139   scoped_ptr<DownloadTargetInfo> target_info =
   2140       RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
   2141                                   item.get());
   2142   EXPECT_FALSE(target_info->is_filetype_handled_securely);
   2143 
   2144   // Register a PPAPI plugin. This should count as handling the filetype
   2145   // securely.
   2146   ScopedRegisterInternalPlugin ppapi_plugin(
   2147       plugin_service,
   2148       content::WebPluginInfo::PLUGIN_TYPE_PEPPER_OUT_OF_PROCESS,
   2149       test_download_dir().AppendASCII("ppapi"),
   2150       kTestMIMEType,
   2151       "fakeext");
   2152 
   2153   target_info = RunDownloadTargetDeterminer(
   2154       GetPathInDownloadDir(kInitialPath), item.get());
   2155   EXPECT_TRUE(target_info->is_filetype_handled_securely);
   2156 
   2157   // Try disabling the plugin. Handling should no longer be considered secure.
   2158   EnablePlugin(false, plugin_prefs, ppapi_plugin.path());
   2159   target_info = RunDownloadTargetDeterminer(
   2160       GetPathInDownloadDir(kInitialPath), item.get());
   2161   EXPECT_FALSE(target_info->is_filetype_handled_securely);
   2162 
   2163   // Now register an unsandboxed PPAPI plug-in. This plugin should not be
   2164   // considered secure.
   2165   ScopedRegisterInternalPlugin ppapi_unsandboxed_plugin(
   2166       plugin_service,
   2167       content::WebPluginInfo::PLUGIN_TYPE_PEPPER_UNSANDBOXED,
   2168       test_download_dir().AppendASCII("ppapi-nosandbox"),
   2169       kTestMIMEType,
   2170       "fakeext");
   2171 
   2172   target_info = RunDownloadTargetDeterminer(
   2173       GetPathInDownloadDir(kInitialPath), item.get());
   2174   EXPECT_FALSE(target_info->is_filetype_handled_securely);
   2175 }
   2176 
   2177 // Check if secure handling of filetypes is determined correctly for NPAPI
   2178 // plugins.
   2179 TEST_F(DownloadTargetDeterminerTestWithPlugin,
   2180        TargetDeterminer_CheckForSecureHandling_NPAPI) {
   2181   // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital
   2182   // path.
   2183   const base::FilePath::CharType kInitialPath[] =
   2184       FILE_PATH_LITERAL("some_path/bar.txt");
   2185   const char kTestMIMEType[] = "application/x-example-should-not-exist";
   2186 
   2187   DownloadTestCase kSecureHandlingTestCase = {
   2188     AUTOMATIC,
   2189     content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
   2190     "http://example.com/foo.fakeext", "",
   2191     FILE_PATH_LITERAL(""),
   2192 
   2193     FILE_PATH_LITERAL(""),
   2194     FILE_PATH_LITERAL("foo.fakeext"),
   2195     DownloadItem::TARGET_DISPOSITION_OVERWRITE,
   2196 
   2197     EXPECT_CRDOWNLOAD
   2198   };
   2199 
   2200   content::PluginService* plugin_service =
   2201       content::PluginService::GetInstance();
   2202 
   2203   // Can't run this test if NPAPI isn't supported.
   2204   if (!plugin_service->NPAPIPluginsSupported())
   2205     return;
   2206 
   2207   // This creates a PluginPrefs for our TestingProfile.
   2208   scoped_refptr<PluginPrefs> plugin_prefs =
   2209       PluginPrefs::GetForTestingProfile(profile());
   2210 
   2211   // Verify our test assumptions.
   2212   {
   2213     ForceRefreshOfPlugins();
   2214     std::vector<content::WebPluginInfo> info;
   2215     ASSERT_FALSE(plugin_service->GetPluginInfoArray(
   2216         GURL(), kTestMIMEType, false, &info, NULL));
   2217     ASSERT_EQ(0u, info.size())
   2218         << "Name: " << info[0].name << ", Path: " << info[0].path.value();
   2219   }
   2220 
   2221   ON_CALL(*delegate(), GetFileMimeType(
   2222       GetPathInDownloadDir(FILE_PATH_LITERAL("foo.fakeext")), _))
   2223       .WillByDefault(WithArg<1>(
   2224           ScheduleCallback(kTestMIMEType)));
   2225   scoped_ptr<content::MockDownloadItem> item(
   2226       CreateActiveDownloadItem(1, kSecureHandlingTestCase));
   2227   scoped_ptr<DownloadTargetInfo> target_info =
   2228       RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath),
   2229                                   item.get());
   2230   EXPECT_FALSE(target_info->is_filetype_handled_securely);
   2231 
   2232   // Register a NPAPI plugin. This should not count as handling the filetype
   2233   // securely.
   2234   ScopedRegisterInternalPlugin npapi_plugin(
   2235       plugin_service,
   2236       content::WebPluginInfo::PLUGIN_TYPE_NPAPI,
   2237       test_download_dir().AppendASCII("npapi"),
   2238       kTestMIMEType,
   2239       "fakeext");
   2240 
   2241   target_info = RunDownloadTargetDeterminer(
   2242       GetPathInDownloadDir(kInitialPath), item.get());
   2243   EXPECT_FALSE(target_info->is_filetype_handled_securely);
   2244 }
   2245 #endif // ENABLE_PLUGINS
   2246 
   2247 }  // namespace
   2248