blob: 58c39fa36df05fc6b64bca79419515ae2768b082 [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
5#include <string>
[email protected]f5920322011-03-24 20:34:166#include <set>
initial.commit09911bf2008-07-26 23:55:297
[email protected]bf68a00b2011-04-07 17:28:268#include "base/file_util.h"
[email protected]9fc114672011-06-15 08:17:489#include "base/i18n/number_formatting.h"
10#include "base/i18n/rtl.h"
[email protected]3b63f8f42011-03-28 01:54:1511#include "base/memory/scoped_ptr.h"
[email protected]7286e3fc2011-07-19 22:13:2412#include "base/stl_util.h"
[email protected]047a03f2009-10-07 02:10:2013#include "base/string_util.h"
[email protected]9fc114672011-06-15 08:17:4814#include "base/string16.h"
15#include "base/utf_string_conversions.h"
[email protected]047a03f2009-10-07 02:10:2016#include "build/build_config.h"
[email protected]aa9881c2011-08-15 18:01:1217#include "chrome/browser/download/chrome_download_manager_delegate.h"
[email protected]9fc114672011-06-15 08:17:4818#include "chrome/browser/download/download_item_model.h"
[email protected]e5dc4222010-08-30 22:16:3219#include "chrome/browser/download/download_prefs.h"
[email protected]594cd7d2010-07-21 03:23:5620#include "chrome/browser/download/download_util.h"
[email protected]37858e52010-08-26 00:22:0221#include "chrome/browser/prefs/pref_service.h"
[email protected]2941c2392010-07-15 22:54:3022#include "chrome/common/pref_names.h"
[email protected]a4ff9eae2011-08-01 19:58:1623#include "chrome/test/base/testing_profile.h"
[email protected]1bda97552011-03-01 20:11:5224#include "content/browser/browser_thread.h"
[email protected]71bf3f5e2011-08-15 21:05:2225#include "content/browser/download/download_create_info.h"
26#include "content/browser/download/download_file.h"
27#include "content/browser/download/download_file_manager.h"
28#include "content/browser/download/download_item.h"
29#include "content/browser/download/download_manager.h"
30#include "content/browser/download/download_status_updater.h"
31#include "content/browser/download/mock_download_manager.h"
[email protected]9fc114672011-06-15 08:17:4832#include "grit/generated_resources.h"
[email protected]594cd7d2010-07-21 03:23:5633#include "testing/gmock/include/gmock/gmock.h"
34#include "testing/gmock_mutant.h"
initial.commit09911bf2008-07-26 23:55:2935#include "testing/gtest/include/gtest/gtest.h"
[email protected]9fc114672011-06-15 08:17:4836#include "ui/base/l10n/l10n_util.h"
[email protected]7a3b2632011-06-22 20:40:2237#include "ui/base/text/bytes_formatting.h"
initial.commit09911bf2008-07-26 23:55:2938
[email protected]583844c2011-08-27 00:38:3539class DownloadManagerTest : public testing::Test {
initial.commit09911bf2008-07-26 23:55:2940 public:
[email protected]bf68a00b2011-04-07 17:28:2641 static const char* kTestData;
42 static const size_t kTestDataLen;
43
[email protected]2941c2392010-07-15 22:54:3044 DownloadManagerTest()
45 : profile_(new TestingProfile()),
[email protected]e7557f172011-08-19 23:42:0146 download_manager_delegate_(new ChromeDownloadManagerDelegate(
47 profile_.get())),
[email protected]da1a27b2011-07-29 23:16:3348 download_manager_(new MockDownloadManager(
[email protected]aa9881c2011-08-15 18:01:1249 download_manager_delegate_, &download_status_updater_)),
[email protected]f5920322011-03-24 20:34:1650 ui_thread_(BrowserThread::UI, &message_loop_),
51 file_thread_(BrowserThread::FILE, &message_loop_) {
[email protected]2941c2392010-07-15 22:54:3052 download_manager_->Init(profile_.get());
[email protected]2588ea9d2011-08-22 20:59:5353 download_manager_delegate_->SetDownloadManager(download_manager_);
[email protected]2941c2392010-07-15 22:54:3054 }
55
56 ~DownloadManagerTest() {
[email protected]326a6a92010-09-10 20:21:1357 download_manager_->Shutdown();
[email protected]2941c2392010-07-15 22:54:3058 // profile_ must outlive download_manager_, so we explicitly delete
59 // download_manager_ first.
[email protected]1b2f8da2010-07-22 08:29:2960 download_manager_ = NULL;
[email protected]e7557f172011-08-19 23:42:0161 download_manager_delegate_ = NULL;
[email protected]1b2f8da2010-07-22 08:29:2962 profile_.reset(NULL);
63 message_loop_.RunAllPending();
initial.commit09911bf2008-07-26 23:55:2964 }
65
[email protected]bf68a00b2011-04-07 17:28:2666 void AddDownloadToFileManager(int id, DownloadFile* download_file) {
67 file_manager()->downloads_[id] = download_file;
68 }
69
70 void OnAllDataSaved(int32 download_id, int64 size, const std::string& hash) {
71 download_manager_->OnAllDataSaved(download_id, size, hash);
72 }
73
[email protected]99cb7f82011-07-28 17:27:2674 void FileSelected(const FilePath& path, void* params) {
75 download_manager_->FileSelected(path, params);
[email protected]bf68a00b2011-04-07 17:28:2676 }
77
[email protected]4cd82f72011-05-23 19:15:0178 void ContinueDownloadWithPath(DownloadItem* download, const FilePath& path) {
79 download_manager_->ContinueDownloadWithPath(download, path);
[email protected]bf68a00b2011-04-07 17:28:2680 }
81
82 void OnDownloadError(int32 download_id, int64 size, int os_error) {
83 download_manager_->OnDownloadError(download_id, size, os_error);
84 }
85
86 // Get the download item with ID |id|.
87 DownloadItem* GetActiveDownloadItem(int32 id) {
88 if (ContainsKey(download_manager_->active_downloads_, id))
89 return download_manager_->active_downloads_[id];
90 return NULL;
[email protected]594cd7d2010-07-21 03:23:5691 }
92
initial.commit09911bf2008-07-26 23:55:2993 protected:
[email protected]a3d2bc42010-10-06 14:08:4994 DownloadStatusUpdater download_status_updater_;
[email protected]2941c2392010-07-15 22:54:3095 scoped_ptr<TestingProfile> profile_;
[email protected]aa9881c2011-08-15 18:01:1296 scoped_refptr<ChromeDownloadManagerDelegate> download_manager_delegate_;
initial.commit09911bf2008-07-26 23:55:2997 scoped_refptr<DownloadManager> download_manager_;
[email protected]594cd7d2010-07-21 03:23:5698 scoped_refptr<DownloadFileManager> file_manager_;
[email protected]dd3eac22008-08-26 07:28:3499 MessageLoopForUI message_loop_;
[email protected]ca4b5fa32010-10-09 12:42:18100 BrowserThread ui_thread_;
[email protected]f5920322011-03-24 20:34:16101 BrowserThread file_thread_;
initial.commit09911bf2008-07-26 23:55:29102
[email protected]594cd7d2010-07-21 03:23:56103 DownloadFileManager* file_manager() {
104 if (!file_manager_) {
105 file_manager_ = new DownloadFileManager(NULL);
106 download_manager_->file_manager_ = file_manager_;
107 }
108 return file_manager_;
109 }
110
[email protected]287b86b2011-02-26 00:11:35111 // Make sure download item |id| was set with correct safety state for
112 // given |is_dangerous_file| and |is_dangerous_url|.
113 bool VerifySafetyState(bool is_dangerous_file,
114 bool is_dangerous_url,
115 int id) {
116 DownloadItem::SafetyState safety_state =
117 download_manager_->GetDownloadItem(id)->safety_state();
118 return (is_dangerous_file || is_dangerous_url) ?
119 safety_state != DownloadItem::SAFE : safety_state == DownloadItem::SAFE;
120 }
121
[email protected]4d818fee2010-06-06 13:32:27122 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest);
initial.commit09911bf2008-07-26 23:55:29123};
124
[email protected]bf68a00b2011-04-07 17:28:26125const char* DownloadManagerTest::kTestData = "a;sdlfalsdfjalsdkfjad";
126const size_t DownloadManagerTest::kTestDataLen =
127 strlen(DownloadManagerTest::kTestData);
128
[email protected]763f946a2009-01-06 19:04:39129namespace {
130
131const struct {
[email protected]2941c2392010-07-15 22:54:30132 const char* url;
133 const char* mime_type;
134 bool save_as;
135 bool prompt_for_download;
136 bool expected_save_as;
137} kStartDownloadCases[] = {
138 { "http://www.foo.com/dont-open.html",
139 "text/html",
140 false,
141 false,
142 false, },
143 { "http://www.foo.com/save-as.html",
144 "text/html",
145 true,
146 false,
147 true, },
148 { "http://www.foo.com/always-prompt.html",
149 "text/html",
150 false,
151 true,
152 true, },
[email protected]bac4f4b2011-03-05 02:01:40153 { "http://www.foo.com/user-script-text-html-mimetype.user.js",
[email protected]2941c2392010-07-15 22:54:30154 "text/html",
155 false,
[email protected]bac4f4b2011-03-05 02:01:40156 false,
[email protected]2941c2392010-07-15 22:54:30157 false, },
158 { "http://www.foo.com/extensionless-extension",
159 "application/x-chrome-extension",
160 true,
161 false,
162 true, },
163 { "http://www.foo.com/save-as.pdf",
164 "application/pdf",
165 true,
166 false,
167 true, },
[email protected]2fc93852011-01-08 22:13:56168 { "http://www.foo.com/sometimes_prompt.pdf",
[email protected]2941c2392010-07-15 22:54:30169 "application/pdf",
170 false,
171 true,
[email protected]2fc93852011-01-08 22:13:56172 false, },
173 { "http://www.foo.com/always_prompt.jar",
174 "application/jar",
175 false,
176 true,
[email protected]3366aca62010-10-20 01:18:24177 true, },
[email protected]2941c2392010-07-15 22:54:30178};
179
[email protected]594cd7d2010-07-21 03:23:56180const struct {
181 FilePath::StringType suggested_path;
[email protected]287b86b2011-02-26 00:11:35182 bool is_dangerous_file;
183 bool is_dangerous_url;
[email protected]594cd7d2010-07-21 03:23:56184 bool finish_before_rename;
[email protected]594cd7d2010-07-21 03:23:56185 int expected_rename_count;
186} kDownloadRenameCases[] = {
[email protected]adb2f3d12011-01-23 16:24:54187 // Safe download, download finishes BEFORE file name determined.
188 // Renamed twice (linear path through UI). Crdownload file does not need
189 // to be deleted.
[email protected]88008002011-05-24 23:14:15190 { FILE_PATH_LITERAL("foo.zip"), false, false, true, 2, },
[email protected]287b86b2011-02-26 00:11:35191 // Dangerous download (file is dangerous or download URL is not safe or both),
192 // download finishes BEFORE file name determined. Needs to be renamed only
193 // once.
[email protected]88008002011-05-24 23:14:15194 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, false, true, 1, },
195 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), false, true, true, 1, },
196 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, true, true, 1, },
[email protected]adb2f3d12011-01-23 16:24:54197 // Safe download, download finishes AFTER file name determined.
[email protected]594cd7d2010-07-21 03:23:56198 // Needs to be renamed twice.
[email protected]88008002011-05-24 23:14:15199 { FILE_PATH_LITERAL("foo.zip"), false, false, false, 2, },
[email protected]adb2f3d12011-01-23 16:24:54200 // Dangerous download, download finishes AFTER file name determined.
[email protected]594cd7d2010-07-21 03:23:56201 // Needs to be renamed only once.
[email protected]88008002011-05-24 23:14:15202 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, false, false, 1, },
203 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), false, true, false, 1, },
204 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"), true, true, false, 1, },
[email protected]594cd7d2010-07-21 03:23:56205};
206
207class MockDownloadFile : public DownloadFile {
208 public:
[email protected]f5920322011-03-24 20:34:16209 MockDownloadFile(DownloadCreateInfo* info, DownloadManager* manager)
210 : DownloadFile(info, manager), renamed_count_(0) { }
[email protected]594cd7d2010-07-21 03:23:56211 virtual ~MockDownloadFile() { Destructed(); }
[email protected]d2310142011-02-18 17:02:55212 MOCK_METHOD1(Rename, bool(const FilePath&));
[email protected]594cd7d2010-07-21 03:23:56213 MOCK_METHOD0(Destructed, void());
214
215 bool TestMultipleRename(
[email protected]d2310142011-02-18 17:02:55216 int expected_count, const FilePath& expected,
217 const FilePath& path) {
[email protected]594cd7d2010-07-21 03:23:56218 ++renamed_count_;
219 EXPECT_EQ(expected_count, renamed_count_);
[email protected]594cd7d2010-07-21 03:23:56220 EXPECT_EQ(expected.value(), path.value());
221 return true;
222 }
223
224 private:
225 int renamed_count_;
226};
227
[email protected]f5920322011-03-24 20:34:16228// This is an observer that records what download IDs have opened a select
229// file dialog.
230class SelectFileObserver : public DownloadManager::Observer {
231 public:
232 explicit SelectFileObserver(DownloadManager* download_manager)
233 : download_manager_(download_manager) {
[email protected]bf68a00b2011-04-07 17:28:26234 DCHECK(download_manager_.get());
[email protected]f5920322011-03-24 20:34:16235 download_manager_->AddObserver(this);
236 }
237
238 ~SelectFileObserver() {
239 download_manager_->RemoveObserver(this);
240 }
241
242 // Downloadmanager::Observer functions.
243 virtual void ModelChanged() {}
244 virtual void ManagerGoingDown() {}
[email protected]fed38252011-07-08 17:26:50245 virtual void SelectFileDialogDisplayed(int32 id) {
[email protected]f5920322011-03-24 20:34:16246 file_dialog_ids_.insert(id);
247 }
248
249 bool ShowedFileDialogForId(int32 id) {
250 return file_dialog_ids_.find(id) != file_dialog_ids_.end();
251 }
252
253 private:
254 std::set<int32> file_dialog_ids_;
[email protected]bf68a00b2011-04-07 17:28:26255 scoped_refptr<DownloadManager> download_manager_;
256};
257
258// This observer tracks the progress of |DownloadItem|s.
259class ItemObserver : public DownloadItem::Observer {
260 public:
261 explicit ItemObserver(DownloadItem* tracked)
262 : tracked_(tracked), states_hit_(0),
[email protected]48837962011-04-19 17:03:29263 was_updated_(false), was_opened_(false) {
[email protected]bf68a00b2011-04-07 17:28:26264 DCHECK(tracked_);
265 tracked_->AddObserver(this);
266 // Record the initial state.
267 OnDownloadUpdated(tracked_);
268 }
269 ~ItemObserver() {
270 tracked_->RemoveObserver(this);
271 }
272
273 bool hit_state(int state) const {
274 return (1 << state) & states_hit_;
275 }
276 bool was_updated() const { return was_updated_; }
[email protected]bf68a00b2011-04-07 17:28:26277 bool was_opened() const { return was_opened_; }
278
279 private:
280 // DownloadItem::Observer methods
281 virtual void OnDownloadUpdated(DownloadItem* download) {
282 DCHECK_EQ(tracked_, download);
283 states_hit_ |= (1 << download->state());
284 was_updated_ = true;
285 }
[email protected]bf68a00b2011-04-07 17:28:26286 virtual void OnDownloadOpened(DownloadItem* download) {
287 DCHECK_EQ(tracked_, download);
288 states_hit_ |= (1 << download->state());
289 was_opened_ = true;
290 }
291
292 DownloadItem* tracked_;
293 int states_hit_;
294 bool was_updated_;
[email protected]bf68a00b2011-04-07 17:28:26295 bool was_opened_;
[email protected]f5920322011-03-24 20:34:16296};
297
[email protected]594cd7d2010-07-21 03:23:56298} // namespace
299
[email protected]f5920322011-03-24 20:34:16300TEST_F(DownloadManagerTest, StartDownload) {
301 BrowserThread io_thread(BrowserThread::IO, &message_loop_);
302 PrefService* prefs = profile_->GetPrefs();
[email protected]fed38252011-07-08 17:26:50303 prefs->SetFilePath(prefs::kDownloadDefaultDirectory, FilePath());
[email protected]e7557f172011-08-19 23:42:01304 DownloadPrefs* download_prefs =
305 DownloadPrefs::FromDownloadManager(download_manager_);
306 download_prefs->EnableAutoOpenBasedOnExtension(
[email protected]f5920322011-03-24 20:34:16307 FilePath(FILE_PATH_LITERAL("example.pdf")));
308
309 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kStartDownloadCases); ++i) {
310 prefs->SetBoolean(prefs::kPromptForDownload,
311 kStartDownloadCases[i].prompt_for_download);
312
313 SelectFileObserver observer(download_manager_);
[email protected]c9994e02011-05-24 20:52:19314 // Normally, the download system takes ownership of info, and is
315 // responsible for deleting it. In these unit tests, however, we
316 // don't call the function that deletes it, so we do so ourselves.
317 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]f5920322011-03-24 20:34:16318 info->download_id = static_cast<int>(i);
319 info->prompt_user_for_save_location = kStartDownloadCases[i].save_as;
[email protected]8799e542011-04-20 03:47:34320 info->url_chain.push_back(GURL(kStartDownloadCases[i].url));
[email protected]f5920322011-03-24 20:34:16321 info->mime_type = kStartDownloadCases[i].mime_type;
[email protected]c9994e02011-05-24 20:52:19322 download_manager_->CreateDownloadItem(info.get());
[email protected]f5920322011-03-24 20:34:16323
[email protected]c9994e02011-05-24 20:52:19324 DownloadFile* download_file(
325 new DownloadFile(info.get(), download_manager_));
[email protected]bf68a00b2011-04-07 17:28:26326 AddDownloadToFileManager(info->download_id, download_file);
327 download_file->Initialize(false);
[email protected]4cd82f72011-05-23 19:15:01328 download_manager_->StartDownload(info->download_id);
[email protected]f5920322011-03-24 20:34:16329 message_loop_.RunAllPending();
330
[email protected]c9994e02011-05-24 20:52:19331 // SelectFileObserver will have recorded any attempt to open the
[email protected]f5920322011-03-24 20:34:16332 // select file dialog.
[email protected]c9994e02011-05-24 20:52:19333 // Note that DownloadManager::FileSelectionCanceled() is never called.
[email protected]f5920322011-03-24 20:34:16334 EXPECT_EQ(kStartDownloadCases[i].expected_save_as,
335 observer.ShowedFileDialogForId(i));
[email protected]f5920322011-03-24 20:34:16336 }
337}
338
[email protected]594cd7d2010-07-21 03:23:56339TEST_F(DownloadManagerTest, DownloadRenameTest) {
340 using ::testing::_;
341 using ::testing::CreateFunctor;
342 using ::testing::Invoke;
343 using ::testing::Return;
344
[email protected]594cd7d2010-07-21 03:23:56345 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDownloadRenameCases); ++i) {
[email protected]c9994e02011-05-24 20:52:19346 // Normally, the download system takes ownership of info, and is
347 // responsible for deleting it. In these unit tests, however, we
348 // don't call the function that deletes it, so we do so ourselves.
349 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]594cd7d2010-07-21 03:23:56350 info->download_id = static_cast<int>(i);
351 info->prompt_user_for_save_location = false;
[email protected]30917cb2011-05-10 21:40:47352 info->url_chain.push_back(GURL());
[email protected]4cd82f72011-05-23 19:15:01353 const FilePath new_path(kDownloadRenameCases[i].suggested_path);
[email protected]594cd7d2010-07-21 03:23:56354
[email protected]bf68a00b2011-04-07 17:28:26355 MockDownloadFile* download_file(
[email protected]c9994e02011-05-24 20:52:19356 new MockDownloadFile(info.get(), download_manager_));
[email protected]bf68a00b2011-04-07 17:28:26357 AddDownloadToFileManager(info->download_id, download_file);
[email protected]594cd7d2010-07-21 03:23:56358
[email protected]bf68a00b2011-04-07 17:28:26359 // |download_file| is owned by DownloadFileManager.
360 ::testing::Mock::AllowLeak(download_file);
361 EXPECT_CALL(*download_file, Destructed()).Times(1);
[email protected]594cd7d2010-07-21 03:23:56362
363 if (kDownloadRenameCases[i].expected_rename_count == 1) {
[email protected]bf68a00b2011-04-07 17:28:26364 EXPECT_CALL(*download_file, Rename(new_path)).WillOnce(Return(true));
[email protected]594cd7d2010-07-21 03:23:56365 } else {
366 ASSERT_EQ(2, kDownloadRenameCases[i].expected_rename_count);
367 FilePath crdownload(download_util::GetCrDownloadPath(new_path));
[email protected]bf68a00b2011-04-07 17:28:26368 EXPECT_CALL(*download_file, Rename(_))
[email protected]d2310142011-02-18 17:02:55369 .WillOnce(testing::WithArgs<0>(Invoke(CreateFunctor(
[email protected]bf68a00b2011-04-07 17:28:26370 download_file, &MockDownloadFile::TestMultipleRename,
[email protected]d2310142011-02-18 17:02:55371 1, crdownload))))
372 .WillOnce(testing::WithArgs<0>(Invoke(CreateFunctor(
[email protected]bf68a00b2011-04-07 17:28:26373 download_file, &MockDownloadFile::TestMultipleRename,
[email protected]d2310142011-02-18 17:02:55374 2, new_path))));
[email protected]594cd7d2010-07-21 03:23:56375 }
[email protected]c9994e02011-05-24 20:52:19376 download_manager_->CreateDownloadItem(info.get());
[email protected]88008002011-05-24 23:14:15377 DownloadItem* download = GetActiveDownloadItem(i);
378 ASSERT_TRUE(download != NULL);
379 if (kDownloadRenameCases[i].is_dangerous_file)
380 download->MarkFileDangerous();
381 if (kDownloadRenameCases[i].is_dangerous_url)
382 download->MarkUrlDangerous();
[email protected]c2e76012010-12-23 21:10:29383
[email protected]4cd82f72011-05-23 19:15:01384 int32* id_ptr = new int32;
385 *id_ptr = i; // Deleted in FileSelected().
[email protected]594cd7d2010-07-21 03:23:56386 if (kDownloadRenameCases[i].finish_before_rename) {
[email protected]bf68a00b2011-04-07 17:28:26387 OnAllDataSaved(i, 1024, std::string("fake_hash"));
[email protected]f5920322011-03-24 20:34:16388 message_loop_.RunAllPending();
[email protected]99cb7f82011-07-28 17:27:26389 FileSelected(new_path, id_ptr);
[email protected]594cd7d2010-07-21 03:23:56390 } else {
[email protected]99cb7f82011-07-28 17:27:26391 FileSelected(new_path, id_ptr);
[email protected]f5920322011-03-24 20:34:16392 message_loop_.RunAllPending();
[email protected]bf68a00b2011-04-07 17:28:26393 OnAllDataSaved(i, 1024, std::string("fake_hash"));
[email protected]594cd7d2010-07-21 03:23:56394 }
395
396 message_loop_.RunAllPending();
[email protected]287b86b2011-02-26 00:11:35397 EXPECT_TRUE(VerifySafetyState(kDownloadRenameCases[i].is_dangerous_file,
398 kDownloadRenameCases[i].is_dangerous_url,
399 i));
[email protected]594cd7d2010-07-21 03:23:56400 }
401}
[email protected]bf68a00b2011-04-07 17:28:26402
403TEST_F(DownloadManagerTest, DownloadInterruptTest) {
404 using ::testing::_;
405 using ::testing::CreateFunctor;
406 using ::testing::Invoke;
407 using ::testing::Return;
408
[email protected]c9994e02011-05-24 20:52:19409 // Normally, the download system takes ownership of info, and is
410 // responsible for deleting it. In these unit tests, however, we
411 // don't call the function that deletes it, so we do so ourselves.
412 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]bf68a00b2011-04-07 17:28:26413 info->download_id = static_cast<int>(0);
414 info->prompt_user_for_save_location = false;
[email protected]30917cb2011-05-10 21:40:47415 info->url_chain.push_back(GURL());
[email protected]9fc114672011-06-15 08:17:48416 info->total_bytes = static_cast<int64>(kTestDataLen);
[email protected]bf68a00b2011-04-07 17:28:26417 const FilePath new_path(FILE_PATH_LITERAL("foo.zip"));
418 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
419
420 MockDownloadFile* download_file(
[email protected]c9994e02011-05-24 20:52:19421 new MockDownloadFile(info.get(), download_manager_));
[email protected]bf68a00b2011-04-07 17:28:26422 AddDownloadToFileManager(info->download_id, download_file);
423
424 // |download_file| is owned by DownloadFileManager.
425 ::testing::Mock::AllowLeak(download_file);
426 EXPECT_CALL(*download_file, Destructed()).Times(1);
427
428 EXPECT_CALL(*download_file, Rename(cr_path)).WillOnce(Return(true));
429
[email protected]c9994e02011-05-24 20:52:19430 download_manager_->CreateDownloadItem(info.get());
[email protected]bf68a00b2011-04-07 17:28:26431
432 DownloadItem* download = GetActiveDownloadItem(0);
433 ASSERT_TRUE(download != NULL);
[email protected]9fc114672011-06-15 08:17:48434 scoped_ptr<DownloadItemModel> download_item_model(
435 new DownloadItemModel(download));
[email protected]bf68a00b2011-04-07 17:28:26436
437 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
[email protected]d8ca4d12011-04-07 22:05:13438 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
[email protected]bf68a00b2011-04-07 17:28:26439
440 download_file->AppendDataToFile(kTestData, kTestDataLen);
441
[email protected]4cd82f72011-05-23 19:15:01442 ContinueDownloadWithPath(download, new_path);
[email protected]bf68a00b2011-04-07 17:28:26443 message_loop_.RunAllPending();
444 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
445
[email protected]9fc114672011-06-15 08:17:48446 int64 error_size = 3;
447 OnDownloadError(0, error_size, -6);
[email protected]bf68a00b2011-04-07 17:28:26448 message_loop_.RunAllPending();
449
450 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
[email protected]bf68a00b2011-04-07 17:28:26451 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
452 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
453 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
454 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
455 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
456 EXPECT_TRUE(observer->was_updated());
[email protected]bf68a00b2011-04-07 17:28:26457 EXPECT_FALSE(observer->was_opened());
[email protected]9fc114672011-06-15 08:17:48458 EXPECT_FALSE(download->file_externally_removed());
459 EXPECT_EQ(DownloadItem::INTERRUPTED, download->state());
[email protected]7a3b2632011-06-22 20:40:22460 ui::DataUnits amount_units = ui::GetByteDisplayUnits(kTestDataLen);
461 string16 simple_size =
462 ui::FormatBytesWithUnits(error_size, amount_units, false);
[email protected]9fc114672011-06-15 08:17:48463 string16 simple_total = base::i18n::GetDisplayStringInLTRDirectionality(
[email protected]7a3b2632011-06-22 20:40:22464 ui::FormatBytesWithUnits(kTestDataLen, amount_units, true));
[email protected]9fc114672011-06-15 08:17:48465 EXPECT_EQ(download_item_model->GetStatusText(),
466 l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED,
467 simple_size,
468 simple_total));
[email protected]bf68a00b2011-04-07 17:28:26469
[email protected]54610672011-07-18 18:24:43470 download->Cancel(true);
[email protected]bf68a00b2011-04-07 17:28:26471
[email protected]bf68a00b2011-04-07 17:28:26472 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
473 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
474 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
475 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
476 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
477 EXPECT_TRUE(observer->was_updated());
[email protected]bf68a00b2011-04-07 17:28:26478 EXPECT_FALSE(observer->was_opened());
[email protected]9fc114672011-06-15 08:17:48479 EXPECT_FALSE(download->file_externally_removed());
480 EXPECT_EQ(DownloadItem::INTERRUPTED, download->state());
481 EXPECT_EQ(download->received_bytes(), error_size);
482 EXPECT_EQ(download->total_bytes(), static_cast<int64>(kTestDataLen));
[email protected]bf68a00b2011-04-07 17:28:26483}
484
485TEST_F(DownloadManagerTest, DownloadCancelTest) {
486 using ::testing::_;
487 using ::testing::CreateFunctor;
488 using ::testing::Invoke;
489 using ::testing::Return;
490
[email protected]c9994e02011-05-24 20:52:19491 // Normally, the download system takes ownership of info, and is
492 // responsible for deleting it. In these unit tests, however, we
493 // don't call the function that deletes it, so we do so ourselves.
494 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]bf68a00b2011-04-07 17:28:26495 info->download_id = static_cast<int>(0);
496 info->prompt_user_for_save_location = false;
[email protected]30917cb2011-05-10 21:40:47497 info->url_chain.push_back(GURL());
[email protected]bf68a00b2011-04-07 17:28:26498 const FilePath new_path(FILE_PATH_LITERAL("foo.zip"));
499 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
500
501 MockDownloadFile* download_file(
[email protected]c9994e02011-05-24 20:52:19502 new MockDownloadFile(info.get(), download_manager_));
[email protected]bf68a00b2011-04-07 17:28:26503 AddDownloadToFileManager(info->download_id, download_file);
504
505 // |download_file| is owned by DownloadFileManager.
506 ::testing::Mock::AllowLeak(download_file);
507 EXPECT_CALL(*download_file, Destructed()).Times(1);
508
509 EXPECT_CALL(*download_file, Rename(cr_path)).WillOnce(Return(true));
510
[email protected]c9994e02011-05-24 20:52:19511 download_manager_->CreateDownloadItem(info.get());
[email protected]bf68a00b2011-04-07 17:28:26512
513 DownloadItem* download = GetActiveDownloadItem(0);
514 ASSERT_TRUE(download != NULL);
[email protected]9fc114672011-06-15 08:17:48515 scoped_ptr<DownloadItemModel> download_item_model(
516 new DownloadItemModel(download));
[email protected]bf68a00b2011-04-07 17:28:26517
518 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
[email protected]d8ca4d12011-04-07 22:05:13519 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
[email protected]bf68a00b2011-04-07 17:28:26520
[email protected]4cd82f72011-05-23 19:15:01521 ContinueDownloadWithPath(download, new_path);
[email protected]bf68a00b2011-04-07 17:28:26522 message_loop_.RunAllPending();
523 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
524
525 download_file->AppendDataToFile(kTestData, kTestDataLen);
526
[email protected]54610672011-07-18 18:24:43527 download->Cancel(false);
[email protected]bf68a00b2011-04-07 17:28:26528 message_loop_.RunAllPending();
529
[email protected]54610672011-07-18 18:24:43530 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
[email protected]bf68a00b2011-04-07 17:28:26531 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
532 EXPECT_TRUE(observer->hit_state(DownloadItem::CANCELLED));
533 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
534 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
535 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
536 EXPECT_TRUE(observer->was_updated());
[email protected]bf68a00b2011-04-07 17:28:26537 EXPECT_FALSE(observer->was_opened());
[email protected]9fc114672011-06-15 08:17:48538 EXPECT_FALSE(download->file_externally_removed());
539 EXPECT_EQ(DownloadItem::CANCELLED, download->state());
540 EXPECT_EQ(download_item_model->GetStatusText(),
541 l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_CANCELED));
[email protected]bf68a00b2011-04-07 17:28:26542
543 EXPECT_FALSE(file_util::PathExists(new_path));
544 EXPECT_FALSE(file_util::PathExists(cr_path));
545}
[email protected]8fa1eeb52011-04-13 14:18:02546
547TEST_F(DownloadManagerTest, DownloadOverwriteTest) {
548 using ::testing::_;
549 using ::testing::CreateFunctor;
550 using ::testing::Invoke;
551 using ::testing::Return;
552
553 // Create a temporary directory.
554 ScopedTempDir temp_dir_;
555 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
556
557 // File names we're using.
558 const FilePath new_path(temp_dir_.path().AppendASCII("foo.txt"));
559 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
560 EXPECT_FALSE(file_util::PathExists(new_path));
561
562 // Create the file that we will overwrite. Will be automatically cleaned
563 // up when temp_dir_ is destroyed.
564 FILE* fp = file_util::OpenFile(new_path, "w");
565 file_util::CloseFile(fp);
566 EXPECT_TRUE(file_util::PathExists(new_path));
567
568 // Construct the unique file name that normally would be created, but
569 // which we will override.
[email protected]ec865262011-08-23 20:01:48570 int uniquifier = DownloadFile::GetUniquePathNumber(new_path);
[email protected]8fa1eeb52011-04-13 14:18:02571 FilePath unique_new_path = new_path;
572 EXPECT_NE(0, uniquifier);
[email protected]ec865262011-08-23 20:01:48573 DownloadFile::AppendNumberToPath(&unique_new_path, uniquifier);
[email protected]8fa1eeb52011-04-13 14:18:02574
[email protected]c9994e02011-05-24 20:52:19575 // Normally, the download system takes ownership of info, and is
576 // responsible for deleting it. In these unit tests, however, we
577 // don't call the function that deletes it, so we do so ourselves.
578 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]8fa1eeb52011-04-13 14:18:02579 info->download_id = static_cast<int>(0);
580 info->prompt_user_for_save_location = true;
[email protected]30917cb2011-05-10 21:40:47581 info->url_chain.push_back(GURL());
[email protected]8fa1eeb52011-04-13 14:18:02582
[email protected]c9994e02011-05-24 20:52:19583 download_manager_->CreateDownloadItem(info.get());
[email protected]8fa1eeb52011-04-13 14:18:02584
585 DownloadItem* download = GetActiveDownloadItem(0);
586 ASSERT_TRUE(download != NULL);
[email protected]9fc114672011-06-15 08:17:48587 scoped_ptr<DownloadItemModel> download_item_model(
588 new DownloadItemModel(download));
[email protected]8fa1eeb52011-04-13 14:18:02589
590 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
591 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
592
593 // Create and initialize the download file. We're bypassing the first part
594 // of the download process and skipping to the part after the final file
595 // name has been chosen, so we need to initialize the download file
596 // properly.
597 DownloadFile* download_file(
[email protected]c9994e02011-05-24 20:52:19598 new DownloadFile(info.get(), download_manager_));
[email protected]8fa1eeb52011-04-13 14:18:02599 download_file->Rename(cr_path);
600 // This creates the .crdownload version of the file.
601 download_file->Initialize(false);
602 // |download_file| is owned by DownloadFileManager.
603 AddDownloadToFileManager(info->download_id, download_file);
604
[email protected]4cd82f72011-05-23 19:15:01605 ContinueDownloadWithPath(download, new_path);
[email protected]8fa1eeb52011-04-13 14:18:02606 message_loop_.RunAllPending();
607 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
608
609 download_file->AppendDataToFile(kTestData, kTestDataLen);
610
611 // Finish the download.
612 OnAllDataSaved(0, kTestDataLen, "");
613 message_loop_.RunAllPending();
614
615 // Download is complete.
616 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
617 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
618 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
619 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
620 EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
621 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
622 EXPECT_TRUE(observer->was_updated());
[email protected]8fa1eeb52011-04-13 14:18:02623 EXPECT_FALSE(observer->was_opened());
[email protected]9fc114672011-06-15 08:17:48624 EXPECT_FALSE(download->file_externally_removed());
[email protected]8fa1eeb52011-04-13 14:18:02625 EXPECT_EQ(DownloadItem::COMPLETE, download->state());
[email protected]9fc114672011-06-15 08:17:48626 EXPECT_EQ(download_item_model->GetStatusText(), ASCIIToUTF16(""));
[email protected]8fa1eeb52011-04-13 14:18:02627
628 EXPECT_TRUE(file_util::PathExists(new_path));
629 EXPECT_FALSE(file_util::PathExists(cr_path));
630 EXPECT_FALSE(file_util::PathExists(unique_new_path));
631 std::string file_contents;
632 EXPECT_TRUE(file_util::ReadFileToString(new_path, &file_contents));
633 EXPECT_EQ(std::string(kTestData), file_contents);
634}
[email protected]9fc114672011-06-15 08:17:48635
636TEST_F(DownloadManagerTest, DownloadRemoveTest) {
637 using ::testing::_;
638 using ::testing::CreateFunctor;
639 using ::testing::Invoke;
640 using ::testing::Return;
641
642 // Create a temporary directory.
643 ScopedTempDir temp_dir_;
644 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
645
646 // File names we're using.
647 const FilePath new_path(temp_dir_.path().AppendASCII("foo.txt"));
648 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
649 EXPECT_FALSE(file_util::PathExists(new_path));
650
651 // Normally, the download system takes ownership of info, and is
652 // responsible for deleting it. In these unit tests, however, we
653 // don't call the function that deletes it, so we do so ourselves.
654 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
655 info->download_id = static_cast<int>(0);
656 info->prompt_user_for_save_location = true;
657 info->url_chain.push_back(GURL());
658
659 download_manager_->CreateDownloadItem(info.get());
660
661 DownloadItem* download = GetActiveDownloadItem(0);
662 ASSERT_TRUE(download != NULL);
663 scoped_ptr<DownloadItemModel> download_item_model(
664 new DownloadItemModel(download));
665
666 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
667 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
668
669 // Create and initialize the download file. We're bypassing the first part
670 // of the download process and skipping to the part after the final file
671 // name has been chosen, so we need to initialize the download file
672 // properly.
673 DownloadFile* download_file(
674 new DownloadFile(info.get(), download_manager_));
675 download_file->Rename(cr_path);
676 // This creates the .crdownload version of the file.
677 download_file->Initialize(false);
678 // |download_file| is owned by DownloadFileManager.
679 AddDownloadToFileManager(info->download_id, download_file);
680
681 ContinueDownloadWithPath(download, new_path);
682 message_loop_.RunAllPending();
683 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
684
685 download_file->AppendDataToFile(kTestData, kTestDataLen);
686
687 // Finish the download.
688 OnAllDataSaved(0, kTestDataLen, "");
689 message_loop_.RunAllPending();
690
691 // Download is complete.
692 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
693 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
694 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
695 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
696 EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
697 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
698 EXPECT_TRUE(observer->was_updated());
699 EXPECT_FALSE(observer->was_opened());
700 EXPECT_FALSE(download->file_externally_removed());
701 EXPECT_EQ(DownloadItem::COMPLETE, download->state());
702 EXPECT_EQ(download_item_model->GetStatusText(), ASCIIToUTF16(""));
703
704 EXPECT_TRUE(file_util::PathExists(new_path));
705 EXPECT_FALSE(file_util::PathExists(cr_path));
706
707 // Remove the downloaded file.
708 ASSERT_TRUE(file_util::Delete(new_path, false));
709 download->OnDownloadedFileRemoved();
710 message_loop_.RunAllPending();
711
712 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
713 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
714 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
715 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
716 EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
717 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
718 EXPECT_TRUE(observer->was_updated());
719 EXPECT_FALSE(observer->was_opened());
720 EXPECT_TRUE(download->file_externally_removed());
721 EXPECT_EQ(DownloadItem::COMPLETE, download->state());
722 EXPECT_EQ(download_item_model->GetStatusText(),
723 l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED));
724
725 EXPECT_FALSE(file_util::PathExists(new_path));
726}