Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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/file_util.h" | |
| 6 #include "base/files/file_path.h" | |
| 7 #include "base/files/scoped_temp_dir.h" | |
| 8 #include "base/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/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_util.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/extensions/extension.h" | |
| 24 #include "chrome/common/pref_names.h" | |
| 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | |
| 26 #include "chrome/test/base/testing_pref_service_syncable.h" | |
| 27 #include "chrome/test/base/testing_profile.h" | |
| 28 #include "content/public/browser/web_contents.h" | |
| 29 #include "content/public/browser/web_contents_delegate.h" | |
| 30 #include "content/public/test/mock_download_item.h" | |
| 31 #include "content/public/test/test_browser_thread.h" | |
| 32 #include "content/public/test/test_renderer_host.h" | |
| 33 #include "content/public/test/web_contents_tester.h" | |
| 34 #include "testing/gmock/include/gmock/gmock.h" | |
| 35 #include "testing/gtest/include/gtest/gtest.h" | |
| 36 | |
| 37 using ::testing::AnyNumber; | |
| 38 using ::testing::Invoke; | |
| 39 using ::testing::Ref; | |
| 40 using ::testing::Return; | |
| 41 using ::testing::ReturnRef; | |
| 42 using ::testing::ReturnRefOfCopy; | |
| 43 using ::testing::Truly; | |
| 44 using ::testing::WithArg; | |
| 45 using ::testing::_; | |
| 46 using content::DownloadItem; | |
| 47 | |
| 48 namespace { | |
| 49 | |
| 50 // No-op delegate. | |
| 51 class NullWebContentsDelegate : public content::WebContentsDelegate { | |
| 52 public: | |
| 53 NullWebContentsDelegate() {} | |
| 54 virtual ~NullWebContentsDelegate() {} | |
| 55 }; | |
| 56 | |
| 57 // Google Mock action that posts a task to the current message loop that invokes | |
| 58 // the first argument of the mocked method as a callback. Said argument must be | |
| 59 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is | |
| 60 // bound as that parameter. | |
| 61 // Example: | |
| 62 // class FooClass { | |
| 63 // public: | |
| 64 // virtual void Foo(base::Callback<void(bool)> callback); | |
| 65 // }; | |
| 66 // ... | |
| 67 // EXPECT_CALL(mock_fooclass_instance, Foo(callback)) | |
| 68 // .WillOnce(ScheduleCallback(false)); | |
| 69 ACTION_P(ScheduleCallback, result0) { | |
| 70 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result0)); | |
| 71 } | |
| 72 | |
| 73 // Similar to ScheduleCallback, but binds 2 arguments. | |
| 74 ACTION_P2(ScheduleCallback2, result0, result1) { | |
| 75 base::MessageLoop::current()->PostTask( | |
| 76 FROM_HERE, base::Bind(arg0, result0, result1)); | |
| 77 } | |
| 78 | |
| 79 // Used with DownloadTestCase. Indicates the type of test case. The expectations | |
| 80 // for the test is set based on the type. | |
| 81 enum TestCaseType { | |
| 82 SAVE_AS, | |
| 83 AUTOMATIC, | |
| 84 FORCED // Requires that forced_file_path be non-empty. | |
| 85 }; | |
| 86 | |
| 87 // Used with DownloadTestCase. Type of intermediate filename to expect. | |
| 88 enum TestCaseExpectIntermediate { | |
| 89 EXPECT_CRDOWNLOAD, // Expect path/to/target.crdownload. | |
| 90 EXPECT_UNCONFIRMED, // Expect path/to/Unconfirmed xxx.crdownload. | |
| 91 EXPECT_LOCAL_PATH, // Expect target path. | |
| 92 }; | |
| 93 | |
| 94 // Typical download test case. Used with | |
| 95 // DownloadTargetDeterminerTest::RunTestCase(). | |
| 96 struct DownloadTestCase { | |
| 97 // Type of test. | |
| 98 TestCaseType test_type; | |
| 99 | |
| 100 // Expected danger type. Verified at the end of target determination. | |
| 101 content::DownloadDangerType expected_danger_type; | |
| 102 | |
| 103 // Value of DownloadItem::GetURL() | |
| 104 const char* url; | |
| 105 | |
| 106 // Value of DownloadItem::GetMimeType() | |
| 107 const char* mime_type; | |
| 108 | |
| 109 // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath(). | |
| 110 const base::FilePath::CharType* forced_file_path; | |
| 111 | |
| 112 // Expected virtual path. Specified relative to the virtual download path. If | |
| 113 // empty, assumed to be the same as |expected_local_path|. | |
| 114 const base::FilePath::CharType* expected_virtual_path; | |
|
Nico
2014/01/15 18:01:07
This appears unused. I'll send out a CL to remove
| |
| 115 | |
| 116 // Expected local path. Specified relative to the test download path. | |
| 117 const base::FilePath::CharType* expected_local_path; | |
| 118 | |
| 119 // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the | |
| 120 // test run will expect ChromeDownloadManagerDelegate to prompt the user for a | |
| 121 // download location. | |
| 122 DownloadItem::TargetDisposition expected_disposition; | |
| 123 | |
| 124 // Type of intermediate path to expect. | |
| 125 TestCaseExpectIntermediate expected_intermediate; | |
| 126 }; | |
| 127 | |
| 128 class MockDownloadTargetDeterminerDelegate : | |
| 129 public DownloadTargetDeterminerDelegate { | |
| 130 public: | |
| 131 MOCK_METHOD3(CheckDownloadUrl, | |
| 132 void(content::DownloadItem*, const base::FilePath&, | |
| 133 const CheckDownloadUrlCallback&)); | |
| 134 MOCK_METHOD3(NotifyExtensions, | |
| 135 void(content::DownloadItem*, const base::FilePath&, | |
| 136 const NotifyExtensionsCallback&)); | |
| 137 MOCK_METHOD3(PromptUserForDownloadPath, | |
| 138 void(content::DownloadItem*, const base::FilePath&, | |
| 139 const FileSelectedCallback&)); | |
| 140 MOCK_METHOD3(DetermineLocalPath, | |
| 141 void(DownloadItem*, const base::FilePath&, | |
| 142 const LocalPathCallback&)); | |
| 143 MOCK_METHOD4(ReserveVirtualPath, | |
| 144 void(DownloadItem*, const base::FilePath&, | |
| 145 DownloadPathReservationTracker::FilenameConflictAction, | |
| 146 const ReservedPathCallback&)); | |
| 147 | |
| 148 void SetupDefaults() { | |
| 149 ON_CALL(*this, CheckDownloadUrl(_, _, _)) | |
| 150 .WillByDefault(WithArg<2>( | |
| 151 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS))); | |
| 152 ON_CALL(*this, NotifyExtensions(_, _, _)) | |
| 153 .WillByDefault(WithArg<2>( | |
| 154 ScheduleCallback2(base::FilePath(), | |
| 155 DownloadPathReservationTracker::UNIQUIFY))); | |
| 156 ON_CALL(*this, ReserveVirtualPath(_, _, _, _)) | |
| 157 .WillByDefault(Invoke( | |
| 158 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath)); | |
| 159 ON_CALL(*this, PromptUserForDownloadPath(_, _, _)) | |
| 160 .WillByDefault(Invoke( | |
| 161 &MockDownloadTargetDeterminerDelegate::NullPromptUser)); | |
| 162 ON_CALL(*this, DetermineLocalPath(_, _, _)) | |
| 163 .WillByDefault(Invoke( | |
| 164 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); | |
| 165 } | |
| 166 private: | |
| 167 static void NullReserveVirtualPath( | |
| 168 DownloadItem* download, | |
| 169 const base::FilePath& virtual_path, | |
| 170 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | |
| 171 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback); | |
| 172 static void NullPromptUser( | |
| 173 DownloadItem* download, const base::FilePath& suggested_path, | |
| 174 const FileSelectedCallback& callback); | |
| 175 static void NullDetermineLocalPath( | |
| 176 DownloadItem* download, const base::FilePath& virtual_path, | |
| 177 const LocalPathCallback& callback); | |
| 178 }; | |
| 179 | |
| 180 class DownloadTargetDeterminerTest : public ChromeRenderViewHostTestHarness { | |
| 181 public: | |
| 182 DownloadTargetDeterminerTest(); | |
| 183 | |
| 184 // ::testing::Test | |
| 185 virtual void SetUp() OVERRIDE; | |
| 186 virtual void TearDown() OVERRIDE; | |
| 187 | |
| 188 // Creates MockDownloadItem and sets up default expectations. | |
| 189 content::MockDownloadItem* CreateActiveDownloadItem( | |
| 190 int32 id, | |
| 191 const DownloadTestCase& test_case); | |
| 192 | |
| 193 // Sets the AutoOpenBasedOnExtension user preference for |path|. | |
| 194 void EnableAutoOpenBasedOnExtension(const base::FilePath& path); | |
| 195 | |
| 196 // Set the kDownloadDefaultDirectory user preference to |path|. | |
| 197 void SetDefaultDownloadPath(const base::FilePath& path); | |
| 198 | |
| 199 // Set the kDownloadDefaultDirectory managed preference to |path|. | |
| 200 void SetManagedDownloadPath(const base::FilePath& path); | |
| 201 | |
| 202 // Set the kPromptForDownload user preference to |prompt|. | |
| 203 void SetPromptForDownload(bool prompt); | |
| 204 | |
| 205 // Given the relative path |path|, returns the full path under the temporary | |
| 206 // downloads directory. | |
| 207 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); | |
| 208 | |
| 209 // Run |test_case| using |item|. | |
| 210 void RunTestCase(const DownloadTestCase& test_case, | |
| 211 content::MockDownloadItem* item); | |
| 212 | |
| 213 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem | |
| 214 // will be created for each test case and destroyed when the test case is | |
| 215 // complete. | |
| 216 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], | |
| 217 size_t test_case_count); | |
| 218 | |
| 219 const base::FilePath& test_download_dir() const { | |
| 220 return test_download_dir_.path(); | |
| 221 } | |
| 222 | |
| 223 const base::FilePath& test_virtual_dir() const { | |
| 224 return test_virtual_dir_; | |
| 225 } | |
| 226 | |
| 227 MockDownloadTargetDeterminerDelegate* delegate() { | |
| 228 return &delegate_; | |
| 229 } | |
| 230 | |
| 231 DownloadPrefs* download_prefs() { | |
| 232 return download_prefs_.get(); | |
| 233 } | |
| 234 | |
| 235 void set_last_selected_directory(const base::FilePath& path) { | |
| 236 last_selected_directory_ = path; | |
| 237 } | |
| 238 | |
| 239 private: | |
| 240 // Verifies that |target_path|, |disposition|, |expected_danger_type| and | |
| 241 // |intermediate_path| matches the expectations of |test_case|. Posts | |
| 242 // |closure| to the current message loop when done. | |
| 243 void DownloadTargetVerifier(const base::Closure& closure, | |
| 244 const DownloadTestCase& test_case, | |
| 245 const base::FilePath& local_path, | |
| 246 DownloadItem::TargetDisposition disposition, | |
| 247 content::DownloadDangerType danger_type, | |
| 248 const base::FilePath& intermediate_path); | |
| 249 | |
| 250 scoped_ptr<DownloadPrefs> download_prefs_; | |
| 251 ::testing::NiceMock<MockDownloadTargetDeterminerDelegate> delegate_; | |
| 252 NullWebContentsDelegate web_contents_delegate_; | |
| 253 base::ScopedTempDir test_download_dir_; | |
| 254 base::FilePath test_virtual_dir_; | |
| 255 base::FilePath last_selected_directory_; | |
| 256 content::TestBrowserThread ui_thread_; | |
| 257 content::TestBrowserThread file_thread_; | |
| 258 }; | |
| 259 | |
| 260 DownloadTargetDeterminerTest::DownloadTargetDeterminerTest() | |
| 261 : ChromeRenderViewHostTestHarness(), | |
| 262 ui_thread_(content::BrowserThread::UI, &message_loop_), | |
| 263 file_thread_(content::BrowserThread::FILE, &message_loop_) { | |
| 264 } | |
| 265 | |
| 266 void DownloadTargetDeterminerTest::SetUp() { | |
| 267 ChromeRenderViewHostTestHarness::SetUp(); | |
| 268 CHECK(profile()); | |
| 269 download_prefs_.reset(new DownloadPrefs(profile())); | |
| 270 web_contents()->SetDelegate(&web_contents_delegate_); | |
| 271 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); | |
| 272 test_virtual_dir_ = test_download_dir().Append(FILE_PATH_LITERAL("virtual")); | |
| 273 SetDefaultDownloadPath(test_download_dir()); | |
| 274 delegate_.SetupDefaults(); | |
| 275 } | |
| 276 | |
| 277 void DownloadTargetDeterminerTest::TearDown() { | |
| 278 download_prefs_.reset(); | |
| 279 message_loop_.RunUntilIdle(); | |
| 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, GetMimeType()) | |
| 314 .WillByDefault(Return(test_case.mime_type)); | |
| 315 ON_CALL(*item, GetReferrerUrl()) | |
| 316 .WillByDefault(ReturnRefOfCopy(download_url)); | |
| 317 ON_CALL(*item, GetState()) | |
| 318 .WillByDefault(Return(DownloadItem::IN_PROGRESS)); | |
| 319 ON_CALL(*item, GetTargetDisposition()) | |
| 320 .WillByDefault(Return(initial_disposition)); | |
| 321 ON_CALL(*item, GetTargetFilePath()) | |
| 322 .WillByDefault(ReturnRefOfCopy(base::FilePath())); | |
| 323 ON_CALL(*item, GetTransitionType()) | |
| 324 .WillByDefault(Return(content::PAGE_TRANSITION_LINK)); | |
| 325 ON_CALL(*item, GetURL()) | |
| 326 .WillByDefault(ReturnRefOfCopy(download_url)); | |
| 327 ON_CALL(*item, GetUrlChain()) | |
| 328 .WillByDefault(ReturnRefOfCopy(url_chain)); | |
| 329 ON_CALL(*item, GetWebContents()) | |
| 330 .WillByDefault(Return(web_contents())); | |
| 331 ON_CALL(*item, HasUserGesture()) | |
| 332 .WillByDefault(Return(true)); | |
| 333 ON_CALL(*item, IsDangerous()) | |
| 334 .WillByDefault(Return(false)); | |
| 335 ON_CALL(*item, IsInProgress()) | |
| 336 .WillByDefault(Return(true)); | |
| 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::SetDefaultDownloadPath( | |
| 348 const base::FilePath& path) { | |
| 349 profile()->GetTestingPrefService()-> | |
| 350 SetFilePath(prefs::kDownloadDefaultDirectory, path); | |
| 351 } | |
| 352 | |
| 353 void DownloadTargetDeterminerTest::SetManagedDownloadPath( | |
| 354 const base::FilePath& path) { | |
| 355 profile()->GetTestingPrefService()-> | |
| 356 SetManagedPref(prefs::kDownloadDefaultDirectory, | |
| 357 base::CreateFilePathValue(path)); | |
| 358 } | |
| 359 | |
| 360 void DownloadTargetDeterminerTest::SetPromptForDownload(bool prompt) { | |
| 361 profile()->GetTestingPrefService()-> | |
| 362 SetBoolean(prefs::kPromptForDownload, prompt); | |
| 363 } | |
| 364 | |
| 365 base::FilePath DownloadTargetDeterminerTest::GetPathInDownloadDir( | |
| 366 const base::FilePath::StringType& relative_path) { | |
| 367 if (relative_path.empty()) | |
| 368 return base::FilePath(); | |
| 369 base::FilePath full_path(test_download_dir().Append(relative_path)); | |
| 370 return full_path.NormalizePathSeparators(); | |
| 371 } | |
| 372 | |
| 373 void DownloadTargetDeterminerTest::RunTestCase( | |
| 374 const DownloadTestCase& test_case, | |
| 375 content::MockDownloadItem* item) { | |
| 376 // Kick off the test. | |
| 377 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); | |
| 378 base::RunLoop run_loop; | |
| 379 DownloadTargetDeterminer::Start( | |
| 380 item, download_prefs_.get(), last_selected_directory_, delegate(), | |
| 381 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, | |
| 382 factory.GetWeakPtr(), run_loop.QuitClosure(), test_case)); | |
| 383 run_loop.Run(); | |
| 384 ::testing::Mock::VerifyAndClearExpectations(delegate()); | |
| 385 } | |
| 386 | |
| 387 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( | |
| 388 const DownloadTestCase test_cases[], | |
| 389 size_t test_case_count) { | |
| 390 for (size_t i = 0; i < test_case_count; ++i) { | |
| 391 scoped_ptr<content::MockDownloadItem> item( | |
| 392 CreateActiveDownloadItem(i, test_cases[i])); | |
| 393 SCOPED_TRACE(testing::Message() << "Running test case " << i); | |
| 394 RunTestCase(test_cases[i], item.get()); | |
| 395 } | |
| 396 } | |
| 397 | |
| 398 void DownloadTargetDeterminerTest::DownloadTargetVerifier( | |
| 399 const base::Closure& closure, | |
| 400 const DownloadTestCase& test_case, | |
| 401 const base::FilePath& local_path, | |
| 402 DownloadItem::TargetDisposition disposition, | |
| 403 content::DownloadDangerType danger_type, | |
| 404 const base::FilePath& intermediate_path) { | |
| 405 base::FilePath expected_local_path( | |
| 406 GetPathInDownloadDir(test_case.expected_local_path)); | |
| 407 EXPECT_EQ(expected_local_path.value(), local_path.value()); | |
| 408 EXPECT_EQ(test_case.expected_disposition, disposition); | |
| 409 EXPECT_EQ(test_case.expected_danger_type, danger_type); | |
| 410 | |
| 411 switch (test_case.expected_intermediate) { | |
| 412 case EXPECT_CRDOWNLOAD: | |
| 413 EXPECT_EQ(download_util::GetCrDownloadPath(local_path).value(), | |
| 414 intermediate_path.value()); | |
| 415 break; | |
| 416 | |
| 417 case EXPECT_UNCONFIRMED: | |
| 418 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. | |
| 419 // Of this, we only check that the path is: | |
| 420 // 1. Not "/path/target.crdownload", | |
| 421 // 2. Points to the same directory as the target. | |
| 422 // 3. Has extension ".crdownload". | |
| 423 // 4. Basename starts with "Unconfirmed ". | |
| 424 EXPECT_NE(download_util::GetCrDownloadPath(expected_local_path).value(), | |
| 425 intermediate_path.value()); | |
| 426 EXPECT_EQ(expected_local_path.DirName().value(), | |
| 427 intermediate_path.DirName().value()); | |
| 428 EXPECT_TRUE(intermediate_path.MatchesExtension( | |
| 429 FILE_PATH_LITERAL(".crdownload"))); | |
| 430 EXPECT_EQ(0u, intermediate_path.BaseName().value().find( | |
| 431 FILE_PATH_LITERAL("Unconfirmed "))); | |
| 432 break; | |
| 433 | |
| 434 case EXPECT_LOCAL_PATH: | |
| 435 EXPECT_EQ(expected_local_path.value(), intermediate_path.value()); | |
| 436 break; | |
| 437 } | |
| 438 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | |
| 439 } | |
| 440 | |
| 441 // static | |
| 442 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath( | |
| 443 DownloadItem* download, | |
| 444 const base::FilePath& virtual_path, | |
| 445 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | |
| 446 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { | |
| 447 callback.Run(virtual_path, true); | |
| 448 } | |
| 449 | |
| 450 // static | |
| 451 void MockDownloadTargetDeterminerDelegate::NullPromptUser( | |
| 452 DownloadItem* download, const base::FilePath& suggested_path, | |
| 453 const FileSelectedCallback& callback) { | |
| 454 callback.Run(suggested_path); | |
| 455 } | |
| 456 | |
| 457 // static | |
| 458 void MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath( | |
| 459 DownloadItem* download, const base::FilePath& virtual_path, | |
| 460 const LocalPathCallback& callback) { | |
| 461 callback.Run(virtual_path); | |
| 462 } | |
| 463 | |
| 464 // NotifyExtensions implementation that overrides the path so that the target | |
| 465 // file is in a subdirectory called 'overridden'. If the extension is '.remove', | |
| 466 // the extension is removed. | |
| 467 void NotifyExtensionsOverridePath( | |
| 468 content::DownloadItem* download, | |
| 469 const base::FilePath& path, | |
| 470 const DownloadTargetDeterminerDelegate::NotifyExtensionsCallback& | |
| 471 callback) { | |
| 472 base::FilePath new_path = | |
| 473 base::FilePath() | |
| 474 .AppendASCII("overridden") | |
| 475 .Append(path.BaseName()); | |
| 476 if (new_path.MatchesExtension(FILE_PATH_LITERAL(".remove"))) | |
| 477 new_path = new_path.RemoveExtension(); | |
| 478 callback.Run(new_path, DownloadPathReservationTracker::UNIQUIFY); | |
| 479 } | |
| 480 | |
| 481 void CheckDownloadUrlCheckExes( | |
| 482 content::DownloadItem* download, | |
| 483 const base::FilePath& path, | |
| 484 const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback& | |
| 485 callback) { | |
| 486 if (path.MatchesExtension(FILE_PATH_LITERAL(".exe"))) | |
| 487 callback.Run(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT); | |
| 488 else | |
| 489 callback.Run(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS); | |
| 490 } | |
| 491 | |
| 492 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_Basic) { | |
| 493 const DownloadTestCase kBasicTestCases[] = { | |
| 494 { | |
| 495 // 0: Automatic Safe | |
| 496 AUTOMATIC, | |
| 497 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 498 "http://example.com/foo.txt", "text/plain", | |
| 499 FILE_PATH_LITERAL(""), | |
| 500 | |
| 501 FILE_PATH_LITERAL(""), | |
| 502 FILE_PATH_LITERAL("foo.txt"), | |
| 503 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 504 | |
| 505 EXPECT_CRDOWNLOAD | |
| 506 }, | |
| 507 | |
| 508 { | |
| 509 // 1: Save_As Safe | |
| 510 SAVE_AS, | |
| 511 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 512 "http://example.com/foo.txt", "text/plain", | |
| 513 FILE_PATH_LITERAL(""), | |
| 514 | |
| 515 FILE_PATH_LITERAL(""), | |
| 516 FILE_PATH_LITERAL("foo.txt"), | |
| 517 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 518 | |
| 519 EXPECT_CRDOWNLOAD | |
| 520 }, | |
| 521 | |
| 522 { | |
| 523 // 2: Automatic Dangerous | |
| 524 AUTOMATIC, | |
| 525 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 526 "http://example.com/foo.html", "", | |
| 527 FILE_PATH_LITERAL(""), | |
| 528 | |
| 529 FILE_PATH_LITERAL(""), | |
| 530 FILE_PATH_LITERAL("foo.html"), | |
| 531 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 532 | |
| 533 EXPECT_UNCONFIRMED | |
| 534 }, | |
| 535 | |
| 536 { | |
| 537 // 3: Forced Safe | |
| 538 FORCED, | |
| 539 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 540 "http://example.com/foo.txt", "", | |
| 541 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 542 | |
| 543 FILE_PATH_LITERAL(""), | |
| 544 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 545 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 546 | |
| 547 EXPECT_LOCAL_PATH | |
| 548 }, | |
| 549 }; | |
| 550 | |
| 551 // The test assumes that .html files have a danger level of | |
| 552 // AllowOnUserGesture. | |
| 553 ASSERT_EQ(download_util::AllowOnUserGesture, | |
| 554 download_util::GetFileDangerLevel( | |
| 555 base::FilePath(FILE_PATH_LITERAL("foo.html")))); | |
| 556 RunTestCasesWithActiveItem(kBasicTestCases, arraysize(kBasicTestCases)); | |
| 557 } | |
| 558 | |
| 559 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_CancelSaveAs) { | |
| 560 const DownloadTestCase kCancelSaveAsTestCases[] = { | |
| 561 { | |
| 562 // 0: Save_As Safe, Cancelled. | |
| 563 SAVE_AS, | |
| 564 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 565 "http://example.com/foo.txt", "text/plain", | |
| 566 FILE_PATH_LITERAL(""), | |
| 567 | |
| 568 FILE_PATH_LITERAL(""), | |
| 569 FILE_PATH_LITERAL(""), | |
| 570 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 571 | |
| 572 EXPECT_LOCAL_PATH | |
| 573 } | |
| 574 }; | |
| 575 ON_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) | |
| 576 .WillByDefault(WithArg<2>(ScheduleCallback(base::FilePath()))); | |
| 577 RunTestCasesWithActiveItem(kCancelSaveAsTestCases, | |
| 578 arraysize(kCancelSaveAsTestCases)); | |
| 579 } | |
| 580 | |
| 581 // The SafeBrowsing check is performed early. Make sure that a download item | |
| 582 // that has been marked as DANGEROUS_URL behaves correctly. | |
| 583 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DangerousUrl) { | |
| 584 const DownloadTestCase kSafeBrowsingTestCases[] = { | |
| 585 { | |
| 586 // 0: Automatic Dangerous URL | |
| 587 AUTOMATIC, | |
| 588 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 589 "http://phishing.example.com/foo.txt", "", | |
| 590 FILE_PATH_LITERAL(""), | |
| 591 | |
| 592 FILE_PATH_LITERAL(""), | |
| 593 FILE_PATH_LITERAL("foo.txt"), | |
| 594 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 595 | |
| 596 EXPECT_UNCONFIRMED | |
| 597 }, | |
| 598 | |
| 599 { | |
| 600 // 1: Save As Dangerous URL | |
| 601 SAVE_AS, | |
| 602 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 603 "http://phishing.example.com/foo.txt", "", | |
| 604 FILE_PATH_LITERAL(""), | |
| 605 | |
| 606 FILE_PATH_LITERAL(""), | |
| 607 FILE_PATH_LITERAL("foo.txt"), | |
| 608 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 609 | |
| 610 EXPECT_UNCONFIRMED | |
| 611 }, | |
| 612 | |
| 613 { | |
| 614 // 2: Forced Dangerous URL | |
| 615 FORCED, | |
| 616 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 617 "http://phishing.example.com/foo.txt", "", | |
| 618 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 619 | |
| 620 FILE_PATH_LITERAL(""), | |
| 621 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 622 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 623 | |
| 624 EXPECT_UNCONFIRMED | |
| 625 }, | |
| 626 | |
| 627 { | |
| 628 // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes | |
| 629 // precendence. | |
| 630 AUTOMATIC, | |
| 631 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 632 "http://phishing.example.com/foo.html", "", | |
| 633 FILE_PATH_LITERAL(""), | |
| 634 | |
| 635 FILE_PATH_LITERAL(""), | |
| 636 FILE_PATH_LITERAL("foo.html"), | |
| 637 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 638 | |
| 639 EXPECT_UNCONFIRMED | |
| 640 }, | |
| 641 | |
| 642 { | |
| 643 // 4: Save As Dangerous URL + Dangerous file | |
| 644 SAVE_AS, | |
| 645 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 646 "http://phishing.example.com/foo.html", "", | |
| 647 FILE_PATH_LITERAL(""), | |
| 648 | |
| 649 FILE_PATH_LITERAL(""), | |
| 650 FILE_PATH_LITERAL("foo.html"), | |
| 651 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 652 | |
| 653 EXPECT_UNCONFIRMED | |
| 654 }, | |
| 655 | |
| 656 { | |
| 657 // 5: Forced Dangerous URL + Dangerous file | |
| 658 FORCED, | |
| 659 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, | |
| 660 "http://phishing.example.com/foo.html", "", | |
| 661 FILE_PATH_LITERAL("forced-foo.html"), | |
| 662 | |
| 663 FILE_PATH_LITERAL(""), | |
| 664 FILE_PATH_LITERAL("forced-foo.html"), | |
| 665 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 666 | |
| 667 EXPECT_UNCONFIRMED | |
| 668 }, | |
| 669 }; | |
| 670 | |
| 671 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _)) | |
| 672 .WillByDefault(WithArg<2>(ScheduleCallback( | |
| 673 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL))); | |
| 674 RunTestCasesWithActiveItem(kSafeBrowsingTestCases, | |
| 675 arraysize(kSafeBrowsingTestCases)); | |
| 676 } | |
| 677 | |
| 678 // The SafeBrowsing check is performed early. Make sure that a download item | |
| 679 // that has been marked as MAYBE_DANGEROUS_CONTENT behaves correctly. | |
| 680 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_MaybeDangerousContent) { | |
| 681 const DownloadTestCase kSafeBrowsingTestCases[] = { | |
| 682 { | |
| 683 // 0: Automatic Maybe dangerous content | |
| 684 AUTOMATIC, | |
| 685 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 686 "http://phishing.example.com/foo.exe", "", | |
| 687 FILE_PATH_LITERAL(""), | |
| 688 | |
| 689 FILE_PATH_LITERAL(""), | |
| 690 FILE_PATH_LITERAL("foo.exe"), | |
| 691 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 692 | |
| 693 EXPECT_UNCONFIRMED | |
| 694 }, | |
| 695 | |
| 696 { | |
| 697 // 1: Save As Maybe dangerous content | |
| 698 SAVE_AS, | |
| 699 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 700 "http://phishing.example.com/foo.exe", "", | |
| 701 FILE_PATH_LITERAL(""), | |
| 702 | |
| 703 FILE_PATH_LITERAL(""), | |
| 704 FILE_PATH_LITERAL("foo.exe"), | |
| 705 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 706 | |
| 707 EXPECT_UNCONFIRMED | |
| 708 }, | |
| 709 | |
| 710 { | |
| 711 // 2: Forced Maybe dangerous content | |
| 712 FORCED, | |
| 713 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 714 "http://phishing.example.com/foo.exe", "", | |
| 715 FILE_PATH_LITERAL("forced-foo.exe"), | |
| 716 | |
| 717 FILE_PATH_LITERAL(""), | |
| 718 FILE_PATH_LITERAL("forced-foo.exe"), | |
| 719 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 720 | |
| 721 EXPECT_UNCONFIRMED | |
| 722 }, | |
| 723 }; | |
| 724 | |
| 725 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _)) | |
| 726 .WillByDefault(WithArg<2>(ScheduleCallback( | |
| 727 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT))); | |
| 728 RunTestCasesWithActiveItem(kSafeBrowsingTestCases, | |
| 729 arraysize(kSafeBrowsingTestCases)); | |
| 730 } | |
| 731 | |
| 732 // Test whether the last saved directory is used for 'Save As' downloads. | |
| 733 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LastSavePath) { | |
| 734 const DownloadTestCase kLastSavePathTestCasesPre[] = { | |
| 735 { | |
| 736 // 0: If the last save path is empty, then the default download directory | |
| 737 // should be used. | |
| 738 SAVE_AS, | |
| 739 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 740 "http://example.com/foo.txt", "text/plain", | |
| 741 FILE_PATH_LITERAL(""), | |
| 742 | |
| 743 FILE_PATH_LITERAL(""), | |
| 744 FILE_PATH_LITERAL("foo.txt"), | |
| 745 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 746 | |
| 747 EXPECT_CRDOWNLOAD | |
| 748 } | |
| 749 }; | |
| 750 | |
| 751 // These test cases are run with a last save path set to a non-emtpy local | |
| 752 // download directory. | |
| 753 const DownloadTestCase kLastSavePathTestCasesPost[] = { | |
| 754 { | |
| 755 // 0: This test case is run with the last download directory set to | |
| 756 // '<test_download_dir()>/foo'. | |
| 757 SAVE_AS, | |
| 758 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 759 "http://example.com/foo.txt", "text/plain", | |
| 760 FILE_PATH_LITERAL(""), | |
| 761 | |
| 762 FILE_PATH_LITERAL(""), | |
| 763 FILE_PATH_LITERAL("foo/foo.txt"), | |
| 764 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 765 | |
| 766 EXPECT_CRDOWNLOAD | |
| 767 }, | |
| 768 | |
| 769 { | |
| 770 // 1: Start an automatic download. This should be saved to the user's | |
| 771 // default download directory and not the last used Save As directory. | |
| 772 AUTOMATIC, | |
| 773 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 774 "http://example.com/foo.txt", "text/plain", | |
| 775 FILE_PATH_LITERAL(""), | |
| 776 | |
| 777 FILE_PATH_LITERAL(""), | |
| 778 FILE_PATH_LITERAL("foo.txt"), | |
| 779 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 780 | |
| 781 EXPECT_CRDOWNLOAD | |
| 782 }, | |
| 783 }; | |
| 784 | |
| 785 // This test case is run with the last save path set to a non-empty virtual | |
| 786 // directory. | |
| 787 const DownloadTestCase kLastSavePathTestCasesVirtual[] = { | |
| 788 { | |
| 789 SAVE_AS, | |
| 790 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 791 "http://example.com/foo.txt", "text/plain", | |
| 792 FILE_PATH_LITERAL(""), | |
| 793 | |
| 794 FILE_PATH_LITERAL("virtual/foo/foo.txt"), | |
| 795 FILE_PATH_LITERAL("bar.txt"), | |
| 796 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 797 | |
| 798 EXPECT_LOCAL_PATH | |
| 799 }, | |
| 800 }; | |
| 801 | |
| 802 { | |
| 803 SCOPED_TRACE(testing::Message() | |
| 804 << "Running with empty last_selected_directory"); | |
| 805 base::FilePath prompt_path = | |
| 806 GetPathInDownloadDir(FILE_PATH_LITERAL("foo.txt")); | |
| 807 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _)); | |
| 808 RunTestCasesWithActiveItem(kLastSavePathTestCasesPre, | |
| 809 arraysize(kLastSavePathTestCasesPre)); | |
| 810 } | |
| 811 | |
| 812 // Try with a non-empty last save path. | |
| 813 { | |
| 814 SCOPED_TRACE(testing::Message() | |
| 815 << "Running with local last_selected_directory"); | |
| 816 set_last_selected_directory(test_download_dir().AppendASCII("foo")); | |
| 817 base::FilePath prompt_path = | |
| 818 GetPathInDownloadDir(FILE_PATH_LITERAL("foo/foo.txt")); | |
| 819 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, prompt_path, _)); | |
| 820 RunTestCasesWithActiveItem(kLastSavePathTestCasesPost, | |
| 821 arraysize(kLastSavePathTestCasesPost)); | |
| 822 } | |
| 823 | |
| 824 // And again, but this time use a virtual directory. | |
| 825 { | |
| 826 SCOPED_TRACE(testing::Message() | |
| 827 << "Running with virtual last_selected_directory"); | |
| 828 base::FilePath last_selected_dir = test_virtual_dir().AppendASCII("foo"); | |
| 829 base::FilePath virtual_path = last_selected_dir.AppendASCII("foo.txt"); | |
| 830 set_last_selected_directory(last_selected_dir); | |
| 831 EXPECT_CALL(*delegate(), PromptUserForDownloadPath( | |
| 832 _, last_selected_dir.AppendASCII("foo.txt"), _)); | |
| 833 EXPECT_CALL(*delegate(), DetermineLocalPath(_, virtual_path, _)) | |
| 834 .WillOnce(WithArg<2>(ScheduleCallback( | |
| 835 GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt"))))); | |
| 836 RunTestCasesWithActiveItem(kLastSavePathTestCasesVirtual, | |
| 837 arraysize(kLastSavePathTestCasesVirtual)); | |
| 838 } | |
| 839 } | |
| 840 | |
| 841 // These tests are run with the default downloads folder set to a virtual | |
| 842 // directory. | |
| 843 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_DefaultVirtual) { | |
| 844 // The default download directory is the virutal path. | |
| 845 SetDefaultDownloadPath(test_virtual_dir()); | |
| 846 | |
| 847 { | |
| 848 SCOPED_TRACE(testing::Message() << "Automatic Safe Download"); | |
| 849 const DownloadTestCase kAutomaticDownloadToVirtualDir = { | |
| 850 AUTOMATIC, | |
| 851 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 852 "http://example.com/foo.txt", "text/plain", | |
| 853 FILE_PATH_LITERAL(""), | |
| 854 | |
| 855 // Downloaded to default virtual directory. | |
| 856 FILE_PATH_LITERAL("virtual/foo.txt"), | |
| 857 FILE_PATH_LITERAL("foo-local.txt"), | |
| 858 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 859 | |
| 860 EXPECT_LOCAL_PATH | |
| 861 }; | |
| 862 EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _)) | |
| 863 .WillOnce(WithArg<2>(ScheduleCallback( | |
| 864 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt"))))); | |
| 865 RunTestCasesWithActiveItem(&kAutomaticDownloadToVirtualDir, 1); | |
| 866 } | |
| 867 | |
| 868 { | |
| 869 SCOPED_TRACE(testing::Message() << "Save As to virtual directory"); | |
| 870 const DownloadTestCase kSaveAsToVirtualDir = { | |
| 871 SAVE_AS, | |
| 872 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 873 "http://example.com/bar.txt", "text/plain", | |
| 874 FILE_PATH_LITERAL(""), | |
| 875 | |
| 876 // The response to the download prompt is to choose the 'prompted.txt' | |
| 877 // virtual path. | |
| 878 FILE_PATH_LITERAL("virtual/prompted.txt"), | |
| 879 FILE_PATH_LITERAL("foo-local.txt"), | |
| 880 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 881 | |
| 882 EXPECT_LOCAL_PATH | |
| 883 }; | |
| 884 EXPECT_CALL(*delegate(), DetermineLocalPath(_, _, _)) | |
| 885 .WillOnce(WithArg<2>(ScheduleCallback( | |
| 886 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-local.txt"))))); | |
| 887 EXPECT_CALL(*delegate(), PromptUserForDownloadPath( | |
| 888 _, test_virtual_dir().AppendASCII("bar.txt"), _)) | |
| 889 .WillOnce(WithArg<2>(ScheduleCallback( | |
| 890 test_virtual_dir().AppendASCII("prompted.txt")))); | |
| 891 RunTestCasesWithActiveItem(&kSaveAsToVirtualDir, 1); | |
| 892 } | |
| 893 | |
| 894 { | |
| 895 SCOPED_TRACE(testing::Message() << "Save As to local directory"); | |
| 896 const DownloadTestCase kSaveAsToLocalDir = { | |
| 897 SAVE_AS, | |
| 898 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 899 "http://example.com/bar.txt", "text/plain", | |
| 900 FILE_PATH_LITERAL(""), | |
| 901 | |
| 902 // Response to the 'Save As' is to choose the local path for 'foo-x.txt'. | |
| 903 FILE_PATH_LITERAL(""), | |
| 904 FILE_PATH_LITERAL("foo-x.txt"), | |
| 905 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 906 | |
| 907 EXPECT_CRDOWNLOAD | |
| 908 }; | |
| 909 EXPECT_CALL(*delegate(), PromptUserForDownloadPath( | |
| 910 _, test_virtual_dir().AppendASCII("bar.txt"), _)) | |
| 911 .WillOnce(WithArg<2>(ScheduleCallback( | |
| 912 GetPathInDownloadDir(FILE_PATH_LITERAL("foo-x.txt"))))); | |
| 913 RunTestCasesWithActiveItem(&kSaveAsToLocalDir, 1); | |
| 914 } | |
| 915 | |
| 916 { | |
| 917 SCOPED_TRACE(testing::Message() << "Forced safe download"); | |
| 918 const DownloadTestCase kForcedSafe = { | |
| 919 FORCED, | |
| 920 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 921 "http://example.com/foo.txt", "", | |
| 922 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 923 | |
| 924 // Forced paths should be left as-is. | |
| 925 FILE_PATH_LITERAL(""), | |
| 926 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 927 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 928 | |
| 929 EXPECT_LOCAL_PATH | |
| 930 }; | |
| 931 RunTestCasesWithActiveItem(&kForcedSafe, 1); | |
| 932 } | |
| 933 } | |
| 934 | |
| 935 // Test that an inactive download will still get a virtual or local download | |
| 936 // path. | |
| 937 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_InactiveDownload) { | |
| 938 const DownloadTestCase kInactiveTestCases[] = { | |
| 939 { | |
| 940 AUTOMATIC, | |
| 941 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 942 "http://example.com/foo.txt", "text/plain", | |
| 943 FILE_PATH_LITERAL(""), | |
| 944 | |
| 945 FILE_PATH_LITERAL("foo.txt"), | |
| 946 FILE_PATH_LITERAL(""), | |
| 947 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 948 | |
| 949 EXPECT_LOCAL_PATH | |
| 950 }, | |
| 951 | |
| 952 { | |
| 953 SAVE_AS, | |
| 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_PROMPT, | |
| 961 | |
| 962 EXPECT_LOCAL_PATH | |
| 963 } | |
| 964 }; | |
| 965 | |
| 966 for (size_t i = 0; i < arraysize(kInactiveTestCases); ++i) { | |
| 967 SCOPED_TRACE(testing::Message() << "Running test case " << i); | |
| 968 const DownloadTestCase& test_case = kInactiveTestCases[i]; | |
| 969 scoped_ptr<content::MockDownloadItem> item( | |
| 970 CreateActiveDownloadItem(i, test_case)); | |
| 971 EXPECT_CALL(*item.get(), IsInProgress()) | |
| 972 .WillRepeatedly(Return(false)); | |
| 973 // Even though one is a SAVE_AS download, no prompt will be displayed to | |
| 974 // the user because the download is inactive. | |
| 975 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, _, _)) | |
| 976 .Times(0); | |
| 977 RunTestCase(kInactiveTestCases[i], item.get()); | |
| 978 } | |
| 979 } | |
| 980 | |
| 981 // If the reserved path could not be verified, then the user should see a | |
| 982 // prompt. | |
| 983 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ReservationFailed) { | |
| 984 const DownloadTestCase kReservationFailedCases[] = { | |
| 985 { | |
| 986 // 0: Automatic download. Since the reservation fails, the disposition of | |
| 987 // the target is to prompt, but the returned path is used. | |
| 988 AUTOMATIC, | |
| 989 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 990 "http://example.com/foo.txt", "text/plain", | |
| 991 FILE_PATH_LITERAL(""), | |
| 992 | |
| 993 FILE_PATH_LITERAL(""), | |
| 994 FILE_PATH_LITERAL("bar.txt"), | |
| 995 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 996 | |
| 997 EXPECT_CRDOWNLOAD | |
| 998 }, | |
| 999 }; | |
| 1000 | |
| 1001 // Setup ReserveVirtualPath() to fail. | |
| 1002 ON_CALL(*delegate(), ReserveVirtualPath(_, _, _, _)) | |
| 1003 .WillByDefault(WithArg<3>(ScheduleCallback2( | |
| 1004 GetPathInDownloadDir(FILE_PATH_LITERAL("bar.txt")), false))); | |
| 1005 RunTestCasesWithActiveItem(kReservationFailedCases, | |
| 1006 arraysize(kReservationFailedCases)); | |
| 1007 } | |
| 1008 | |
| 1009 // If the local path could not be determined, the download should be cancelled. | |
| 1010 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_LocalPathFailed) { | |
| 1011 const DownloadTestCase kLocalPathFailedCases[] = { | |
| 1012 { | |
| 1013 // 0: Automatic download. | |
| 1014 AUTOMATIC, | |
| 1015 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1016 "http://example.com/foo.txt", "text/plain", | |
| 1017 FILE_PATH_LITERAL(""), | |
| 1018 | |
| 1019 FILE_PATH_LITERAL(""), | |
| 1020 FILE_PATH_LITERAL(""), | |
| 1021 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1022 | |
| 1023 EXPECT_LOCAL_PATH | |
| 1024 }, | |
| 1025 }; | |
| 1026 | |
| 1027 base::FilePath expected_virtual_path( | |
| 1028 GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt"))); | |
| 1029 // The default download directory is the virtual path. | |
| 1030 SetDefaultDownloadPath(test_virtual_dir()); | |
| 1031 // Simulate failed call to DetermineLocalPath. | |
| 1032 EXPECT_CALL(*delegate(), DetermineLocalPath( | |
| 1033 _, GetPathInDownloadDir(FILE_PATH_LITERAL("virtual/foo.txt")), _)) | |
| 1034 .WillOnce(WithArg<2>(ScheduleCallback(base::FilePath()))); | |
| 1035 RunTestCasesWithActiveItem(kLocalPathFailedCases, | |
| 1036 arraysize(kLocalPathFailedCases)); | |
| 1037 } | |
| 1038 | |
| 1039 // Downloads that have a danger level of AllowOnUserGesture should be marked as | |
| 1040 // safe depending on whether there was a user gesture associated with the | |
| 1041 // download and whether the referrer was visited prior to today. | |
| 1042 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_VisitedReferrer) { | |
| 1043 const DownloadTestCase kVisitedReferrerCases[] = { | |
| 1044 // http://visited.example.com/ is added to the history as a visit that | |
| 1045 // happened prior to today. | |
| 1046 { | |
| 1047 // 0: Safe download due to visiting referrer before. | |
| 1048 AUTOMATIC, | |
| 1049 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1050 "http://visited.example.com/foo.html", "text/html", | |
| 1051 FILE_PATH_LITERAL(""), | |
| 1052 | |
| 1053 FILE_PATH_LITERAL(""), | |
| 1054 FILE_PATH_LITERAL("foo.html"), | |
| 1055 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1056 | |
| 1057 EXPECT_CRDOWNLOAD | |
| 1058 }, | |
| 1059 | |
| 1060 { | |
| 1061 // 1: Dangerous due to not having visited referrer before. | |
| 1062 AUTOMATIC, | |
| 1063 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 1064 "http://not-visited.example.com/foo.html", "text/html", | |
| 1065 FILE_PATH_LITERAL(""), | |
| 1066 | |
| 1067 FILE_PATH_LITERAL(""), | |
| 1068 FILE_PATH_LITERAL("foo.html"), | |
| 1069 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1070 | |
| 1071 EXPECT_UNCONFIRMED | |
| 1072 }, | |
| 1073 | |
| 1074 { | |
| 1075 // 2: Safe because the user is being prompted. | |
| 1076 SAVE_AS, | |
| 1077 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1078 "http://not-visited.example.com/foo.html", "text/html", | |
| 1079 FILE_PATH_LITERAL(""), | |
| 1080 | |
| 1081 FILE_PATH_LITERAL(""), | |
| 1082 FILE_PATH_LITERAL("foo.html"), | |
| 1083 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 1084 | |
| 1085 EXPECT_CRDOWNLOAD | |
| 1086 }, | |
| 1087 | |
| 1088 { | |
| 1089 // 3: Safe because of forced path. | |
| 1090 FORCED, | |
| 1091 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1092 "http://not-visited.example.com/foo.html", "text/html", | |
| 1093 FILE_PATH_LITERAL("foo.html"), | |
| 1094 | |
| 1095 FILE_PATH_LITERAL(""), | |
| 1096 FILE_PATH_LITERAL("foo.html"), | |
| 1097 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1098 | |
| 1099 EXPECT_LOCAL_PATH | |
| 1100 }, | |
| 1101 }; | |
| 1102 | |
| 1103 // This test assumes that the danger level of .html files is | |
| 1104 // AllowOnUserGesture. | |
| 1105 ASSERT_EQ(download_util::AllowOnUserGesture, | |
| 1106 download_util::GetFileDangerLevel( | |
| 1107 base::FilePath(FILE_PATH_LITERAL("foo.html")))); | |
| 1108 | |
| 1109 // First the history service must exist. | |
| 1110 profile()->CreateHistoryService(false, false); | |
| 1111 | |
| 1112 GURL url("http://visited.example.com/visited-link.html"); | |
| 1113 // The time of visit is picked to be several seconds prior to the most recent | |
| 1114 // midnight. | |
| 1115 base::Time time_of_visit( | |
| 1116 base::Time::Now().LocalMidnight() - base::TimeDelta::FromSeconds(10)); | |
| 1117 HistoryService* history_service = | |
| 1118 HistoryServiceFactory::GetForProfile(profile(), Profile::EXPLICIT_ACCESS); | |
| 1119 ASSERT_TRUE(history_service); | |
| 1120 history_service->AddPage(url, time_of_visit, history::SOURCE_BROWSED); | |
| 1121 | |
| 1122 RunTestCasesWithActiveItem(kVisitedReferrerCases, | |
| 1123 arraysize(kVisitedReferrerCases)); | |
| 1124 } | |
| 1125 | |
| 1126 // These test cases are run with "Prompt for download" user preference set to | |
| 1127 // true. | |
| 1128 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways) { | |
| 1129 const DownloadTestCase kPromptingTestCases[] = { | |
| 1130 { | |
| 1131 // 0: Safe Automatic - Should prompt because of "Prompt for download" | |
| 1132 // preference setting. | |
| 1133 AUTOMATIC, | |
| 1134 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1135 "http://example.com/foo.txt", "text/plain", | |
| 1136 FILE_PATH_LITERAL(""), | |
| 1137 | |
| 1138 FILE_PATH_LITERAL(""), | |
| 1139 FILE_PATH_LITERAL("foo.txt"), | |
| 1140 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 1141 | |
| 1142 EXPECT_CRDOWNLOAD | |
| 1143 }, | |
| 1144 | |
| 1145 { | |
| 1146 // 1: Safe Forced - Shouldn't prompt. | |
| 1147 FORCED, | |
| 1148 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1149 "http://example.com/foo.txt", "text/plain", | |
| 1150 FILE_PATH_LITERAL("foo.txt"), | |
| 1151 | |
| 1152 FILE_PATH_LITERAL(""), | |
| 1153 FILE_PATH_LITERAL("foo.txt"), | |
| 1154 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1155 | |
| 1156 EXPECT_LOCAL_PATH | |
| 1157 }, | |
| 1158 | |
| 1159 { | |
| 1160 // 2: Automatic - The filename extension is marked as one that we will | |
| 1161 // open automatically. Shouldn't prompt. | |
| 1162 AUTOMATIC, | |
| 1163 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1164 "http://example.com/foo.dummy", "", | |
| 1165 FILE_PATH_LITERAL(""), | |
| 1166 | |
| 1167 FILE_PATH_LITERAL(""), | |
| 1168 FILE_PATH_LITERAL("foo.dummy"), | |
| 1169 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1170 | |
| 1171 EXPECT_CRDOWNLOAD | |
| 1172 }, | |
| 1173 }; | |
| 1174 | |
| 1175 SetPromptForDownload(true); | |
| 1176 EnableAutoOpenBasedOnExtension( | |
| 1177 base::FilePath(FILE_PATH_LITERAL("dummy.dummy"))); | |
| 1178 RunTestCasesWithActiveItem(kPromptingTestCases, | |
| 1179 arraysize(kPromptingTestCases)); | |
| 1180 } | |
| 1181 | |
| 1182 #if !defined(OS_ANDROID) | |
| 1183 // These test cases are run with "Prompt for download" user preference set to | |
| 1184 // true. Automatic extension downloads shouldn't cause prompting. | |
| 1185 // Android doesn't support extensions. | |
| 1186 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_PromptAlways_Extension) { | |
| 1187 const DownloadTestCase kPromptingTestCases[] = { | |
| 1188 { | |
| 1189 // 0: Automatic Browser Extension download. - Shouldn't prompt for browser | |
| 1190 // extension downloads even if "Prompt for download" preference is set. | |
| 1191 AUTOMATIC, | |
| 1192 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 1193 "http://example.com/foo.crx", | |
| 1194 extensions::Extension::kMimeType, | |
| 1195 FILE_PATH_LITERAL(""), | |
| 1196 | |
| 1197 FILE_PATH_LITERAL(""), | |
| 1198 FILE_PATH_LITERAL("foo.crx"), | |
| 1199 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1200 | |
| 1201 EXPECT_UNCONFIRMED | |
| 1202 }, | |
| 1203 | |
| 1204 #if defined(OS_WIN) | |
| 1205 { | |
| 1206 // 1: Automatic User Script - Shouldn't prompt for user script downloads | |
| 1207 // even if "Prompt for download" preference is set. ".js" files are | |
| 1208 // considered dangerous on Windows. | |
| 1209 AUTOMATIC, | |
| 1210 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 1211 "http://example.com/foo.user.js", "", | |
| 1212 FILE_PATH_LITERAL(""), | |
| 1213 | |
| 1214 FILE_PATH_LITERAL(""), | |
| 1215 FILE_PATH_LITERAL("foo.user.js"), | |
| 1216 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1217 | |
| 1218 EXPECT_UNCONFIRMED | |
| 1219 }, | |
| 1220 #else | |
| 1221 { | |
| 1222 // 1: Automatic User Script - Shouldn't prompt for user script downloads | |
| 1223 // even if "Prompt for download" preference is set. | |
| 1224 AUTOMATIC, | |
| 1225 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1226 "http://example.com/foo.user.js", "", | |
| 1227 FILE_PATH_LITERAL(""), | |
| 1228 | |
| 1229 FILE_PATH_LITERAL(""), | |
| 1230 FILE_PATH_LITERAL("foo.user.js"), | |
| 1231 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1232 | |
| 1233 EXPECT_CRDOWNLOAD | |
| 1234 }, | |
| 1235 #endif | |
| 1236 }; | |
| 1237 | |
| 1238 SetPromptForDownload(true); | |
| 1239 RunTestCasesWithActiveItem(kPromptingTestCases, | |
| 1240 arraysize(kPromptingTestCases)); | |
| 1241 } | |
| 1242 #endif | |
| 1243 | |
| 1244 // If the download path is managed, then we don't show any prompts. | |
| 1245 // Note that if the download path is managed, then PromptForDownload() is false. | |
| 1246 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_ManagedPath) { | |
| 1247 const DownloadTestCase kManagedPathTestCases[] = { | |
| 1248 { | |
| 1249 // 0: Automatic Safe | |
| 1250 AUTOMATIC, | |
| 1251 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1252 "http://example.com/foo.txt", "text/plain", | |
| 1253 FILE_PATH_LITERAL(""), | |
| 1254 | |
| 1255 FILE_PATH_LITERAL(""), | |
| 1256 FILE_PATH_LITERAL("foo.txt"), | |
| 1257 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1258 | |
| 1259 EXPECT_CRDOWNLOAD | |
| 1260 }, | |
| 1261 | |
| 1262 { | |
| 1263 // 1: Save_As Safe | |
| 1264 SAVE_AS, | |
| 1265 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1266 "http://example.com/foo.txt", "text/plain", | |
| 1267 FILE_PATH_LITERAL(""), | |
| 1268 | |
| 1269 FILE_PATH_LITERAL(""), | |
| 1270 FILE_PATH_LITERAL("foo.txt"), | |
| 1271 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1272 | |
| 1273 EXPECT_CRDOWNLOAD | |
| 1274 }, | |
| 1275 }; | |
| 1276 | |
| 1277 SetManagedDownloadPath(test_download_dir()); | |
| 1278 ASSERT_TRUE(download_prefs()->IsDownloadPathManaged()); | |
| 1279 RunTestCasesWithActiveItem(kManagedPathTestCases, | |
| 1280 arraysize(kManagedPathTestCases)); | |
| 1281 } | |
| 1282 | |
| 1283 // Test basic functionality supporting extensions that want to override download | |
| 1284 // filenames. | |
| 1285 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsSafe) { | |
| 1286 const DownloadTestCase kNotifyExtensionsTestCases[] = { | |
| 1287 { | |
| 1288 // 0: Automatic Safe | |
| 1289 AUTOMATIC, | |
| 1290 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1291 "http://example.com/foo.txt", "text/plain", | |
| 1292 FILE_PATH_LITERAL(""), | |
| 1293 | |
| 1294 FILE_PATH_LITERAL(""), | |
| 1295 FILE_PATH_LITERAL("overridden/foo.txt"), | |
| 1296 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1297 | |
| 1298 EXPECT_CRDOWNLOAD | |
| 1299 }, | |
| 1300 | |
| 1301 { | |
| 1302 // 1: Save_As Safe | |
| 1303 SAVE_AS, | |
| 1304 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1305 "http://example.com/foo.txt", "text/plain", | |
| 1306 FILE_PATH_LITERAL(""), | |
| 1307 | |
| 1308 FILE_PATH_LITERAL(""), | |
| 1309 FILE_PATH_LITERAL("overridden/foo.txt"), | |
| 1310 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 1311 | |
| 1312 EXPECT_CRDOWNLOAD | |
| 1313 }, | |
| 1314 | |
| 1315 { | |
| 1316 // 2: Automatic Dangerous | |
| 1317 AUTOMATIC, | |
| 1318 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 1319 "http://example.com/foo.html", "", | |
| 1320 FILE_PATH_LITERAL(""), | |
| 1321 | |
| 1322 FILE_PATH_LITERAL(""), | |
| 1323 FILE_PATH_LITERAL("overridden/foo.html"), | |
| 1324 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1325 | |
| 1326 EXPECT_UNCONFIRMED | |
| 1327 }, | |
| 1328 | |
| 1329 { | |
| 1330 // 3: Forced Safe | |
| 1331 FORCED, | |
| 1332 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1333 "http://example.com/foo.txt", "", | |
| 1334 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 1335 | |
| 1336 FILE_PATH_LITERAL(""), | |
| 1337 FILE_PATH_LITERAL("forced-foo.txt"), | |
| 1338 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1339 | |
| 1340 EXPECT_LOCAL_PATH | |
| 1341 }, | |
| 1342 }; | |
| 1343 | |
| 1344 ON_CALL(*delegate(), NotifyExtensions(_, _, _)) | |
| 1345 .WillByDefault(Invoke(&NotifyExtensionsOverridePath)); | |
| 1346 RunTestCasesWithActiveItem(kNotifyExtensionsTestCases, | |
| 1347 arraysize(kNotifyExtensionsTestCases)); | |
| 1348 } | |
| 1349 | |
| 1350 // Test that filenames provided by extensions are passed into SafeBrowsing | |
| 1351 // checks and dangerous download checks. | |
| 1352 TEST_F(DownloadTargetDeterminerTest, TargetDeterminer_NotifyExtensionsUnsafe) { | |
| 1353 const DownloadTestCase kNotifyExtensionsTestCases[] = { | |
| 1354 { | |
| 1355 // 0: Automatic Safe : Later overridden by a dangerous filetype. | |
| 1356 AUTOMATIC, | |
| 1357 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, | |
| 1358 "http://example.com/foo.html.remove", "text/plain", | |
| 1359 FILE_PATH_LITERAL(""), | |
| 1360 | |
| 1361 FILE_PATH_LITERAL(""), | |
| 1362 FILE_PATH_LITERAL("overridden/foo.html"), | |
| 1363 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1364 | |
| 1365 EXPECT_UNCONFIRMED | |
| 1366 }, | |
| 1367 | |
| 1368 { | |
| 1369 // 1: Automatic Safe : Later overridden by a potentially dangerous | |
| 1370 // filetype. | |
| 1371 AUTOMATIC, | |
| 1372 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, | |
| 1373 "http://example.com/foo.exe.remove", "text/plain", | |
| 1374 FILE_PATH_LITERAL(""), | |
| 1375 | |
| 1376 FILE_PATH_LITERAL(""), | |
| 1377 FILE_PATH_LITERAL("overridden/foo.exe"), | |
| 1378 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1379 | |
| 1380 EXPECT_UNCONFIRMED | |
| 1381 }, | |
| 1382 }; | |
| 1383 | |
| 1384 ON_CALL(*delegate(), NotifyExtensions(_, _, _)) | |
| 1385 .WillByDefault(Invoke(&NotifyExtensionsOverridePath)); | |
| 1386 ON_CALL(*delegate(), CheckDownloadUrl(_, _, _)) | |
| 1387 .WillByDefault(Invoke(&CheckDownloadUrlCheckExes)); | |
| 1388 RunTestCasesWithActiveItem(kNotifyExtensionsTestCases, | |
| 1389 arraysize(kNotifyExtensionsTestCases)); | |
| 1390 } | |
| 1391 | |
| 1392 // Test that conflict actions set by extensions are passed correctly into | |
| 1393 // ReserveVirtualPath. | |
| 1394 TEST_F(DownloadTargetDeterminerTest, | |
| 1395 TargetDeterminer_NotifyExtensionsConflict) { | |
| 1396 const DownloadTestCase kNotifyExtensionsTestCase = { | |
| 1397 AUTOMATIC, | |
| 1398 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1399 "http://example.com/foo.txt", "text/plain", | |
| 1400 FILE_PATH_LITERAL(""), | |
| 1401 | |
| 1402 FILE_PATH_LITERAL(""), | |
| 1403 FILE_PATH_LITERAL("overridden/foo.txt"), | |
| 1404 DownloadItem::TARGET_DISPOSITION_OVERWRITE, | |
| 1405 | |
| 1406 EXPECT_CRDOWNLOAD | |
| 1407 }; | |
| 1408 | |
| 1409 const DownloadTestCase& test_case = kNotifyExtensionsTestCase; | |
| 1410 scoped_ptr<content::MockDownloadItem> item( | |
| 1411 CreateActiveDownloadItem(0, test_case)); | |
| 1412 base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt")); | |
| 1413 base::FilePath full_overridden_path = | |
| 1414 GetPathInDownloadDir(overridden_path.value()); | |
| 1415 | |
| 1416 // First case: An extension sets the conflict_action to OVERWRITE. | |
| 1417 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | |
| 1418 .WillOnce(WithArg<2>( | |
| 1419 ScheduleCallback2(overridden_path, | |
| 1420 DownloadPathReservationTracker::OVERWRITE))); | |
| 1421 EXPECT_CALL(*delegate(), ReserveVirtualPath( | |
| 1422 _, full_overridden_path, DownloadPathReservationTracker::OVERWRITE, _)) | |
| 1423 .WillOnce(WithArg<3>( | |
| 1424 ScheduleCallback2(full_overridden_path, true))); | |
| 1425 | |
| 1426 RunTestCase(test_case, item.get()); | |
| 1427 | |
| 1428 // Second case: An extension sets the conflict_action to PROMPT. | |
| 1429 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | |
| 1430 .WillOnce(WithArg<2>( | |
| 1431 ScheduleCallback2(overridden_path, | |
| 1432 DownloadPathReservationTracker::PROMPT))); | |
| 1433 EXPECT_CALL(*delegate(), ReserveVirtualPath( | |
| 1434 _, full_overridden_path, DownloadPathReservationTracker::PROMPT, _)) | |
| 1435 .WillOnce(WithArg<3>( | |
| 1436 ScheduleCallback2(full_overridden_path, true))); | |
| 1437 RunTestCase(test_case, item.get()); | |
| 1438 } | |
| 1439 | |
| 1440 // Test that relative paths returned by extensions are always relative to the | |
| 1441 // default downloads path. | |
| 1442 TEST_F(DownloadTargetDeterminerTest, | |
| 1443 TargetDeterminer_NotifyExtensionsDefaultPath) { | |
| 1444 const DownloadTestCase kNotifyExtensionsTestCase = { | |
| 1445 SAVE_AS, | |
| 1446 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, | |
| 1447 "http://example.com/foo.txt", "text/plain", | |
| 1448 FILE_PATH_LITERAL(""), | |
| 1449 | |
| 1450 FILE_PATH_LITERAL(""), | |
| 1451 FILE_PATH_LITERAL("overridden/foo.txt"), | |
| 1452 DownloadItem::TARGET_DISPOSITION_PROMPT, | |
| 1453 | |
| 1454 EXPECT_CRDOWNLOAD | |
| 1455 }; | |
| 1456 | |
| 1457 const DownloadTestCase& test_case = kNotifyExtensionsTestCase; | |
| 1458 scoped_ptr<content::MockDownloadItem> item( | |
| 1459 CreateActiveDownloadItem(0, test_case)); | |
| 1460 base::FilePath overridden_path(FILE_PATH_LITERAL("overridden/foo.txt")); | |
| 1461 base::FilePath full_overridden_path = | |
| 1462 GetPathInDownloadDir(overridden_path.value()); | |
| 1463 | |
| 1464 // The last selected directory is this one. Since the test case is a SAVE_AS | |
| 1465 // download, it should use this directory for the generated path. | |
| 1466 set_last_selected_directory(GetPathInDownloadDir( | |
| 1467 FILE_PATH_LITERAL("last_selected"))); | |
| 1468 | |
| 1469 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | |
| 1470 .WillOnce(WithArg<2>( | |
| 1471 ScheduleCallback2(overridden_path, | |
| 1472 DownloadPathReservationTracker::UNIQUIFY))); | |
| 1473 EXPECT_CALL(*delegate(), | |
| 1474 PromptUserForDownloadPath(_, full_overridden_path, _)) | |
| 1475 .WillOnce(WithArg<2>( | |
| 1476 ScheduleCallback(full_overridden_path))); | |
| 1477 RunTestCase(test_case, item.get()); | |
| 1478 } | |
| 1479 } // namespace | |
| OLD | NEW |