OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "base/at_exit.h" |
5 #include "base/files/file_path.h" | 6 #include "base/files/file_path.h" |
6 #include "base/files/scoped_temp_dir.h" | 7 #include "base/files/scoped_temp_dir.h" |
7 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
8 #include "base/observer_list.h" | 9 #include "base/observer_list.h" |
9 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
10 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
11 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
12 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
13 #include "base/value_conversions.h" | 14 #include "base/value_conversions.h" |
14 #include "chrome/browser/download/chrome_download_manager_delegate.h" | 15 #include "chrome/browser/download/chrome_download_manager_delegate.h" |
15 #include "chrome/browser/download/download_extensions.h" | 16 #include "chrome/browser/download/download_extensions.h" |
16 #include "chrome/browser/download/download_prefs.h" | 17 #include "chrome/browser/download/download_prefs.h" |
17 #include "chrome/browser/download/download_target_determiner.h" | 18 #include "chrome/browser/download/download_target_determiner.h" |
| 19 #include "chrome/browser/download/download_target_info.h" |
18 #include "chrome/browser/history/history_service.h" | 20 #include "chrome/browser/history/history_service.h" |
19 #include "chrome/browser/history/history_service_factory.h" | 21 #include "chrome/browser/history/history_service_factory.h" |
20 #include "chrome/browser/history/history_types.h" | 22 #include "chrome/browser/history/history_types.h" |
21 #include "chrome/common/extensions/extension.h" | 23 #include "chrome/common/extensions/extension.h" |
22 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
23 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 25 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
24 #include "chrome/test/base/testing_pref_service_syncable.h" | 26 #include "chrome/test/base/testing_pref_service_syncable.h" |
25 #include "chrome/test/base/testing_profile.h" | 27 #include "chrome/test/base/testing_profile.h" |
26 #include "content/public/browser/download_interrupt_reasons.h" | 28 #include "content/public/browser/download_interrupt_reasons.h" |
| 29 #include "content/public/browser/render_process_host.h" |
27 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
28 #include "content/public/browser/web_contents_delegate.h" | 31 #include "content/public/browser/web_contents_delegate.h" |
29 #include "content/public/test/mock_download_item.h" | 32 #include "content/public/test/mock_download_item.h" |
30 #include "content/public/test/test_browser_thread.h" | 33 #include "content/public/test/test_browser_thread.h" |
31 #include "content/public/test/test_renderer_host.h" | 34 #include "content/public/test/test_renderer_host.h" |
32 #include "content/public/test/web_contents_tester.h" | 35 #include "content/public/test/web_contents_tester.h" |
| 36 #include "net/base/mime_util.h" |
33 #include "testing/gmock/include/gmock/gmock.h" | 37 #include "testing/gmock/include/gmock/gmock.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
35 | 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 |
36 using ::testing::AnyNumber; | 46 using ::testing::AnyNumber; |
37 using ::testing::Invoke; | 47 using ::testing::Invoke; |
38 using ::testing::Ref; | 48 using ::testing::Ref; |
39 using ::testing::Return; | 49 using ::testing::Return; |
40 using ::testing::ReturnRef; | 50 using ::testing::ReturnRef; |
41 using ::testing::ReturnRefOfCopy; | 51 using ::testing::ReturnRefOfCopy; |
42 using ::testing::Truly; | 52 using ::testing::Truly; |
43 using ::testing::WithArg; | 53 using ::testing::WithArg; |
44 using ::testing::_; | 54 using ::testing::_; |
45 using content::DownloadItem; | 55 using content::DownloadItem; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 MOCK_METHOD3(PromptUserForDownloadPath, | 146 MOCK_METHOD3(PromptUserForDownloadPath, |
137 void(content::DownloadItem*, const base::FilePath&, | 147 void(content::DownloadItem*, const base::FilePath&, |
138 const FileSelectedCallback&)); | 148 const FileSelectedCallback&)); |
139 MOCK_METHOD3(DetermineLocalPath, | 149 MOCK_METHOD3(DetermineLocalPath, |
140 void(DownloadItem*, const base::FilePath&, | 150 void(DownloadItem*, const base::FilePath&, |
141 const LocalPathCallback&)); | 151 const LocalPathCallback&)); |
142 MOCK_METHOD5(ReserveVirtualPath, | 152 MOCK_METHOD5(ReserveVirtualPath, |
143 void(DownloadItem*, const base::FilePath&, bool, | 153 void(DownloadItem*, const base::FilePath&, bool, |
144 DownloadPathReservationTracker::FilenameConflictAction, | 154 DownloadPathReservationTracker::FilenameConflictAction, |
145 const ReservedPathCallback&)); | 155 const ReservedPathCallback&)); |
| 156 MOCK_METHOD2(GetFileMimeType, |
| 157 void(const base::FilePath&, |
| 158 const GetFileMimeTypeCallback&)); |
146 | 159 |
147 void SetupDefaults() { | 160 void SetupDefaults() { |
148 ON_CALL(*this, CheckDownloadUrl(_, _, _)) | 161 ON_CALL(*this, CheckDownloadUrl(_, _, _)) |
149 .WillByDefault(WithArg<2>( | 162 .WillByDefault(WithArg<2>( |
150 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS))); | 163 ScheduleCallback(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS))); |
151 ON_CALL(*this, NotifyExtensions(_, _, _)) | 164 ON_CALL(*this, NotifyExtensions(_, _, _)) |
152 .WillByDefault(WithArg<2>( | 165 .WillByDefault(WithArg<2>( |
153 ScheduleCallback2(base::FilePath(), | 166 ScheduleCallback2(base::FilePath(), |
154 DownloadPathReservationTracker::UNIQUIFY))); | 167 DownloadPathReservationTracker::UNIQUIFY))); |
155 ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _)) | 168 ON_CALL(*this, ReserveVirtualPath(_, _, _, _, _)) |
156 .WillByDefault(Invoke( | 169 .WillByDefault(Invoke( |
157 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath)); | 170 &MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath)); |
158 ON_CALL(*this, PromptUserForDownloadPath(_, _, _)) | 171 ON_CALL(*this, PromptUserForDownloadPath(_, _, _)) |
159 .WillByDefault(Invoke( | 172 .WillByDefault(Invoke( |
160 &MockDownloadTargetDeterminerDelegate::NullPromptUser)); | 173 &MockDownloadTargetDeterminerDelegate::NullPromptUser)); |
161 ON_CALL(*this, DetermineLocalPath(_, _, _)) | 174 ON_CALL(*this, DetermineLocalPath(_, _, _)) |
162 .WillByDefault(Invoke( | 175 .WillByDefault(Invoke( |
163 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); | 176 &MockDownloadTargetDeterminerDelegate::NullDetermineLocalPath)); |
| 177 ON_CALL(*this, GetFileMimeType(_, _)) |
| 178 .WillByDefault(WithArg<1>( |
| 179 ScheduleCallback(""))); |
164 } | 180 } |
165 private: | 181 private: |
166 static void NullReserveVirtualPath( | 182 static void NullReserveVirtualPath( |
167 DownloadItem* download, | 183 DownloadItem* download, |
168 const base::FilePath& virtual_path, | 184 const base::FilePath& virtual_path, |
169 bool create_directory, | 185 bool create_directory, |
170 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 186 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
171 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback); | 187 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback); |
172 static void NullPromptUser( | 188 static void NullPromptUser( |
173 DownloadItem* download, const base::FilePath& suggested_path, | 189 DownloadItem* download, const base::FilePath& suggested_path, |
(...skipping 25 matching lines...) Expand all Loading... |
199 | 215 |
200 // Given the relative path |path|, returns the full path under the temporary | 216 // Given the relative path |path|, returns the full path under the temporary |
201 // downloads directory. | 217 // downloads directory. |
202 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); | 218 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); |
203 | 219 |
204 // Run |test_case| using |item|. | 220 // Run |test_case| using |item|. |
205 void RunTestCase(const DownloadTestCase& test_case, | 221 void RunTestCase(const DownloadTestCase& test_case, |
206 const base::FilePath& initial_virtual_path, | 222 const base::FilePath& initial_virtual_path, |
207 content::MockDownloadItem* item); | 223 content::MockDownloadItem* item); |
208 | 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 |
209 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem | 231 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem |
210 // will be created for each test case and destroyed when the test case is | 232 // will be created for each test case and destroyed when the test case is |
211 // complete. | 233 // complete. |
212 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], | 234 void RunTestCasesWithActiveItem(const DownloadTestCase test_cases[], |
213 size_t test_case_count); | 235 size_t test_case_count); |
214 | 236 |
215 // Verifies that |target_path|, |disposition|, |expected_danger_type| and | 237 // Verifies that |target_path|, |disposition|, |expected_danger_type| and |
216 // |intermediate_path| matches the expectations of |test_case|. Posts | 238 // |intermediate_path| matches the expectations of |test_case|. Posts |
217 // |closure| to the current message loop when done. | 239 // |closure| to the current message loop when done. |
218 void DownloadTargetVerifier(const base::Closure& closure, | 240 void VerifyDownloadTarget(const DownloadTestCase& test_case, |
219 const DownloadTestCase& test_case, | 241 const DownloadTargetInfo* target_info); |
220 const base::FilePath& local_path, | |
221 DownloadItem::TargetDisposition disposition, | |
222 content::DownloadDangerType danger_type, | |
223 const base::FilePath& intermediate_path); | |
224 | 242 |
225 const base::FilePath& test_download_dir() const { | 243 const base::FilePath& test_download_dir() const { |
226 return test_download_dir_.path(); | 244 return test_download_dir_.path(); |
227 } | 245 } |
228 | 246 |
229 const base::FilePath& test_virtual_dir() const { | 247 const base::FilePath& test_virtual_dir() const { |
230 return test_virtual_dir_; | 248 return test_virtual_dir_; |
231 } | 249 } |
232 | 250 |
233 MockDownloadTargetDeterminerDelegate* delegate() { | 251 MockDownloadTargetDeterminerDelegate* delegate() { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 if (relative_path.empty()) | 361 if (relative_path.empty()) |
344 return base::FilePath(); | 362 return base::FilePath(); |
345 base::FilePath full_path(test_download_dir().Append(relative_path)); | 363 base::FilePath full_path(test_download_dir().Append(relative_path)); |
346 return full_path.NormalizePathSeparators(); | 364 return full_path.NormalizePathSeparators(); |
347 } | 365 } |
348 | 366 |
349 void DownloadTargetDeterminerTest::RunTestCase( | 367 void DownloadTargetDeterminerTest::RunTestCase( |
350 const DownloadTestCase& test_case, | 368 const DownloadTestCase& test_case, |
351 const base::FilePath& initial_virtual_path, | 369 const base::FilePath& initial_virtual_path, |
352 content::MockDownloadItem* item) { | 370 content::MockDownloadItem* item) { |
353 // Kick off the test. | 371 scoped_ptr<DownloadTargetInfo> target_info = |
354 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); | 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; |
355 base::RunLoop run_loop; | 389 base::RunLoop run_loop; |
356 DownloadTargetDeterminer::Start( | 390 DownloadTargetDeterminer::Start( |
357 item, initial_virtual_path, download_prefs_.get(), delegate(), | 391 item, initial_virtual_path, download_prefs_.get(), delegate(), |
358 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, | 392 base::Bind(&CompletionCallbackWrapper, |
359 factory.GetWeakPtr(), run_loop.QuitClosure(), test_case)); | 393 run_loop.QuitClosure(), |
| 394 &target_info)); |
360 run_loop.Run(); | 395 run_loop.Run(); |
361 ::testing::Mock::VerifyAndClearExpectations(delegate()); | 396 ::testing::Mock::VerifyAndClearExpectations(delegate()); |
| 397 return target_info.Pass(); |
362 } | 398 } |
363 | 399 |
364 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( | 400 void DownloadTargetDeterminerTest::RunTestCasesWithActiveItem( |
365 const DownloadTestCase test_cases[], | 401 const DownloadTestCase test_cases[], |
366 size_t test_case_count) { | 402 size_t test_case_count) { |
367 for (size_t i = 0; i < test_case_count; ++i) { | 403 for (size_t i = 0; i < test_case_count; ++i) { |
368 scoped_ptr<content::MockDownloadItem> item( | 404 scoped_ptr<content::MockDownloadItem> item( |
369 CreateActiveDownloadItem(i, test_cases[i])); | 405 CreateActiveDownloadItem(i, test_cases[i])); |
370 SCOPED_TRACE(testing::Message() << "Running test case " << i); | 406 SCOPED_TRACE(testing::Message() << "Running test case " << i); |
371 RunTestCase(test_cases[i], base::FilePath(), item.get()); | 407 RunTestCase(test_cases[i], base::FilePath(), item.get()); |
372 } | 408 } |
373 } | 409 } |
374 | 410 |
375 void DownloadTargetDeterminerTest::DownloadTargetVerifier( | 411 void DownloadTargetDeterminerTest::VerifyDownloadTarget( |
376 const base::Closure& closure, | |
377 const DownloadTestCase& test_case, | 412 const DownloadTestCase& test_case, |
378 const base::FilePath& local_path, | 413 const DownloadTargetInfo* target_info) { |
379 DownloadItem::TargetDisposition disposition, | |
380 content::DownloadDangerType danger_type, | |
381 const base::FilePath& intermediate_path) { | |
382 base::FilePath expected_local_path( | 414 base::FilePath expected_local_path( |
383 GetPathInDownloadDir(test_case.expected_local_path)); | 415 GetPathInDownloadDir(test_case.expected_local_path)); |
384 EXPECT_EQ(expected_local_path.value(), local_path.value()); | 416 EXPECT_EQ(expected_local_path.value(), target_info->target_path.value()); |
385 EXPECT_EQ(test_case.expected_disposition, disposition); | 417 EXPECT_EQ(test_case.expected_disposition, target_info->target_disposition); |
386 EXPECT_EQ(test_case.expected_danger_type, danger_type); | 418 EXPECT_EQ(test_case.expected_danger_type, target_info->danger_type); |
387 | 419 |
388 switch (test_case.expected_intermediate) { | 420 switch (test_case.expected_intermediate) { |
389 case EXPECT_CRDOWNLOAD: | 421 case EXPECT_CRDOWNLOAD: |
390 EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath(local_path).value(), | 422 EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath( |
391 intermediate_path.value()); | 423 target_info->target_path).value(), |
| 424 target_info->intermediate_path.value()); |
392 break; | 425 break; |
393 | 426 |
394 case EXPECT_UNCONFIRMED: | 427 case EXPECT_UNCONFIRMED: |
395 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. | 428 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload. |
396 // Of this, we only check that the path is: | 429 // Of this, we only check that the path is: |
397 // 1. Not "/path/target.crdownload", | 430 // 1. Not "/path/target.crdownload", |
398 // 2. Points to the same directory as the target. | 431 // 2. Points to the same directory as the target. |
399 // 3. Has extension ".crdownload". | 432 // 3. Has extension ".crdownload". |
400 // 4. Basename starts with "Unconfirmed ". | 433 // 4. Basename starts with "Unconfirmed ". |
401 EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path) | 434 EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(expected_local_path) |
402 .value(), | 435 .value(), |
403 intermediate_path.value()); | 436 target_info->intermediate_path.value()); |
404 EXPECT_EQ(expected_local_path.DirName().value(), | 437 EXPECT_EQ(expected_local_path.DirName().value(), |
405 intermediate_path.DirName().value()); | 438 target_info->intermediate_path.DirName().value()); |
406 EXPECT_TRUE(intermediate_path.MatchesExtension( | 439 EXPECT_TRUE(target_info->intermediate_path.MatchesExtension( |
407 FILE_PATH_LITERAL(".crdownload"))); | 440 FILE_PATH_LITERAL(".crdownload"))); |
408 EXPECT_EQ(0u, intermediate_path.BaseName().value().find( | 441 EXPECT_EQ(0u, |
409 FILE_PATH_LITERAL("Unconfirmed "))); | 442 target_info->intermediate_path.BaseName().value().find( |
| 443 FILE_PATH_LITERAL("Unconfirmed "))); |
410 break; | 444 break; |
411 | 445 |
412 case EXPECT_LOCAL_PATH: | 446 case EXPECT_LOCAL_PATH: |
413 EXPECT_EQ(expected_local_path.value(), intermediate_path.value()); | 447 EXPECT_EQ(expected_local_path.value(), |
| 448 target_info->intermediate_path.value()); |
414 break; | 449 break; |
415 } | 450 } |
416 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | |
417 } | 451 } |
418 | 452 |
419 // static | 453 // static |
420 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath( | 454 void MockDownloadTargetDeterminerDelegate::NullReserveVirtualPath( |
421 DownloadItem* download, | 455 DownloadItem* download, |
422 const base::FilePath& virtual_path, | 456 const base::FilePath& virtual_path, |
423 bool create_directory, | 457 bool create_directory, |
424 DownloadPathReservationTracker::FilenameConflictAction conflict_action, | 458 DownloadPathReservationTracker::FilenameConflictAction conflict_action, |
425 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { | 459 const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) { |
426 callback.Run(virtual_path, true); | 460 callback.Run(virtual_path, true); |
(...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1697 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) | 1731 EXPECT_CALL(*delegate(), NotifyExtensions(_, _, _)) |
1698 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); | 1732 .Times(test_case.test_type == AUTOMATIC ? 1 : 0); |
1699 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); | 1733 EXPECT_CALL(*delegate(), ReserveVirtualPath(_, expected_path, false, _, _)); |
1700 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)); | 1734 EXPECT_CALL(*delegate(), PromptUserForDownloadPath(_, expected_path, _)); |
1701 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); | 1735 EXPECT_CALL(*delegate(), DetermineLocalPath(_, expected_path, _)); |
1702 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); | 1736 EXPECT_CALL(*delegate(), CheckDownloadUrl(_, expected_path, _)); |
1703 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); | 1737 RunTestCase(test_case, GetPathInDownloadDir(kInitialPath), item.get()); |
1704 } | 1738 } |
1705 } | 1739 } |
1706 | 1740 |
1707 // Used with TargetDeterminer_IntermediateNameForResumed test. Verifies that | |
1708 // |intermediate_path| == |expected_intermediate_path| if the latter is | |
1709 // non-empty. | |
1710 void IntermediatePathVerifier( | |
1711 const base::FilePath& expected_intermediate_path, | |
1712 const content::DownloadTargetCallback& callback, | |
1713 const base::FilePath& target_path, | |
1714 content::DownloadItem::TargetDisposition disposition, | |
1715 content::DownloadDangerType danger_type, | |
1716 const base::FilePath& intermediate_path) { | |
1717 if (!expected_intermediate_path.empty()) | |
1718 EXPECT_EQ(expected_intermediate_path, intermediate_path); | |
1719 callback.Run(target_path, disposition, danger_type, intermediate_path); | |
1720 } | |
1721 | |
1722 // Test intermediate filename generation for resumed downloads. | 1741 // Test intermediate filename generation for resumed downloads. |
1723 TEST_F(DownloadTargetDeterminerTest, | 1742 TEST_F(DownloadTargetDeterminerTest, |
1724 TargetDeterminer_IntermediateNameForResumed) { | 1743 TargetDeterminer_IntermediateNameForResumed) { |
1725 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital | 1744 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
1726 // path. | 1745 // path. |
1727 const base::FilePath::CharType kInitialPath[] = | 1746 const base::FilePath::CharType kInitialPath[] = |
1728 FILE_PATH_LITERAL("some_path/bar.txt"); | 1747 FILE_PATH_LITERAL("some_path/bar.txt"); |
1729 | 1748 |
1730 struct IntermediateNameTestCase { | 1749 struct IntermediateNameTestCase { |
1731 // General test case settings. | 1750 // General test case settings. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 | 1867 |
1849 ON_CALL(*item.get(), GetLastReason()) | 1868 ON_CALL(*item.get(), GetLastReason()) |
1850 .WillByDefault(Return( | 1869 .WillByDefault(Return( |
1851 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); | 1870 content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED)); |
1852 ON_CALL(*item.get(), GetFullPath()) | 1871 ON_CALL(*item.get(), GetFullPath()) |
1853 .WillByDefault(ReturnRefOfCopy( | 1872 .WillByDefault(ReturnRefOfCopy( |
1854 GetPathInDownloadDir(test_case.initial_intermediate_path))); | 1873 GetPathInDownloadDir(test_case.initial_intermediate_path))); |
1855 ON_CALL(*item.get(), GetDangerType()) | 1874 ON_CALL(*item.get(), GetDangerType()) |
1856 .WillByDefault(Return(test_case.general.expected_danger_type)); | 1875 .WillByDefault(Return(test_case.general.expected_danger_type)); |
1857 | 1876 |
1858 base::WeakPtrFactory<DownloadTargetDeterminerTest> factory(this); | 1877 scoped_ptr<DownloadTargetInfo> target_info = |
1859 base::RunLoop run_loop; | 1878 RunDownloadTargetDeterminer(GetPathInDownloadDir(kInitialPath), |
1860 content::DownloadTargetCallback verifier_callback = | 1879 item.get()); |
1861 base::Bind(&DownloadTargetDeterminerTest::DownloadTargetVerifier, | 1880 VerifyDownloadTarget(test_case.general, target_info.get()); |
1862 factory.GetWeakPtr(), | 1881 base::FilePath expected_intermediate_path = |
1863 run_loop.QuitClosure(), | 1882 GetPathInDownloadDir(test_case.expected_intermediate_path); |
1864 test_case.general); | 1883 if (!expected_intermediate_path.empty()) |
1865 content::DownloadTargetCallback test_callback = | 1884 EXPECT_EQ(expected_intermediate_path, target_info->intermediate_path); |
1866 base::Bind(&IntermediatePathVerifier, | 1885 } |
1867 GetPathInDownloadDir(test_case.expected_intermediate_path), | 1886 } |
1868 verifier_callback); | 1887 |
1869 DownloadTargetDeterminer::Start(item.get(), | 1888 // Test MIME type determination based on the target filename. |
1870 GetPathInDownloadDir(kInitialPath), | 1889 TEST_F(DownloadTargetDeterminerTest, |
1871 download_prefs(), | 1890 TargetDeterminer_MIMETypeDetermination) { |
1872 delegate(), | 1891 // All test cases run with GetPathInDownloadDir(kInitialPath) as the inital |
1873 test_callback); | 1892 // path. |
1874 run_loop.Run(); | 1893 const base::FilePath::CharType kInitialPath[] = |
1875 ::testing::Mock::VerifyAndClearExpectations(delegate()); | 1894 FILE_PATH_LITERAL("some_path/bar.txt"); |
1876 } | 1895 |
1877 } | 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 |
1878 | 2246 |
1879 } // namespace | 2247 } // namespace |
OLD | NEW |