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

Side by Side Diff: chrome/browser/download/chrome_download_manager_delegate_unittest.cc

Issue 14773004: Move download filename determination into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/file_util.h"
6 #include "base/files/file_path.h" 5 #include "base/files/file_path.h"
7 #include "base/files/scoped_temp_dir.h" 6 #include "base/files/scoped_temp_dir.h"
8 #include "base/message_loop.h" 7 #include "base/message_loop.h"
9 #include "base/observer_list.h"
10 #include "base/prefs/pref_service.h" 8 #include "base/prefs/pref_service.h"
11 #include "base/stl_util.h" 9 #include "base/run_loop.h"
12 #include "base/string_util.h"
13 #include "base/value_conversions.h"
14 #include "chrome/browser/download/chrome_download_manager_delegate.h" 10 #include "chrome/browser/download/chrome_download_manager_delegate.h"
15 #include "chrome/browser/download/download_prefs.h" 11 #include "chrome/browser/download/download_prefs.h"
16 #include "chrome/browser/download/download_util.h"
17 #include "chrome/browser/safe_browsing/download_protection_service.h"
18 #include "chrome/common/extensions/extension.h"
19 #include "chrome/common/pref_names.h" 12 #include "chrome/common/pref_names.h"
20 #include "chrome/test/base/chrome_render_view_host_test_harness.h" 13 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
21 #include "chrome/test/base/testing_pref_service_syncable.h" 14 #include "chrome/test/base/testing_pref_service_syncable.h"
22 #include "chrome/test/base/testing_profile.h" 15 #include "chrome/test/base/testing_profile.h"
23 #include "content/public/browser/web_contents.h" 16 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_contents_delegate.h" 17 #include "content/public/browser/web_contents_delegate.h"
25 #include "content/public/test/mock_download_item.h" 18 #include "content/public/test/mock_download_item.h"
26 #include "content/public/test/mock_download_manager.h" 19 #include "content/public/test/mock_download_manager.h"
27 #include "content/public/test/test_browser_thread.h" 20 #include "content/public/test/test_browser_thread.h"
28 #include "content/public/test/test_renderer_host.h" 21 #include "content/public/test/test_renderer_host.h"
29 #include "content/public/test/web_contents_tester.h" 22 #include "content/public/test/web_contents_tester.h"
30 #include "testing/gmock/include/gmock/gmock.h" 23 #include "testing/gmock/include/gmock/gmock.h"
31 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
32 25
33 using ::testing::AtMost; 26 using ::testing::AtMost;
34 using ::testing::Invoke; 27 using ::testing::Invoke;
35 using ::testing::Ref; 28 using ::testing::Ref;
36 using ::testing::Return; 29 using ::testing::Return;
37 using ::testing::ReturnPointee; 30 using ::testing::ReturnPointee;
38 using ::testing::ReturnRef; 31 using ::testing::ReturnRef;
39 using ::testing::ReturnRefOfCopy; 32 using ::testing::ReturnRefOfCopy;
40 using ::testing::SetArgPointee; 33 using ::testing::SetArgPointee;
41 using ::testing::WithArg; 34 using ::testing::WithArg;
42 using ::testing::_; 35 using ::testing::_;
43 using content::DownloadItem; 36 using content::DownloadItem;
44 using safe_browsing::DownloadProtectionService;
45 37
46 namespace { 38 namespace {
47 39
48 class MockWebContentsDelegate : public content::WebContentsDelegate { 40 class MockWebContentsDelegate : public content::WebContentsDelegate {
49 public: 41 public:
50 virtual ~MockWebContentsDelegate() {} 42 virtual ~MockWebContentsDelegate() {}
51 }; 43 };
52 44
53 // Google Mock action that posts a task to the current message loop that invokes 45 // Google Mock action that posts a task to the current message loop that invokes
54 // the first argument of the mocked method as a callback. Said argument must be 46 // the first argument of the mocked method as a callback. Said argument must be
55 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is 47 // a base::Callback<void(ParamType)>. |result| must be of |ParamType| and is
56 // bound as that parameter. 48 // bound as that parameter.
57 // Example: 49 // Example:
58 // class FooClass { 50 // class FooClass {
59 // public: 51 // public:
60 // virtual void Foo(base::Callback<void(bool)> callback); 52 // virtual void Foo(base::Callback<void(bool)> callback);
61 // }; 53 // };
62 // ... 54 // ...
63 // EXPECT_CALL(mock_fooclass_instance, Foo(callback)) 55 // EXPECT_CALL(mock_fooclass_instance, Foo(callback))
64 // .WillOnce(ScheduleCallback(false)); 56 // .WillOnce(ScheduleCallback(false));
65 ACTION_P(ScheduleCallback, result) { 57 ACTION_P(ScheduleCallback, result) {
66 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result)); 58 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(arg0, result));
67 } 59 }
68 60
69 // Used with DownloadTestCase. Indicates the type of test case. The expectations 61 // Similar to ScheduleCallback, but binds 2 arguments.
70 // for the test is set based on the type. 62 ACTION_P2(ScheduleCallback2, result0, result1) {
71 enum TestCaseType { 63 MessageLoop::current()->PostTask(
72 SAVE_AS, 64 FROM_HERE, base::Bind(arg0, result0, result1));
73 AUTOMATIC, 65 }
74 FORCED // Requires that forced_file_path be non-empty. 66
67 struct DownloadTarget {
68 base::FilePath target_path;
69 base::FilePath intermediate_path;
70 DownloadItem::TargetDisposition target_disposition;
71 content::DownloadDangerType danger_type;
75 }; 72 };
76 73
77 // Used with DownloadTestCase. Indicates whether the a file should be
78 // overwritten.
79 enum TestCaseExpectOverwrite {
80 EXPECT_OVERWRITE,
81 EXPECT_NO_OVERWRITE
82 };
83
84 // Used with DownloadTestCase. Type of intermediate filename to expect.
85 enum TestCaseExpectIntermediate {
86 EXPECT_CRDOWNLOAD, // Expect path/to/target.crdownload.
87 EXPECT_UNCONFIRMED, // Expect path/to/Unconfirmed xxx.crdownload.
88 EXPECT_TARGET_PATH, // Expect target path.
89 };
90
91 // Typical download test case. Used with
92 // ChromeDownloadManagerDelegateTest::RunTestCase().
93 struct DownloadTestCase {
94 // Type of test.
95 TestCaseType test_type;
96
97 // The |danger_type| is the expected danger type for the download as
98 // determined by CDMD. This value is also used to determine the behavior of
99 // DownloadProtectionService::IsSupportedDownload(), CDMD::CheckDownloadUrl()
100 // as necessary for flagging the download with as a dangerous download of type
101 // |danger_type|.
102 content::DownloadDangerType danger_type;
103
104 // Value of DownloadItem::GetURL()
105 const char* url;
106
107 // Value of DownloadItem::GetMimeType()
108 const char* mime_type;
109
110 // Should be non-empty if |test_type| == FORCED. Value of GetForcedFilePath().
111 const base::FilePath::CharType* forced_file_path;
112
113 // Expected final download path. Specified relative to the test download path.
114 // If the user is presented with a file chooser, this path will also be the
115 // response sent back from the file chooser.
116 const base::FilePath::CharType* expected_target_path;
117
118 // The path to expect as the suggested path if the user will be prompted for a
119 // download path.
120 const base::FilePath::CharType* expected_prompt_path;
121
122 // Expected target disposition. If this is TARGET_DISPOSITION_PROMPT, then the
123 // test run will expect ChromeDownloadManagerDelegate to prompt the user for a
124 // download location.
125 DownloadItem::TargetDisposition expected_disposition;
126
127 // Type of intermediate path to expect.
128 TestCaseExpectIntermediate expected_intermediate;
129 };
130
131 #if defined(FULL_SAFE_BROWSING)
132 // DownloadProtectionService with mock methods. Since the SafeBrowsingService is
133 // set to NULL, it is not safe to call any non-mocked methods other than
134 // SetEnabled() and enabled().
135 class TestDownloadProtectionService
136 : public safe_browsing::DownloadProtectionService {
137 public:
138 TestDownloadProtectionService()
139 : safe_browsing::DownloadProtectionService(NULL, NULL) {}
140 MOCK_METHOD2(CheckClientDownload,
141 void(content::DownloadItem*,
142 const DownloadProtectionService::CheckDownloadCallback&));
143 MOCK_METHOD2(CheckDownloadUrl,
144 void(const content::DownloadItem&,
145 const DownloadProtectionService::CheckDownloadCallback&));
146 MOCK_CONST_METHOD2(IsSupportedDownload,
147 bool(const content::DownloadItem&,
148 const base::FilePath&));
149 };
150 #endif
151
152 // Subclass of the ChromeDownloadManagerDelegate that uses a mock 74 // Subclass of the ChromeDownloadManagerDelegate that uses a mock
153 // DownloadProtectionService and IsDangerousFile. 75 // DownloadProtectionService.
154 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate { 76 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
155 public: 77 public:
156 explicit TestChromeDownloadManagerDelegate(Profile* profile) 78 explicit TestChromeDownloadManagerDelegate(Profile* profile)
157 : ChromeDownloadManagerDelegate(profile) { 79 : ChromeDownloadManagerDelegate(profile) {
158 #if defined(FULL_SAFE_BROWSING)
159 download_protection_service_.reset(new TestDownloadProtectionService());
160 download_protection_service_->SetEnabled(true);
161 #endif
162 } 80 }
163 81
164 virtual safe_browsing::DownloadProtectionService* 82 virtual safe_browsing::DownloadProtectionService*
165 GetDownloadProtectionService() OVERRIDE { 83 GetDownloadProtectionService() OVERRIDE {
166 #if defined(FULL_SAFE_BROWSING)
167 return download_protection_service_.get();
168 #else
169 return NULL; 84 return NULL;
170 #endif
171 } 85 }
172 86
173 virtual bool IsDangerousFile(const DownloadItem& download, 87 virtual void NotifyExtensions(
174 const base::FilePath& suggested_path, 88 content::DownloadItem* download,
175 bool visited_referrer_before) OVERRIDE { 89 const base::FilePath& suggested_virtual_path,
176 // The implementaion of ChromeDownloadManagerDelegate::IsDangerousFile() is 90 const NotifyExtensionsCallback& callback) OVERRIDE {
177 // sensitive to a number of external factors (e.g. whether off-store 91 callback.Run(base::FilePath(),
178 // extension installs are allowed, whether a given extension download is 92 DownloadPathReservationTracker::UNIQUIFY);
179 // approved, whether the user wants files of a given type to be opened
180 // automatically etc...). We should test these specifically, but for other
181 // tests, we keep the IsDangerousFile() test simple so as not to make the
182 // tests flaky.
183 return suggested_path.MatchesExtension(FILE_PATH_LITERAL(".jar")) ||
184 suggested_path.MatchesExtension(FILE_PATH_LITERAL(".exe"));
185 } 93 }
186 94
187 virtual void GetReservedPath( 95 virtual void ReserveVirtualPath(
188 content::DownloadItem& download, 96 content::DownloadItem* download,
189 const base::FilePath& target_path, 97 const base::FilePath& target_path,
190 const base::FilePath& default_download_path,
191 DownloadPathReservationTracker::FilenameConflictAction conflict_action, 98 DownloadPathReservationTracker::FilenameConflictAction conflict_action,
192 const DownloadPathReservationTracker::ReservedPathCallback& callback) 99 const DownloadPathReservationTracker::ReservedPathCallback& callback)
193 OVERRIDE { 100 OVERRIDE {
194 // Pretend the path reservation succeeded without any change to 101 // Pretend the path reservation succeeded without any change to
195 // |target_path|. 102 // |target_path|.
196 MessageLoop::current()->PostTask(FROM_HERE, 103 MessageLoop::current()->PostTask(FROM_HERE,
197 base::Bind(callback, target_path, true)); 104 base::Bind(callback, target_path, true));
198 } 105 }
199 106
200 // During tests, we want to mock the behavior of this method. 107 virtual void PromptUserForDownloadPath(
201 MOCK_METHOD3(ChooseDownloadPath, 108 DownloadItem* download,
202 void(content::DownloadItem*, 109 const base::FilePath& suggested_path,
203 const base::FilePath&, 110 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback)
204 const FileSelectedCallback&)); 111 OVERRIDE {
112 base::FilePath return_path = MockPromptUserForDownloadPath(download,
113 suggested_path,
114 callback);
115 OnDownloadPathSelected(callback, return_path);
116 }
205 117
206 #if defined(FULL_SAFE_BROWSING) 118 MOCK_METHOD3(
207 // A TestDownloadProtectionService* is convenient for setting up mocks. 119 MockPromptUserForDownloadPath,
208 TestDownloadProtectionService* test_download_protection_service() { 120 base::FilePath(
209 return download_protection_service_.get(); 121 content::DownloadItem*,
210 } 122 const base::FilePath&,
211 #endif 123 const DownloadTargetDeterminerDelegate::FileSelectedCallback&));
212 124
213 private: 125 private:
214 ~TestChromeDownloadManagerDelegate() {} 126 ~TestChromeDownloadManagerDelegate() {}
215
216 #if defined(FULL_SAFE_BROWSING)
217 scoped_ptr<TestDownloadProtectionService> download_protection_service_;
218 #endif
219 }; 127 };
220 128
221 class ChromeDownloadManagerDelegateTest : 129 class ChromeDownloadManagerDelegateTest :
222 public ChromeRenderViewHostTestHarness { 130 public ChromeRenderViewHostTestHarness {
223 public: 131 public:
224 ChromeDownloadManagerDelegateTest(); 132 ChromeDownloadManagerDelegateTest();
225 133
226 // ::testing::Test 134 // ::testing::Test
227 virtual void SetUp() OVERRIDE; 135 virtual void SetUp() OVERRIDE;
228 virtual void TearDown() OVERRIDE; 136 virtual void TearDown() OVERRIDE;
229 137
230 // Verifies and clears test expectations for |delegate_| and 138 // Verifies and clears test expectations for |delegate_| and
231 // |download_manager_|. 139 // |download_manager_|.
232 void VerifyAndClearExpectations(); 140 void VerifyAndClearExpectations();
233 141
234 // Creates MockDownloadItem and sets up default expectations. 142 // Creates MockDownloadItem and sets up default expectations.
235 content::MockDownloadItem* CreateActiveDownloadItem(int32 id); 143 content::MockDownloadItem* CreateActiveDownloadItem(int32 id);
236 144
237 // Sets the AutoOpenBasedOnExtension user preference for |path|.
238 void EnableAutoOpenBasedOnExtension(const base::FilePath& path);
239
240 // Given the relative path |path|, returns the full path under the temporary 145 // Given the relative path |path|, returns the full path under the temporary
241 // downloads directory. 146 // downloads directory.
242 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); 147 base::FilePath GetPathInDownloadDir(const char* path);
243
244 // Run |test_case| using |item|.
245 void RunTestCaseWithDownloadItem(const DownloadTestCase& test_case,
246 content::MockDownloadItem* item);
247
248 // Run through |test_case_count| tests in |test_cases|. A new MockDownloadItem
249 // will be created for each test case and destroyed when the test case is
250 // complete.
251 void RunTestCases(const DownloadTestCase test_cases[],
252 size_t test_case_count);
253 148
254 // Set the kDownloadDefaultDirectory user preference to |path|. 149 // Set the kDownloadDefaultDirectory user preference to |path|.
255 void SetDefaultDownloadPath(const base::FilePath& path); 150 void SetDefaultDownloadPath(const base::FilePath& path);
256 151
257 // Set the kDownloadDefaultDirectory managed preference to |path|. 152 void DetermineDownloadTarget(DownloadItem* download,
258 void SetManagedDownloadPath(const base::FilePath& path); 153 DownloadTarget* result);
259
260 // Set the kPromptForDownload user preference to |prompt|.
261 void SetPromptForDownload(bool prompt);
262 154
263 const base::FilePath& default_download_path() const; 155 const base::FilePath& default_download_path() const;
264 TestChromeDownloadManagerDelegate* delegate(); 156 TestChromeDownloadManagerDelegate* delegate();
265 content::MockDownloadManager* download_manager(); 157 content::MockDownloadManager* download_manager();
266 DownloadPrefs* download_prefs(); 158 DownloadPrefs* download_prefs();
267 159
268 private: 160 private:
269 // Verifies that |target_path|, |disposition|, |danger_type| and 161 void OnDownloadTargetDone(DownloadTarget* result,
270 // |intermediate_path| matches the expectations of |test_case|. 162 const base::FilePath& target_path,
271 void DownloadTargetVerifier(const DownloadTestCase* test_case, 163 DownloadItem::TargetDisposition disposition,
272 const base::FilePath& target_path, 164 content::DownloadDangerType danger_type,
273 DownloadItem::TargetDisposition disposition, 165 const base::FilePath& intermediate_path);
274 content::DownloadDangerType danger_type,
275 const base::FilePath& intermediate_path);
276 166
277 TestingPrefServiceSyncable* pref_service_; 167 TestingPrefServiceSyncable* pref_service_;
278 base::ScopedTempDir test_download_dir_; 168 base::ScopedTempDir test_download_dir_;
279 content::TestBrowserThread ui_thread_; 169 content::TestBrowserThread ui_thread_;
280 content::TestBrowserThread file_thread_; 170 content::TestBrowserThread file_thread_;
281 scoped_refptr<content::MockDownloadManager> download_manager_; 171 scoped_refptr<content::MockDownloadManager> download_manager_;
282 scoped_refptr<TestChromeDownloadManagerDelegate> delegate_; 172 scoped_refptr<TestChromeDownloadManagerDelegate> delegate_;
283 MockWebContentsDelegate web_contents_delegate_; 173 MockWebContentsDelegate web_contents_delegate_;
284 }; 174 };
285 175
286 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest() 176 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest()
287 : ChromeRenderViewHostTestHarness(), 177 : ChromeRenderViewHostTestHarness(),
288 ui_thread_(content::BrowserThread::UI, &message_loop_), 178 ui_thread_(content::BrowserThread::UI, &message_loop_),
289 file_thread_(content::BrowserThread::FILE, &message_loop_), 179 file_thread_(content::BrowserThread::FILE, &message_loop_),
290 download_manager_(new content::MockDownloadManager) { 180 download_manager_(new ::testing::NiceMock<content::MockDownloadManager>) {
291 EXPECT_CALL(*download_manager_, GetAllDownloads(_)).WillRepeatedly(Return());
292 EXPECT_CALL(*download_manager_, AddObserver(_)).WillRepeatedly(Return());
293 EXPECT_CALL(*download_manager_, RemoveObserver(_)).WillRepeatedly(Return());
294 } 181 }
295 182
296 void ChromeDownloadManagerDelegateTest::SetUp() { 183 void ChromeDownloadManagerDelegateTest::SetUp() {
297 ChromeRenderViewHostTestHarness::SetUp(); 184 ChromeRenderViewHostTestHarness::SetUp();
298 185
299 CHECK(profile()); 186 CHECK(profile());
300 delegate_ = new TestChromeDownloadManagerDelegate(profile()); 187 delegate_ = new TestChromeDownloadManagerDelegate(profile());
301 EXPECT_CALL(*download_manager_.get(), GetAllDownloads(_))
302 .WillRepeatedly(Return());
303 EXPECT_CALL(*download_manager_.get(), AddObserver(_))
304 .WillRepeatedly(Return());
305 delegate_->SetDownloadManager(download_manager_.get()); 188 delegate_->SetDownloadManager(download_manager_.get());
306 pref_service_ = profile()->GetTestingPrefService(); 189 pref_service_ = profile()->GetTestingPrefService();
307 web_contents()->SetDelegate(&web_contents_delegate_); 190 web_contents()->SetDelegate(&web_contents_delegate_);
308 191
309 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); 192 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
310 SetDefaultDownloadPath(test_download_dir_.path()); 193 SetDefaultDownloadPath(test_download_dir_.path());
311 } 194 }
312 195
313 void ChromeDownloadManagerDelegateTest::TearDown() { 196 void ChromeDownloadManagerDelegateTest::TearDown() {
314 message_loop_.RunUntilIdle(); 197 message_loop_.RunUntilIdle();
315 delegate_->Shutdown(); 198 delegate_->Shutdown();
316 ChromeRenderViewHostTestHarness::TearDown(); 199 ChromeRenderViewHostTestHarness::TearDown();
317 } 200 }
318 201
319 void ChromeDownloadManagerDelegateTest::VerifyAndClearExpectations() { 202 void ChromeDownloadManagerDelegateTest::VerifyAndClearExpectations() {
320 ::testing::Mock::VerifyAndClearExpectations(delegate_); 203 ::testing::Mock::VerifyAndClearExpectations(delegate_);
321 ::testing::Mock::VerifyAndClearExpectations(download_manager_);
322 EXPECT_CALL(*download_manager_, RemoveObserver(_)).WillRepeatedly(Return());
323 EXPECT_CALL(*download_manager_, GetAllDownloads(_))
324 .WillRepeatedly(Return());
325 } 204 }
326 205
327 content::MockDownloadItem* 206 content::MockDownloadItem*
328 ChromeDownloadManagerDelegateTest::CreateActiveDownloadItem(int32 id) { 207 ChromeDownloadManagerDelegateTest::CreateActiveDownloadItem(int32 id) {
329 content::MockDownloadItem* item = 208 content::MockDownloadItem* item =
330 new ::testing::NiceMock<content::MockDownloadItem>(); 209 new ::testing::NiceMock<content::MockDownloadItem>();
210 ON_CALL(*item, GetBrowserContext())
211 .WillByDefault(Return(profile()));
212 ON_CALL(*item, GetDangerType())
213 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
214 ON_CALL(*item, GetForcedFilePath())
215 .WillByDefault(ReturnRefOfCopy(base::FilePath()));
331 ON_CALL(*item, GetFullPath()) 216 ON_CALL(*item, GetFullPath())
332 .WillByDefault(ReturnRefOfCopy(base::FilePath())); 217 .WillByDefault(ReturnRefOfCopy(base::FilePath()));
333 ON_CALL(*item, GetHash()) 218 ON_CALL(*item, GetHash())
334 .WillByDefault(ReturnRefOfCopy(std::string())); 219 .WillByDefault(ReturnRefOfCopy(std::string()));
220 ON_CALL(*item, GetId())
221 .WillByDefault(Return(id));
335 ON_CALL(*item, GetReferrerUrl()) 222 ON_CALL(*item, GetReferrerUrl())
336 .WillByDefault(ReturnRefOfCopy(GURL())); 223 .WillByDefault(ReturnRefOfCopy(GURL()));
224 ON_CALL(*item, GetState())
225 .WillByDefault(Return(DownloadItem::IN_PROGRESS));
337 ON_CALL(*item, GetTransitionType()) 226 ON_CALL(*item, GetTransitionType())
338 .WillByDefault(Return(content::PAGE_TRANSITION_LINK)); 227 .WillByDefault(Return(content::PAGE_TRANSITION_LINK));
228 ON_CALL(*item, GetWebContents())
229 .WillByDefault(Return(web_contents()));
339 ON_CALL(*item, HasUserGesture()) 230 ON_CALL(*item, HasUserGesture())
340 .WillByDefault(Return(false)); 231 .WillByDefault(Return(false));
341 ON_CALL(*item, IsDangerous()) 232 ON_CALL(*item, IsDangerous())
342 .WillByDefault(Return(false)); 233 .WillByDefault(Return(false));
234 ON_CALL(*item, IsInProgress())
235 .WillByDefault(Return(true));
343 ON_CALL(*item, IsTemporary()) 236 ON_CALL(*item, IsTemporary())
344 .WillByDefault(Return(false)); 237 .WillByDefault(Return(false));
345 ON_CALL(*item, GetWebContents())
346 .WillByDefault(Return(web_contents()));
347 EXPECT_CALL(*item, GetId())
348 .WillRepeatedly(Return(id));
349 EXPECT_CALL(*item, GetState())
350 .WillRepeatedly(Return(DownloadItem::IN_PROGRESS));
351 EXPECT_CALL(*item, AddObserver(_)).WillRepeatedly(Return());
352 EXPECT_CALL(*item, RemoveObserver(_)).WillRepeatedly(Return());
353 EXPECT_CALL(*download_manager_, GetDownload(id)) 238 EXPECT_CALL(*download_manager_, GetDownload(id))
354 .WillRepeatedly(Return(item)); 239 .WillRepeatedly(Return(item));
355 return item; 240 return item;
356 } 241 }
357 242
358 void ChromeDownloadManagerDelegateTest::EnableAutoOpenBasedOnExtension(
359 const base::FilePath& path) {
360 EXPECT_TRUE(
361 delegate_->download_prefs()->EnableAutoOpenBasedOnExtension(path));
362 }
363
364 base::FilePath ChromeDownloadManagerDelegateTest::GetPathInDownloadDir( 243 base::FilePath ChromeDownloadManagerDelegateTest::GetPathInDownloadDir(
365 const base::FilePath::StringType& relative_path) { 244 const char* relative_path) {
366 if (relative_path.empty()) 245 base::FilePath full_path =
367 return base::FilePath(); 246 test_download_dir_.path().AppendASCII(relative_path);
368 base::FilePath full_path(test_download_dir_.path().Append(relative_path));
369 return full_path.NormalizePathSeparators(); 247 return full_path.NormalizePathSeparators();
370 } 248 }
371 249
372 void ChromeDownloadManagerDelegateTest::RunTestCaseWithDownloadItem(
373 const DownloadTestCase& test_case,
374 content::MockDownloadItem* item) {
375 // SetUp DownloadItem
376 GURL download_url(test_case.url);
377 std::vector<GURL> url_chain;
378 url_chain.push_back(download_url);
379 base::FilePath forced_file_path(
380 GetPathInDownloadDir(test_case.forced_file_path));
381 EXPECT_CALL(*item, GetURL())
382 .WillRepeatedly(ReturnRef(download_url));
383 EXPECT_CALL(*item, GetUrlChain())
384 .WillRepeatedly(ReturnRef(url_chain));
385 EXPECT_CALL(*item, GetForcedFilePath())
386 .WillRepeatedly(ReturnRef(forced_file_path));
387 EXPECT_CALL(*item, GetMimeType())
388 .WillRepeatedly(Return(test_case.mime_type));
389 std::vector<DownloadItem*> items;
390 items.push_back(item);
391 EXPECT_CALL(*download_manager_, GetAllDownloads(_))
392 .WillRepeatedly(SetArgPointee<0>(items));
393
394 #if defined(FULL_SAFE_BROWSING)
395 // Results of SafeBrowsing URL check.
396 DownloadProtectionService::DownloadCheckResult url_check_result =
397 (test_case.danger_type == content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL) ?
398 DownloadProtectionService::DANGEROUS :
399 DownloadProtectionService::SAFE;
400 EXPECT_CALL(*delegate_->test_download_protection_service(),
401 CheckDownloadUrl(Ref(*item), _))
402 .WillOnce(WithArg<1>(ScheduleCallback(url_check_result)));
403
404 // Downloads that are flagged as DANGEROUS_URL aren't checked for dangerous
405 // content. So we never end up calling IsSupportedDownload for them.
406 if (test_case.danger_type != content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL) {
407 bool maybe_dangerous =
408 (test_case.danger_type ==
409 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT);
410 EXPECT_CALL(*delegate_->test_download_protection_service(),
411 IsSupportedDownload(Ref(*item), _))
412 .WillOnce(Return(maybe_dangerous));
413 }
414 #else // FULL_SAFE_BROWSING
415 // If safe browsing is not enabled, then these tests would fail. If such a
416 // test was added, then fail early.
417 EXPECT_NE(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL, test_case.danger_type);
418 EXPECT_NE(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
419 test_case.danger_type);
420 #endif // !FULL_SAFE_BROWSING
421
422 DownloadItem::TargetDisposition initial_disposition =
423 (test_case.test_type == SAVE_AS) ?
424 DownloadItem::TARGET_DISPOSITION_PROMPT :
425 DownloadItem::TARGET_DISPOSITION_OVERWRITE;
426 EXPECT_CALL(*item, GetTargetFilePath())
427 .WillRepeatedly(ReturnRefOfCopy(base::FilePath()));
428 EXPECT_CALL(*item, GetTargetDisposition())
429 .WillRepeatedly(Return(initial_disposition));
430 EXPECT_CALL(*item, GetDangerType())
431 .WillRepeatedly(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
432
433 if (test_case.expected_disposition ==
434 DownloadItem::TARGET_DISPOSITION_PROMPT) {
435 base::FilePath expected_prompt_path = GetPathInDownloadDir(
436 test_case.expected_prompt_path);
437 base::FilePath expected_target_path = GetPathInDownloadDir(
438 test_case.expected_target_path);
439 EXPECT_CALL(*delegate_,
440 ChooseDownloadPath(item, expected_prompt_path, _))
441 .WillOnce(WithArg<2>(ScheduleCallback(expected_target_path)));
442 }
443
444 // Kick off the test.
445 base::WeakPtrFactory<ChromeDownloadManagerDelegateTest> factory(this);
446 EXPECT_TRUE(delegate_->DetermineDownloadTarget(
447 item,
448 base::Bind(&ChromeDownloadManagerDelegateTest::DownloadTargetVerifier,
449 factory.GetWeakPtr(), base::Unretained(&test_case))));
450 message_loop_.RunUntilIdle();
451 VerifyAndClearExpectations();
452 }
453
454 void ChromeDownloadManagerDelegateTest::RunTestCases(
455 const DownloadTestCase test_cases[],
456 size_t test_case_count) {
457 for (size_t i = 0; i < test_case_count; ++i) {
458 scoped_ptr<content::MockDownloadItem> item(CreateActiveDownloadItem(i));
459 SCOPED_TRACE(testing::Message() << "Running test case " << i);
460 RunTestCaseWithDownloadItem(test_cases[i], item.get());
461 }
462 }
463
464 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath( 250 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath(
465 const base::FilePath& path) { 251 const base::FilePath& path) {
466 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path); 252 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path);
467 } 253 }
468 254
469 void ChromeDownloadManagerDelegateTest::SetManagedDownloadPath( 255 void ChromeDownloadManagerDelegateTest::DetermineDownloadTarget(
470 const base::FilePath& path) { 256 DownloadItem* download_item,
471 pref_service_->SetManagedPref(prefs::kDownloadDefaultDirectory, 257 DownloadTarget* result) {
472 base::CreateFilePathValue(path)); 258 base::WeakPtrFactory<ChromeDownloadManagerDelegateTest> factory(this);
259 delegate()->DetermineDownloadTarget(
260 download_item,
261 base::Bind(&ChromeDownloadManagerDelegateTest::OnDownloadTargetDone,
262 factory.GetWeakPtr(), base::Unretained(result)));
263 base::RunLoop loop_runner;
264 loop_runner.RunUntilIdle();
473 } 265 }
474 266
475 void ChromeDownloadManagerDelegateTest::SetPromptForDownload(bool prompt) { 267 void ChromeDownloadManagerDelegateTest::OnDownloadTargetDone(
476 pref_service_->SetBoolean(prefs::kPromptForDownload, prompt); 268 DownloadTarget* result,
477 }
478
479 void ChromeDownloadManagerDelegateTest::DownloadTargetVerifier(
480 const DownloadTestCase* test_case,
481 const base::FilePath& target_path, 269 const base::FilePath& target_path,
482 DownloadItem::TargetDisposition disposition, 270 DownloadItem::TargetDisposition target_disposition,
483 content::DownloadDangerType danger_type, 271 content::DownloadDangerType danger_type,
484 const base::FilePath& intermediate_path) { 272 const base::FilePath& intermediate_path) {
485 base::FilePath expected_target_path( 273 result->target_path = target_path;
486 GetPathInDownloadDir(test_case->expected_target_path)); 274 result->intermediate_path = intermediate_path;
487 EXPECT_EQ(expected_target_path.value(), target_path.value()); 275 result->target_disposition = target_disposition;
488 EXPECT_EQ(test_case->expected_disposition, disposition); 276 result->danger_type = danger_type;
489 EXPECT_EQ(test_case->danger_type, danger_type);
490
491 switch (test_case->expected_intermediate) {
492 case EXPECT_CRDOWNLOAD:
493 EXPECT_EQ(download_util::GetCrDownloadPath(target_path).value(),
494 intermediate_path.value());
495 break;
496
497 case EXPECT_UNCONFIRMED:
498 // The paths (in English) look like: /path/Unconfirmed xxx.crdownload.
499 // Of this, we only check that the path is:
500 // 1. Not "/path/target.crdownload",
501 // 2. Points to the same directory as the target.
502 // 3. Has extension ".crdownload".
503 EXPECT_NE(download_util::GetCrDownloadPath(target_path).value(),
504 intermediate_path.value());
505 EXPECT_EQ(target_path.DirName().value(),
506 intermediate_path.DirName().value());
507 EXPECT_TRUE(intermediate_path.MatchesExtension(
508 FILE_PATH_LITERAL(".crdownload")));
509 break;
510
511 case EXPECT_TARGET_PATH:
512 EXPECT_EQ(target_path.value(), intermediate_path.value());
513 break;
514 }
515 } 277 }
516 278
517 const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path() 279 const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path()
518 const { 280 const {
519 return test_download_dir_.path(); 281 return test_download_dir_.path();
520 } 282 }
521 283
522 TestChromeDownloadManagerDelegate* 284 TestChromeDownloadManagerDelegate*
523 ChromeDownloadManagerDelegateTest::delegate() { 285 ChromeDownloadManagerDelegateTest::delegate() {
524 return delegate_.get(); 286 return delegate_.get();
525 } 287 }
526 288
527 content::MockDownloadManager* 289 content::MockDownloadManager*
528 ChromeDownloadManagerDelegateTest::download_manager() { 290 ChromeDownloadManagerDelegateTest::download_manager() {
529 return download_manager_.get(); 291 return download_manager_.get();
530 } 292 }
531 293
532 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() { 294 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() {
533 return delegate_->download_prefs(); 295 return delegate_->download_prefs();
534 } 296 }
535 297
536 } // namespace 298 } // namespace
537 299
538 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_Basic) {
539 const DownloadTestCase kBasicTestCases[] = {
540 {
541 // 0: Automatic Safe
542 AUTOMATIC,
543 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
544 "http://example.com/foo.txt", "text/plain",
545 FILE_PATH_LITERAL(""),
546
547 FILE_PATH_LITERAL("foo.txt"),
548 FILE_PATH_LITERAL(""),
549 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
550
551 EXPECT_CRDOWNLOAD
552 },
553
554 {
555 // 1: Save_As Safe
556 SAVE_AS,
557 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
558 "http://example.com/foo.txt", "text/plain",
559 FILE_PATH_LITERAL(""),
560
561 FILE_PATH_LITERAL("foo.txt"),
562 FILE_PATH_LITERAL("foo.txt"),
563 DownloadItem::TARGET_DISPOSITION_PROMPT,
564
565 EXPECT_CRDOWNLOAD
566 },
567
568 {
569 // 2: Automatic Dangerous
570 AUTOMATIC,
571 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
572 "http://example.com/foo.exe", "",
573 FILE_PATH_LITERAL(""),
574
575 FILE_PATH_LITERAL("foo.exe"),
576 FILE_PATH_LITERAL(""),
577 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
578
579 EXPECT_UNCONFIRMED
580 },
581
582 {
583 // 3 Forced Safe
584 FORCED,
585 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
586 "http://example.com/foo.txt", "",
587 FILE_PATH_LITERAL("forced-foo.txt"),
588
589 FILE_PATH_LITERAL("forced-foo.txt"),
590 FILE_PATH_LITERAL(""),
591 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
592
593 EXPECT_TARGET_PATH
594 },
595
596 #if defined(FULL_SAFE_BROWSING)
597 // These test cases are only applicable if safe browsing is enabled. Without
598 // it, these are equivalent to FORCED/SAFE and SAFE_AS/SAFE respectively.
599 {
600 // 4: Forced Dangerous. As above. .jar is considered to be one of the file
601 // types supportred by safe browsing.
602 FORCED,
603 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
604 "http://example.com/foo.exe", "",
605 FILE_PATH_LITERAL("forced-foo.exe"),
606
607 FILE_PATH_LITERAL("forced-foo.exe"),
608 FILE_PATH_LITERAL(""),
609 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
610
611 EXPECT_UNCONFIRMED
612 },
613
614 {
615 // 5: Save_As Dangerous.
616 SAVE_AS,
617 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
618 "http://example.com/foo.exe", "",
619 FILE_PATH_LITERAL(""),
620
621 FILE_PATH_LITERAL("foo.exe"),
622 FILE_PATH_LITERAL("foo.exe"),
623 DownloadItem::TARGET_DISPOSITION_PROMPT,
624
625 EXPECT_UNCONFIRMED
626 }
627 #endif
628 };
629
630 RunTestCases(kBasicTestCases, arraysize(kBasicTestCases));
631 }
632
633 #if defined(FULL_SAFE_BROWSING)
634 // The SafeBrowsing URL check is performed early. Make sure that a download item
635 // that has been marked as DANGEROUS_URL behaves correctly.
636 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_DangerousURL) {
637 const DownloadTestCase kDangerousURLTestCases[] = {
638 {
639 // 0: Automatic Dangerous URL
640 AUTOMATIC,
641 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
642 "http://phishing.example.com/foo.txt", "",
643 FILE_PATH_LITERAL(""),
644
645 FILE_PATH_LITERAL("foo.txt"),
646 FILE_PATH_LITERAL(""),
647 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
648
649 EXPECT_UNCONFIRMED
650 },
651
652 {
653 // 1: Save As Dangerous URL
654 SAVE_AS,
655 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
656 "http://phishing.example.com/foo.txt", "",
657 FILE_PATH_LITERAL(""),
658
659 FILE_PATH_LITERAL("foo.txt"),
660 FILE_PATH_LITERAL("foo.txt"),
661 DownloadItem::TARGET_DISPOSITION_PROMPT,
662
663 EXPECT_UNCONFIRMED
664 },
665
666 {
667 // 2: Forced Dangerous URL
668 FORCED,
669 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
670 "http://phishing.example.com/foo.txt", "",
671 FILE_PATH_LITERAL("forced-foo.txt"),
672
673 FILE_PATH_LITERAL("forced-foo.txt"),
674 FILE_PATH_LITERAL(""),
675 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
676
677 EXPECT_UNCONFIRMED
678 },
679
680 {
681 // 3: Automatic Dangerous URL + Dangerous file. Dangerous URL takes
682 // precendence.
683 AUTOMATIC,
684 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
685 "http://phishing.example.com/foo.jar", "",
686 FILE_PATH_LITERAL(""),
687
688 FILE_PATH_LITERAL("foo.jar"),
689 FILE_PATH_LITERAL(""),
690 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
691
692 EXPECT_UNCONFIRMED
693 },
694
695 {
696 // 4: Save As Dangerous URL + Dangerous file
697 SAVE_AS,
698 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
699 "http://phishing.example.com/foo.jar", "",
700 FILE_PATH_LITERAL(""),
701
702 FILE_PATH_LITERAL("foo.jar"),
703 FILE_PATH_LITERAL("foo.jar"),
704 DownloadItem::TARGET_DISPOSITION_PROMPT,
705
706 EXPECT_UNCONFIRMED
707 },
708
709 {
710 // 5: Forced Dangerous URL + Dangerous file
711 FORCED,
712 content::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL,
713 "http://phishing.example.com/foo.jar", "",
714 FILE_PATH_LITERAL("forced-foo.jar"),
715
716 FILE_PATH_LITERAL("forced-foo.jar"),
717 FILE_PATH_LITERAL(""),
718 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
719
720 EXPECT_UNCONFIRMED
721 },
722 };
723
724 RunTestCases(kDangerousURLTestCases, arraysize(kDangerousURLTestCases));
725 }
726 #endif // FULL_SAFE_BROWSING
727
728 // These test cases are run with "Prompt for download" user preference set to
729 // true. Even with the preference set, some of these downloads should not cause
730 // a prompt to appear.
731 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_PromptAlways) {
732 const DownloadTestCase kPromptingTestCases[] = {
733 {
734 // 0: Safe Automatic - Should prompt because of "Prompt for download"
735 // preference setting.
736 AUTOMATIC,
737 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
738 "http://example.com/foo.txt", "text/plain",
739 FILE_PATH_LITERAL(""),
740
741 FILE_PATH_LITERAL("foo.txt"),
742 FILE_PATH_LITERAL("foo.txt"),
743 DownloadItem::TARGET_DISPOSITION_PROMPT,
744
745 EXPECT_CRDOWNLOAD
746 },
747
748 {
749 // 1: Automatic Browser Extension download. - Shouldn't prompt for browser
750 // extension downloads even if "Prompt for download" preference is set.
751 AUTOMATIC,
752 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
753 "http://example.com/foo.crx",
754 extensions::Extension::kMimeType,
755 FILE_PATH_LITERAL(""),
756
757 FILE_PATH_LITERAL("foo.crx"),
758 FILE_PATH_LITERAL(""),
759 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
760
761 EXPECT_CRDOWNLOAD
762 },
763
764 {
765 // 2: Automatic User Script - Shouldn't prompt for user script downloads
766 // even if "Prompt for download" preference is set.
767 AUTOMATIC,
768 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
769 "http://example.com/foo.user.js", "",
770 FILE_PATH_LITERAL(""),
771
772 FILE_PATH_LITERAL("foo.user.js"),
773 FILE_PATH_LITERAL(""),
774 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
775
776 EXPECT_CRDOWNLOAD
777 },
778
779 {
780 // 3: Automatic - The filename extension is marked as one that we will
781 // open automatically. Shouldn't prompt.
782 AUTOMATIC,
783 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
784 "http://example.com/foo.dummy", "",
785 FILE_PATH_LITERAL(""),
786
787 FILE_PATH_LITERAL("foo.dummy"),
788 FILE_PATH_LITERAL(""),
789 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
790
791 EXPECT_CRDOWNLOAD
792 },
793
794 #if defined(FULL_SAFE_BROWSING)
795 // If safe browsing is disabled, this case is equivalent to AUTOMATIC/SAFE
796 // since the download isn't marked as dangerous when we are going to prompt
797 // the user.
798 {
799 // 4: Dangerous Automatic - Should prompt due to "Prompt for download"
800 // preference setting.
801 AUTOMATIC,
802 content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
803 "http://example.com/foo.exe", "",
804 FILE_PATH_LITERAL(""),
805
806 FILE_PATH_LITERAL("foo.exe"),
807 FILE_PATH_LITERAL("foo.exe"),
808 DownloadItem::TARGET_DISPOSITION_PROMPT,
809
810 EXPECT_UNCONFIRMED
811 },
812 #endif
813 };
814
815 SetPromptForDownload(true);
816 EnableAutoOpenBasedOnExtension(
817 base::FilePath(FILE_PATH_LITERAL("dummy.dummy")));
818 RunTestCases(kPromptingTestCases, arraysize(kPromptingTestCases));
819 }
820
821 // If the download path is managed, then we don't show any prompts.
822 // Note that if the download path is managed, then PromptForDownload() is false.
823 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_ManagedPath) {
824 const DownloadTestCase kManagedPathTestCases[] = {
825 {
826 // 0: Automatic Safe
827 AUTOMATIC,
828 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
829 "http://example.com/foo.txt", "text/plain",
830 FILE_PATH_LITERAL(""),
831
832 FILE_PATH_LITERAL("foo.txt"),
833 FILE_PATH_LITERAL(""),
834 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
835
836 EXPECT_CRDOWNLOAD
837 },
838
839 {
840 // 1: Save_As Safe
841 SAVE_AS,
842 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
843 "http://example.com/foo.txt", "text/plain",
844 FILE_PATH_LITERAL(""),
845
846 FILE_PATH_LITERAL("foo.txt"),
847 FILE_PATH_LITERAL(""),
848 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
849
850 EXPECT_CRDOWNLOAD
851 },
852 };
853
854 SetManagedDownloadPath(default_download_path());
855 ASSERT_TRUE(download_prefs()->IsDownloadPathManaged());
856 RunTestCases(kManagedPathTestCases, arraysize(kManagedPathTestCases));
857 }
858
859 // Test whether the last saved directory is saved if the user was presented with
860 // a file chooser.
861 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) { 300 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) {
862 const DownloadTestCase kLastSavePathTestCases[] = { 301 GURL download_url("http://example.com/foo.txt");
863 {
864 // Initially the last saved directory is the user's default download path.
865
866 // 0: Start a Save As download. Then respond to the file chooser with
867 // foo/bar.txt as the target directory. This should cause the foo/
868 // directory to be remembered as the last used save directory.
869 SAVE_AS,
870 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
871 "http://example.com/foo.txt", "text/plain",
872 FILE_PATH_LITERAL(""),
873
874 FILE_PATH_LITERAL("foo/bar.txt"),
875 FILE_PATH_LITERAL("foo.txt"),
876 DownloadItem::TARGET_DISPOSITION_PROMPT,
877
878 EXPECT_CRDOWNLOAD
879 },
880
881 {
882 // 1: Start another Save As download. This time the suggested path should
883 // be in the foo/ directory.
884 SAVE_AS,
885 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
886 "http://example.com/foo.txt", "text/plain",
887 FILE_PATH_LITERAL(""),
888
889 FILE_PATH_LITERAL("bar/foo.txt"),
890 FILE_PATH_LITERAL("foo/foo.txt"),
891 DownloadItem::TARGET_DISPOSITION_PROMPT,
892
893 EXPECT_CRDOWNLOAD
894 },
895
896 {
897 // 2: Start an automatic download. This should be saved to the user's
898 // default download directory and not the last used Save As directory.
899 AUTOMATIC,
900 content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
901 "http://example.com/foo.txt", "text/plain",
902 FILE_PATH_LITERAL(""),
903
904 FILE_PATH_LITERAL("foo.txt"),
905 FILE_PATH_LITERAL(""),
906 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
907
908 EXPECT_CRDOWNLOAD
909 },
910 };
911
912 RunTestCases(kLastSavePathTestCases, arraysize(kLastSavePathTestCases));
913
914 // Now clear the last download path.
915 delegate()->ClearLastDownloadPath(); 302 delegate()->ClearLastDownloadPath();
916 303
917 // Run the first test case again. Since the last download path was cleared, 304 scoped_ptr<content::MockDownloadItem> save_as_download(
918 // this test case should behave identically to the first time it was run. 305 CreateActiveDownloadItem(0));
919 RunTestCases(kLastSavePathTestCases, 1); 306 EXPECT_CALL(*save_as_download, GetURL())
307 .Times(::testing::AnyNumber())
308 .WillRepeatedly(ReturnRef(download_url));
309 EXPECT_CALL(*save_as_download, GetTargetDisposition())
310 .Times(::testing::AnyNumber())
311 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT));
312
313 scoped_ptr<content::MockDownloadItem> automatic_download(
314 CreateActiveDownloadItem(1));
315 EXPECT_CALL(*automatic_download, GetURL())
316 .Times(::testing::AnyNumber())
317 .WillRepeatedly(ReturnRef(download_url));
318 EXPECT_CALL(*automatic_download, GetTargetDisposition())
319 .Times(::testing::AnyNumber())
320 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE));
321
322 {
323 // When the prompt is displayed for the first download, the user selects a
324 // path in a different directory.
325 DownloadTarget result;
326 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt"));
327 base::FilePath user_selected_path(GetPathInDownloadDir("bar/baz.txt"));
328 EXPECT_CALL(*delegate(),
329 MockPromptUserForDownloadPath(save_as_download.get(),
330 expected_prompt_path, _))
331 .WillOnce(Return(user_selected_path));
332 DetermineDownloadTarget(save_as_download.get(), &result);
333 EXPECT_EQ(user_selected_path, result.target_path);
334 VerifyAndClearExpectations();
335 }
336
337 {
338 // The prompt path for the second download is the user selected directroy
339 // from the previous download.
340 DownloadTarget result;
341 base::FilePath expected_prompt_path(GetPathInDownloadDir("bar/foo.txt"));
342 EXPECT_CALL(*delegate(),
343 MockPromptUserForDownloadPath(save_as_download.get(),
344 expected_prompt_path, _))
345 .WillOnce(Return(base::FilePath()));
346 DetermineDownloadTarget(save_as_download.get(), &result);
347 VerifyAndClearExpectations();
348 }
349
350 {
351 // Start an automatic download. This one should get the default download
352 // path since the last download path only affects Save As downloads.
353 DownloadTarget result;
354 base::FilePath expected_path(GetPathInDownloadDir("foo.txt"));
355 DetermineDownloadTarget(automatic_download.get(), &result);
356 EXPECT_EQ(expected_path, result.target_path);
357 VerifyAndClearExpectations();
358 }
359
360 // Clear the last download path.
361 delegate()->ClearLastDownloadPath();
362
363 {
364 // The prompt path for the next download should be the default.
365 DownloadTarget result;
366 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt"));
367 EXPECT_CALL(*delegate(),
368 MockPromptUserForDownloadPath(save_as_download.get(),
369 expected_prompt_path, _))
370 .WillOnce(Return(base::FilePath()));
371 DetermineDownloadTarget(save_as_download.get(), &result);
372 VerifyAndClearExpectations();
373 }
920 } 374 }
921
922 // TODO(asanka): Add more tests.
923 // * Default download path is not writable.
924 // * Download path doesn't exist.
925 // * IsDangerousFile().
926 // * Filename generation.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698