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

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

Issue 12850002: Move download filename determintion into a separate class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View 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 ReserveVirtualPath(
174 const base::FilePath& suggested_path, 88 content::DownloadItem* download,
175 bool visited_referrer_before) OVERRIDE {
176 // The implementaion of ChromeDownloadManagerDelegate::IsDangerousFile() is
177 // sensitive to a number of external factors (e.g. whether off-store
178 // extension installs are allowed, whether a given extension download is
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 }
186
187 virtual void GetReservedPath(
188 content::DownloadItem& download,
189 const base::FilePath& target_path, 89 const base::FilePath& target_path,
190 const base::FilePath& default_download_path,
191 bool should_uniquify_path, 90 bool should_uniquify_path,
192 const DownloadPathReservationTracker::ReservedPathCallback& callback) 91 const DownloadPathReservationTracker::ReservedPathCallback& callback)
193 OVERRIDE { 92 OVERRIDE {
194 // Pretend the path reservation succeeded without any change to 93 // Pretend the path reservation succeeded without any change to
195 // |target_path|. 94 // |target_path|.
196 MessageLoop::current()->PostTask(FROM_HERE, 95 MessageLoop::current()->PostTask(FROM_HERE,
197 base::Bind(callback, target_path, true)); 96 base::Bind(callback, target_path, true));
198 } 97 }
199 98
200 // During tests, we want to mock the behavior of this method. 99 virtual void PromptUserForDownloadPath(
201 MOCK_METHOD3(ChooseDownloadPath, 100 DownloadItem* download,
202 void(content::DownloadItem*, 101 const base::FilePath& suggested_path,
203 const base::FilePath&, 102 const DownloadTargetDeterminerDelegate::FileSelectedCallback& callback)
204 const FileSelectedCallback&)); 103 OVERRIDE {
104 base::FilePath return_path = MockPromptUserForDownloadPath(download,
105 suggested_path,
106 callback);
107 OnDownloadPathSelected(callback, return_path, return_path);
108 }
205 109
206 #if defined(FULL_SAFE_BROWSING) 110 MOCK_METHOD3(
207 // A TestDownloadProtectionService* is convenient for setting up mocks. 111 MockPromptUserForDownloadPath,
208 TestDownloadProtectionService* test_download_protection_service() { 112 base::FilePath(
209 return download_protection_service_.get(); 113 content::DownloadItem*,
114 const base::FilePath&,
115 const DownloadTargetDeterminerDelegate::FileSelectedCallback&));
116
117 virtual ExtensionDownloadsEventRouter* GetExtensionEventRouter() OVERRIDE {
118 return NULL;
210 } 119 }
211 #endif
212 120
213 private: 121 private:
214 ~TestChromeDownloadManagerDelegate() {} 122 ~TestChromeDownloadManagerDelegate() {}
215
216 #if defined(FULL_SAFE_BROWSING)
217 scoped_ptr<TestDownloadProtectionService> download_protection_service_;
218 #endif
219 }; 123 };
220 124
221 class ChromeDownloadManagerDelegateTest : 125 class ChromeDownloadManagerDelegateTest :
222 public ChromeRenderViewHostTestHarness { 126 public ChromeRenderViewHostTestHarness {
223 public: 127 public:
224 ChromeDownloadManagerDelegateTest(); 128 ChromeDownloadManagerDelegateTest();
225 129
226 // ::testing::Test 130 // ::testing::Test
227 virtual void SetUp() OVERRIDE; 131 virtual void SetUp() OVERRIDE;
228 virtual void TearDown() OVERRIDE; 132 virtual void TearDown() OVERRIDE;
229 133
230 // Verifies and clears test expectations for |delegate_| and 134 // Verifies and clears test expectations for |delegate_| and
231 // |download_manager_|. 135 // |download_manager_|.
232 void VerifyAndClearExpectations(); 136 void VerifyAndClearExpectations();
233 137
234 // Creates MockDownloadItem and sets up default expectations. 138 // Creates MockDownloadItem and sets up default expectations.
235 content::MockDownloadItem* CreateActiveDownloadItem(int32 id); 139 content::MockDownloadItem* CreateActiveDownloadItem(int32 id);
236 140
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 141 // Given the relative path |path|, returns the full path under the temporary
241 // downloads directory. 142 // downloads directory.
242 base::FilePath GetPathInDownloadDir(const base::FilePath::StringType& path); 143 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 144
254 // Set the kDownloadDefaultDirectory user preference to |path|. 145 // Set the kDownloadDefaultDirectory user preference to |path|.
255 void SetDefaultDownloadPath(const base::FilePath& path); 146 void SetDefaultDownloadPath(const base::FilePath& path);
256 147
257 // Set the kDownloadDefaultDirectory managed preference to |path|. 148 void DetermineDownloadTarget(DownloadItem* download,
258 void SetManagedDownloadPath(const base::FilePath& path); 149 DownloadTarget* result);
259
260 // Set the kPromptForDownload user preference to |prompt|.
261 void SetPromptForDownload(bool prompt);
262 150
263 const base::FilePath& default_download_path() const; 151 const base::FilePath& default_download_path() const;
264 TestChromeDownloadManagerDelegate* delegate(); 152 TestChromeDownloadManagerDelegate* delegate();
265 content::MockDownloadManager* download_manager(); 153 content::MockDownloadManager* download_manager();
266 DownloadPrefs* download_prefs(); 154 DownloadPrefs* download_prefs();
267 155
268 private: 156 private:
269 // Verifies that |target_path|, |disposition|, |danger_type| and 157 void OnDownloadTargetDone(DownloadTarget* result,
270 // |intermediate_path| matches the expectations of |test_case|. 158 const base::FilePath& target_path,
271 void DownloadTargetVerifier(const DownloadTestCase* test_case, 159 DownloadItem::TargetDisposition disposition,
272 const base::FilePath& target_path, 160 content::DownloadDangerType danger_type,
273 DownloadItem::TargetDisposition disposition, 161 const base::FilePath& intermediate_path);
274 content::DownloadDangerType danger_type,
275 const base::FilePath& intermediate_path);
276 162
277 TestingPrefServiceSyncable* pref_service_; 163 TestingPrefServiceSyncable* pref_service_;
278 base::ScopedTempDir test_download_dir_; 164 base::ScopedTempDir test_download_dir_;
279 content::TestBrowserThread ui_thread_; 165 content::TestBrowserThread ui_thread_;
280 content::TestBrowserThread file_thread_; 166 content::TestBrowserThread file_thread_;
281 scoped_refptr<content::MockDownloadManager> download_manager_; 167 scoped_refptr<content::MockDownloadManager> download_manager_;
282 scoped_refptr<TestChromeDownloadManagerDelegate> delegate_; 168 scoped_refptr<TestChromeDownloadManagerDelegate> delegate_;
283 MockWebContentsDelegate web_contents_delegate_; 169 MockWebContentsDelegate web_contents_delegate_;
284 }; 170 };
285 171
286 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest() 172 ChromeDownloadManagerDelegateTest::ChromeDownloadManagerDelegateTest()
287 : ChromeRenderViewHostTestHarness(), 173 : ChromeRenderViewHostTestHarness(),
288 ui_thread_(content::BrowserThread::UI, &message_loop_), 174 ui_thread_(content::BrowserThread::UI, &message_loop_),
289 file_thread_(content::BrowserThread::FILE, &message_loop_), 175 file_thread_(content::BrowserThread::FILE, &message_loop_),
290 download_manager_(new content::MockDownloadManager) { 176 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 } 177 }
295 178
296 void ChromeDownloadManagerDelegateTest::SetUp() { 179 void ChromeDownloadManagerDelegateTest::SetUp() {
297 ChromeRenderViewHostTestHarness::SetUp(); 180 ChromeRenderViewHostTestHarness::SetUp();
298 181
299 CHECK(profile()); 182 CHECK(profile());
300 delegate_ = new TestChromeDownloadManagerDelegate(profile()); 183 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()); 184 delegate_->SetDownloadManager(download_manager_.get());
306 pref_service_ = profile()->GetTestingPrefService(); 185 pref_service_ = profile()->GetTestingPrefService();
307 web_contents()->SetDelegate(&web_contents_delegate_); 186 web_contents()->SetDelegate(&web_contents_delegate_);
308 187
309 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir()); 188 ASSERT_TRUE(test_download_dir_.CreateUniqueTempDir());
310 SetDefaultDownloadPath(test_download_dir_.path()); 189 SetDefaultDownloadPath(test_download_dir_.path());
311 } 190 }
312 191
313 void ChromeDownloadManagerDelegateTest::TearDown() { 192 void ChromeDownloadManagerDelegateTest::TearDown() {
314 message_loop_.RunUntilIdle(); 193 message_loop_.RunUntilIdle();
315 delegate_->Shutdown(); 194 delegate_->Shutdown();
316 ChromeRenderViewHostTestHarness::TearDown(); 195 ChromeRenderViewHostTestHarness::TearDown();
317 } 196 }
318 197
319 void ChromeDownloadManagerDelegateTest::VerifyAndClearExpectations() { 198 void ChromeDownloadManagerDelegateTest::VerifyAndClearExpectations() {
320 ::testing::Mock::VerifyAndClearExpectations(delegate_); 199 ::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 } 200 }
326 201
327 content::MockDownloadItem* 202 content::MockDownloadItem*
328 ChromeDownloadManagerDelegateTest::CreateActiveDownloadItem(int32 id) { 203 ChromeDownloadManagerDelegateTest::CreateActiveDownloadItem(int32 id) {
329 content::MockDownloadItem* item = 204 content::MockDownloadItem* item =
330 new ::testing::NiceMock<content::MockDownloadItem>(); 205 new ::testing::NiceMock<content::MockDownloadItem>();
206 ON_CALL(*item, GetBrowserContext())
207 .WillByDefault(Return(profile()));
208 ON_CALL(*item, GetDangerType())
209 .WillByDefault(Return(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS));
210 ON_CALL(*item, GetForcedFilePath())
211 .WillByDefault(ReturnRefOfCopy(base::FilePath()));
331 ON_CALL(*item, GetFullPath()) 212 ON_CALL(*item, GetFullPath())
332 .WillByDefault(ReturnRefOfCopy(base::FilePath())); 213 .WillByDefault(ReturnRefOfCopy(base::FilePath()));
333 ON_CALL(*item, GetHash()) 214 ON_CALL(*item, GetHash())
334 .WillByDefault(ReturnRefOfCopy(std::string())); 215 .WillByDefault(ReturnRefOfCopy(std::string()));
216 ON_CALL(*item, GetId())
217 .WillByDefault(Return(id));
335 ON_CALL(*item, GetReferrerUrl()) 218 ON_CALL(*item, GetReferrerUrl())
336 .WillByDefault(ReturnRefOfCopy(GURL())); 219 .WillByDefault(ReturnRefOfCopy(GURL()));
220 ON_CALL(*item, GetState())
221 .WillByDefault(Return(DownloadItem::IN_PROGRESS));
337 ON_CALL(*item, GetTransitionType()) 222 ON_CALL(*item, GetTransitionType())
338 .WillByDefault(Return(content::PAGE_TRANSITION_LINK)); 223 .WillByDefault(Return(content::PAGE_TRANSITION_LINK));
224 ON_CALL(*item, GetWebContents())
225 .WillByDefault(Return(web_contents()));
339 ON_CALL(*item, HasUserGesture()) 226 ON_CALL(*item, HasUserGesture())
340 .WillByDefault(Return(false)); 227 .WillByDefault(Return(false));
341 ON_CALL(*item, IsDangerous()) 228 ON_CALL(*item, IsDangerous())
342 .WillByDefault(Return(false)); 229 .WillByDefault(Return(false));
230 ON_CALL(*item, IsInProgress())
231 .WillByDefault(Return(true));
343 ON_CALL(*item, IsTemporary()) 232 ON_CALL(*item, IsTemporary())
344 .WillByDefault(Return(false)); 233 .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)) 234 EXPECT_CALL(*download_manager_, GetDownload(id))
354 .WillRepeatedly(Return(item)); 235 .WillRepeatedly(Return(item));
355 return item; 236 return item;
356 } 237 }
357 238
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( 239 base::FilePath ChromeDownloadManagerDelegateTest::GetPathInDownloadDir(
365 const base::FilePath::StringType& relative_path) { 240 const char* relative_path) {
366 if (relative_path.empty()) 241 base::FilePath full_path =
367 return base::FilePath(); 242 test_download_dir_.path().AppendASCII(relative_path);
368 base::FilePath full_path(test_download_dir_.path().Append(relative_path));
369 return full_path.NormalizePathSeparators(); 243 return full_path.NormalizePathSeparators();
370 } 244 }
371 245
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( 246 void ChromeDownloadManagerDelegateTest::SetDefaultDownloadPath(
465 const base::FilePath& path) { 247 const base::FilePath& path) {
466 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path); 248 pref_service_->SetFilePath(prefs::kDownloadDefaultDirectory, path);
467 } 249 }
468 250
469 void ChromeDownloadManagerDelegateTest::SetManagedDownloadPath( 251 void ChromeDownloadManagerDelegateTest::DetermineDownloadTarget(
470 const base::FilePath& path) { 252 DownloadItem* download_item,
471 pref_service_->SetManagedPref(prefs::kDownloadDefaultDirectory, 253 DownloadTarget* result) {
472 base::CreateFilePathValue(path)); 254 base::WeakPtrFactory<ChromeDownloadManagerDelegateTest> factory(this);
255 delegate()->DetermineDownloadTarget(
256 download_item,
257 base::Bind(&ChromeDownloadManagerDelegateTest::OnDownloadTargetDone,
258 factory.GetWeakPtr(), base::Unretained(result)));
259 base::RunLoop loop_runner;
260 loop_runner.RunUntilIdle();
473 } 261 }
474 262
475 void ChromeDownloadManagerDelegateTest::SetPromptForDownload(bool prompt) { 263 void ChromeDownloadManagerDelegateTest::OnDownloadTargetDone(
476 pref_service_->SetBoolean(prefs::kPromptForDownload, prompt); 264 DownloadTarget* result,
477 }
478
479 void ChromeDownloadManagerDelegateTest::DownloadTargetVerifier(
480 const DownloadTestCase* test_case,
481 const base::FilePath& target_path, 265 const base::FilePath& target_path,
482 DownloadItem::TargetDisposition disposition, 266 DownloadItem::TargetDisposition target_disposition,
483 content::DownloadDangerType danger_type, 267 content::DownloadDangerType danger_type,
484 const base::FilePath& intermediate_path) { 268 const base::FilePath& intermediate_path) {
485 base::FilePath expected_target_path( 269 result->target_path = target_path;
486 GetPathInDownloadDir(test_case->expected_target_path)); 270 result->intermediate_path = intermediate_path;
487 EXPECT_EQ(expected_target_path.value(), target_path.value()); 271 result->target_disposition = target_disposition;
488 EXPECT_EQ(test_case->expected_disposition, disposition); 272 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 } 273 }
516 274
517 const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path() 275 const base::FilePath& ChromeDownloadManagerDelegateTest::default_download_path()
518 const { 276 const {
519 return test_download_dir_.path(); 277 return test_download_dir_.path();
520 } 278 }
521 279
522 TestChromeDownloadManagerDelegate* 280 TestChromeDownloadManagerDelegate*
523 ChromeDownloadManagerDelegateTest::delegate() { 281 ChromeDownloadManagerDelegateTest::delegate() {
524 return delegate_.get(); 282 return delegate_.get();
525 } 283 }
526 284
527 content::MockDownloadManager* 285 content::MockDownloadManager*
528 ChromeDownloadManagerDelegateTest::download_manager() { 286 ChromeDownloadManagerDelegateTest::download_manager() {
529 return download_manager_.get(); 287 return download_manager_.get();
530 } 288 }
531 289
532 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() { 290 DownloadPrefs* ChromeDownloadManagerDelegateTest::download_prefs() {
533 return delegate_->download_prefs(); 291 return delegate_->download_prefs();
534 } 292 }
535 293
536 } // namespace 294 } // namespace
537 295
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) { 296 TEST_F(ChromeDownloadManagerDelegateTest, StartDownload_LastSavePath) {
862 const DownloadTestCase kLastSavePathTestCases[] = { 297 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(); 298 delegate()->ClearLastDownloadPath();
916 299
917 // Run the first test case again. Since the last download path was cleared, 300 scoped_ptr<content::MockDownloadItem> save_as_download(
918 // this test case should behave identically to the first time it was run. 301 CreateActiveDownloadItem(0));
919 RunTestCases(kLastSavePathTestCases, 1); 302 EXPECT_CALL(*save_as_download, GetURL())
303 .Times(::testing::AnyNumber())
304 .WillRepeatedly(ReturnRef(download_url));
305 EXPECT_CALL(*save_as_download, GetTargetDisposition())
306 .Times(::testing::AnyNumber())
307 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_PROMPT));
308
309 scoped_ptr<content::MockDownloadItem> automatic_download(
310 CreateActiveDownloadItem(1));
311 EXPECT_CALL(*automatic_download, GetURL())
312 .Times(::testing::AnyNumber())
313 .WillRepeatedly(ReturnRef(download_url));
314 EXPECT_CALL(*automatic_download, GetTargetDisposition())
315 .Times(::testing::AnyNumber())
316 .WillRepeatedly(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE));
317
318 {
319 // When the prompt is displayed for the first download, the user selects a
320 // path in a different directory.
321 DownloadTarget result;
322 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt"));
323 base::FilePath user_selected_path(GetPathInDownloadDir("bar/baz.txt"));
324 EXPECT_CALL(*delegate(),
325 MockPromptUserForDownloadPath(save_as_download.get(),
326 expected_prompt_path, _))
327 .WillOnce(Return(user_selected_path));
328 DetermineDownloadTarget(save_as_download.get(), &result);
329 EXPECT_EQ(user_selected_path, result.target_path);
330 VerifyAndClearExpectations();
331 }
332
333 {
334 // The prompt path for the second download is the user selected directroy
335 // from the previous download.
336 DownloadTarget result;
337 base::FilePath expected_prompt_path(GetPathInDownloadDir("bar/foo.txt"));
338 EXPECT_CALL(*delegate(),
339 MockPromptUserForDownloadPath(save_as_download.get(),
340 expected_prompt_path, _))
341 .WillOnce(Return(base::FilePath()));
342 DetermineDownloadTarget(save_as_download.get(), &result);
343 VerifyAndClearExpectations();
344 }
345
346 {
347 // Start an automatic download. This one should get the default download
348 // path since the last download path only affects Save As downloads.
349 DownloadTarget result;
350 base::FilePath expected_path(GetPathInDownloadDir("foo.txt"));
351 DetermineDownloadTarget(automatic_download.get(), &result);
352 EXPECT_EQ(expected_path, result.target_path);
353 VerifyAndClearExpectations();
354 }
355
356 // Clear the last download path.
357 delegate()->ClearLastDownloadPath();
358
359 {
360 // The prompt path for the next download should be the default.
361 DownloadTarget result;
362 base::FilePath expected_prompt_path(GetPathInDownloadDir("foo.txt"));
363 EXPECT_CALL(*delegate(),
364 MockPromptUserForDownloadPath(save_as_download.get(),
365 expected_prompt_path, _))
366 .WillOnce(Return(base::FilePath()));
367 DetermineDownloadTarget(save_as_download.get(), &result);
368 VerifyAndClearExpectations();
369 }
920 } 370 }
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