blob: 42e6a2c4d6c2c5fab5ca83d4f490a915ed726b22 [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
[email protected]f5920322011-03-24 20:34:165#include <set>
[email protected]c38831a12011-10-28 12:44:496#include <string>
initial.commit09911bf2008-07-26 23:55:297
[email protected]a3094072011-10-10 17:14:058#include "base/bind.h"
[email protected]bf68a00b2011-04-07 17:28:269#include "base/file_util.h"
[email protected]9fc114672011-06-15 08:17:4810#include "base/i18n/number_formatting.h"
11#include "base/i18n/rtl.h"
[email protected]3b63f8f42011-03-28 01:54:1512#include "base/memory/scoped_ptr.h"
[email protected]3fc40c142011-12-01 13:09:0413#include "base/message_loop.h"
[email protected]795b76a2011-12-14 16:52:5314#include "base/scoped_temp_dir.h"
[email protected]7286e3fc2011-07-19 22:13:2415#include "base/stl_util.h"
[email protected]c2475df2011-09-07 23:52:2216#include "base/string16.h"
[email protected]eda58402011-09-21 19:32:0217#include "base/string_util.h"
[email protected]9fc114672011-06-15 08:17:4818#include "base/utf_string_conversions.h"
[email protected]047a03f2009-10-07 02:10:2019#include "build/build_config.h"
[email protected]aa9881c2011-08-15 18:01:1220#include "chrome/browser/download/chrome_download_manager_delegate.h"
[email protected]9fc114672011-06-15 08:17:4821#include "chrome/browser/download/download_item_model.h"
[email protected]e5dc4222010-08-30 22:16:3222#include "chrome/browser/download/download_prefs.h"
[email protected]594cd7d2010-07-21 03:23:5623#include "chrome/browser/download/download_util.h"
[email protected]37858e52010-08-26 00:22:0224#include "chrome/browser/prefs/pref_service.h"
[email protected]2941c2392010-07-15 22:54:3025#include "chrome/common/pref_names.h"
[email protected]a4ff9eae2011-08-01 19:58:1626#include "chrome/test/base/testing_profile.h"
[email protected]2606e5a92011-10-21 00:09:5227#include "content/browser/download/download_buffer.h"
[email protected]71bf3f5e2011-08-15 21:05:2228#include "content/browser/download/download_create_info.h"
[email protected]f6c2b5312011-11-16 22:31:3929#include "content/browser/download/download_file_impl.h"
[email protected]71bf3f5e2011-08-15 21:05:2230#include "content/browser/download/download_file_manager.h"
[email protected]2909e342011-10-29 00:46:5331#include "content/browser/download/download_id_factory.h"
[email protected]b39e7a88b2012-01-10 21:43:1732#include "content/browser/download/download_manager_impl.h"
[email protected]594e66fe2011-10-25 22:49:4133#include "content/browser/download/download_request_handle.h"
[email protected]71bf3f5e2011-08-15 21:05:2234#include "content/browser/download/download_status_updater.h"
[email protected]be76b7e2011-10-13 12:57:5735#include "content/browser/download/interrupt_reasons.h"
[email protected]f6c2b5312011-11-16 22:31:3936#include "content/browser/download/mock_download_file.h"
[email protected]71bf3f5e2011-08-15 21:05:2237#include "content/browser/download/mock_download_manager.h"
[email protected]e582fdd2011-12-20 16:48:1738#include "content/public/browser/download_item.h"
[email protected]c38831a12011-10-28 12:44:4939#include "content/test/test_browser_thread.h"
[email protected]9fc114672011-06-15 08:17:4840#include "grit/generated_resources.h"
[email protected]47a881b2011-08-29 22:59:2141#include "net/base/io_buffer.h"
[email protected]594cd7d2010-07-21 03:23:5642#include "testing/gmock/include/gmock/gmock.h"
43#include "testing/gmock_mutant.h"
initial.commit09911bf2008-07-26 23:55:2944#include "testing/gtest/include/gtest/gtest.h"
[email protected]9fc114672011-06-15 08:17:4845#include "ui/base/l10n/l10n_util.h"
[email protected]7a3b2632011-06-22 20:40:2246#include "ui/base/text/bytes_formatting.h"
initial.commit09911bf2008-07-26 23:55:2947
[email protected]e8c75812011-11-23 20:30:4748#if defined(USE_AURA) && defined(OS_WIN)
49// http://crbug.com/105200
50#define MAYBE_StartDownload DISABLED_StartDownload
51#define MAYBE_DownloadOverwriteTest DISABLED_DownloadOverwriteTest
52#define MAYBE_DownloadRemoveTest DISABLED_DownloadRemoveTest
53#else
54#define MAYBE_StartDownload StartDownload
55#define MAYBE_DownloadOverwriteTest DownloadOverwriteTest
56#define MAYBE_DownloadRemoveTest DownloadRemoveTest
57#endif
58
[email protected]e582fdd2011-12-20 16:48:1759using content::BrowserThread;
60using content::DownloadFile;
61using content::DownloadItem;
62using content::DownloadManager;
[email protected]ef9572e2012-01-04 22:14:1263using content::WebContents;
[email protected]e582fdd2011-12-20 16:48:1764
[email protected]159ffc1b2011-12-08 21:04:3565namespace {
66
67class MockDownloadFileFactory
68 : public DownloadFileManager::DownloadFileFactory {
69 public:
70 MockDownloadFileFactory() {}
71
72 virtual DownloadFile* CreateFile(DownloadCreateInfo* info,
73 const DownloadRequestHandle& request_handle,
[email protected]443853c62011-12-22 19:22:4174 DownloadManager* download_manager,
75 bool calculate_hash) OVERRIDE;
[email protected]159ffc1b2011-12-08 21:04:3576};
77
78DownloadFile* MockDownloadFileFactory::CreateFile(
79 DownloadCreateInfo* info,
80 const DownloadRequestHandle& request_handle,
[email protected]443853c62011-12-22 19:22:4181 DownloadManager* download_manager,
82 bool calculate_hash) {
[email protected]159ffc1b2011-12-08 21:04:3583 NOTREACHED();
84 return NULL;
85}
86
[email protected]2909e342011-10-29 00:46:5387DownloadId::Domain kValidIdDomain = "valid DownloadId::Domain";
88
[email protected]795b76a2011-12-14 16:52:5389class TestDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
90 public:
91 explicit TestDownloadManagerDelegate(Profile* profile)
92 : ChromeDownloadManagerDelegate(profile),
93 mark_content_dangerous_(false) {
94 }
95
[email protected]ef9572e2012-01-04 22:14:1296 virtual void ChooseDownloadPath(WebContents* web_contents,
[email protected]795b76a2011-12-14 16:52:5397 const FilePath& suggested_path,
98 void* data) OVERRIDE {
99 if (!expected_suggested_path_.empty()) {
100 EXPECT_STREQ(expected_suggested_path_.value().c_str(),
101 suggested_path.value().c_str());
102 }
103 if (file_selection_response_.empty()) {
104 BrowserThread::PostTask(
105 BrowserThread::UI, FROM_HERE,
106 base::Bind(&DownloadManager::FileSelectionCanceled,
107 download_manager_.get(),
108 base::Unretained(data)));
109 } else {
110 BrowserThread::PostTask(
111 BrowserThread::UI, FROM_HERE,
112 base::Bind(&DownloadManager::FileSelected,
113 download_manager_.get(),
114 file_selection_response_,
115 base::Unretained(data)));
116 }
117 expected_suggested_path_.clear();
118 file_selection_response_.clear();
119 }
120
121 void SetFileSelectionExpectation(const FilePath& suggested_path,
122 const FilePath& response) {
123 expected_suggested_path_ = suggested_path;
124 file_selection_response_ = response;
125 }
126
127 void SetMarkContentsDangerous(bool dangerous) {
128 mark_content_dangerous_ = dangerous;
129 }
130
131 virtual bool ShouldCompleteDownload(DownloadItem* item) {
132 if (mark_content_dangerous_) {
133 BrowserThread::PostTask(
134 BrowserThread::UI, FROM_HERE,
135 base::Bind(&TestDownloadManagerDelegate::MarkContentDangerous,
136 this, item->GetId()));
137 mark_content_dangerous_ = false;
138 return false;
139 } else {
140 return true;
141 }
142 }
143
144 private:
145 void MarkContentDangerous(int32 download_id) {
146 DownloadItem* item = download_manager_->GetActiveDownloadItem(download_id);
147 if (!item)
148 return;
149 item->MarkContentDangerous();
150 item->MaybeCompleteDownload();
151 }
152
153 FilePath expected_suggested_path_;
154 FilePath file_selection_response_;
155 bool mark_content_dangerous_;
156};
157
158} // namespace
159
[email protected]583844c2011-08-27 00:38:35160class DownloadManagerTest : public testing::Test {
initial.commit09911bf2008-07-26 23:55:29161 public:
[email protected]bf68a00b2011-04-07 17:28:26162 static const char* kTestData;
163 static const size_t kTestDataLen;
164
[email protected]2941c2392010-07-15 22:54:30165 DownloadManagerTest()
166 : profile_(new TestingProfile()),
[email protected]795b76a2011-12-14 16:52:53167 download_manager_delegate_(new TestDownloadManagerDelegate(
[email protected]e7557f172011-08-19 23:42:01168 profile_.get())),
[email protected]2909e342011-10-29 00:46:53169 id_factory_(new DownloadIdFactory(kValidIdDomain)),
[email protected]b39e7a88b2012-01-10 21:43:17170 download_manager_(new DownloadManagerImpl(
[email protected]2909e342011-10-29 00:46:53171 download_manager_delegate_,
172 id_factory_,
173 &download_status_updater_)),
[email protected]f5920322011-03-24 20:34:16174 ui_thread_(BrowserThread::UI, &message_loop_),
[email protected]2606e5a92011-10-21 00:09:52175 file_thread_(BrowserThread::FILE, &message_loop_),
176 download_buffer_(new content::DownloadBuffer) {
[email protected]2941c2392010-07-15 22:54:30177 download_manager_->Init(profile_.get());
[email protected]2588ea9d2011-08-22 20:59:53178 download_manager_delegate_->SetDownloadManager(download_manager_);
[email protected]2941c2392010-07-15 22:54:30179 }
180
181 ~DownloadManagerTest() {
[email protected]326a6a92010-09-10 20:21:13182 download_manager_->Shutdown();
[email protected]2941c2392010-07-15 22:54:30183 // profile_ must outlive download_manager_, so we explicitly delete
184 // download_manager_ first.
[email protected]1b2f8da2010-07-22 08:29:29185 download_manager_ = NULL;
[email protected]e7557f172011-08-19 23:42:01186 download_manager_delegate_ = NULL;
[email protected]1b2f8da2010-07-22 08:29:29187 profile_.reset(NULL);
188 message_loop_.RunAllPending();
initial.commit09911bf2008-07-26 23:55:29189 }
190
[email protected]bf68a00b2011-04-07 17:28:26191 void AddDownloadToFileManager(int id, DownloadFile* download_file) {
[email protected]2909e342011-10-29 00:46:53192 file_manager()->downloads_[DownloadId(kValidIdDomain, id)] =
[email protected]eda58402011-09-21 19:32:02193 download_file;
[email protected]bf68a00b2011-04-07 17:28:26194 }
195
[email protected]47a881b2011-08-29 22:59:21196 void OnResponseCompleted(int32 download_id, int64 size,
197 const std::string& hash) {
198 download_manager_->OnResponseCompleted(download_id, size, hash);
[email protected]bf68a00b2011-04-07 17:28:26199 }
200
[email protected]99cb7f82011-07-28 17:27:26201 void FileSelected(const FilePath& path, void* params) {
202 download_manager_->FileSelected(path, params);
[email protected]bf68a00b2011-04-07 17:28:26203 }
204
[email protected]4cd82f72011-05-23 19:15:01205 void ContinueDownloadWithPath(DownloadItem* download, const FilePath& path) {
206 download_manager_->ContinueDownloadWithPath(download, path);
[email protected]bf68a00b2011-04-07 17:28:26207 }
208
[email protected]47a881b2011-08-29 22:59:21209 void UpdateData(int32 id, const char* data, size_t length) {
210 // We are passing ownership of this buffer to the download file manager.
211 net::IOBuffer* io_buffer = new net::IOBuffer(length);
212 // We need |AddRef()| because we do a |Release()| in |UpdateDownload()|.
213 io_buffer->AddRef();
214 memcpy(io_buffer->data(), data, length);
215
[email protected]2606e5a92011-10-21 00:09:52216 download_buffer_->AddData(io_buffer, length);
[email protected]47a881b2011-08-29 22:59:21217
218 BrowserThread::PostTask(
219 BrowserThread::FILE, FROM_HERE,
[email protected]a3094072011-10-10 17:14:05220 base::Bind(&DownloadFileManager::UpdateDownload, file_manager_.get(),
[email protected]2909e342011-10-29 00:46:53221 DownloadId(kValidIdDomain, id), download_buffer_));
[email protected]47a881b2011-08-29 22:59:21222
223 message_loop_.RunAllPending();
224 }
225
[email protected]be76b7e2011-10-13 12:57:57226 void OnDownloadInterrupted(int32 download_id, int64 size,
[email protected]443853c62011-12-22 19:22:41227 const std::string& hash_state,
[email protected]be76b7e2011-10-13 12:57:57228 InterruptReason reason) {
[email protected]443853c62011-12-22 19:22:41229 download_manager_->OnDownloadInterrupted(download_id, size,
230 hash_state, reason);
[email protected]bf68a00b2011-04-07 17:28:26231 }
232
233 // Get the download item with ID |id|.
234 DownloadItem* GetActiveDownloadItem(int32 id) {
[email protected]5656f8a2011-11-17 16:12:58235 return download_manager_->GetActiveDownload(id);
[email protected]594cd7d2010-07-21 03:23:56236 }
237
initial.commit09911bf2008-07-26 23:55:29238 protected:
[email protected]a3d2bc42010-10-06 14:08:49239 DownloadStatusUpdater download_status_updater_;
[email protected]2941c2392010-07-15 22:54:30240 scoped_ptr<TestingProfile> profile_;
[email protected]795b76a2011-12-14 16:52:53241 scoped_refptr<TestDownloadManagerDelegate> download_manager_delegate_;
[email protected]2909e342011-10-29 00:46:53242 scoped_refptr<DownloadIdFactory> id_factory_;
initial.commit09911bf2008-07-26 23:55:29243 scoped_refptr<DownloadManager> download_manager_;
[email protected]594cd7d2010-07-21 03:23:56244 scoped_refptr<DownloadFileManager> file_manager_;
[email protected]dd3eac22008-08-26 07:28:34245 MessageLoopForUI message_loop_;
[email protected]c38831a12011-10-28 12:44:49246 content::TestBrowserThread ui_thread_;
247 content::TestBrowserThread file_thread_;
[email protected]2606e5a92011-10-21 00:09:52248 scoped_refptr<content::DownloadBuffer> download_buffer_;
initial.commit09911bf2008-07-26 23:55:29249
[email protected]594cd7d2010-07-21 03:23:56250 DownloadFileManager* file_manager() {
251 if (!file_manager_) {
[email protected]159ffc1b2011-12-08 21:04:35252 file_manager_ = new DownloadFileManager(NULL,
253 new MockDownloadFileFactory);
[email protected]5656f8a2011-11-17 16:12:58254 download_manager_->SetFileManager(file_manager_);
[email protected]594cd7d2010-07-21 03:23:56255 }
256 return file_manager_;
257 }
258
[email protected]4d818fee2010-06-06 13:32:27259 DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest);
initial.commit09911bf2008-07-26 23:55:29260};
261
[email protected]bf68a00b2011-04-07 17:28:26262const char* DownloadManagerTest::kTestData = "a;sdlfalsdfjalsdkfjad";
263const size_t DownloadManagerTest::kTestDataLen =
264 strlen(DownloadManagerTest::kTestData);
265
[email protected]f6c2b5312011-11-16 22:31:39266// A DownloadFile that we can inject errors into.
267class DownloadFileWithErrors : public DownloadFileImpl {
[email protected]47a881b2011-08-29 22:59:21268 public:
[email protected]443853c62011-12-22 19:22:41269 DownloadFileWithErrors(DownloadCreateInfo* info,
270 DownloadManager* manager,
271 bool calculate_hash);
[email protected]f6c2b5312011-11-16 22:31:39272 virtual ~DownloadFileWithErrors() {}
[email protected]47a881b2011-08-29 22:59:21273
[email protected]f6c2b5312011-11-16 22:31:39274 // BaseFile delegated functions.
[email protected]443853c62011-12-22 19:22:41275 virtual net::Error Initialize();
[email protected]f6c2b5312011-11-16 22:31:39276 virtual net::Error AppendDataToFile(const char* data, size_t data_len);
277 virtual net::Error Rename(const FilePath& full_path);
[email protected]47a881b2011-08-29 22:59:21278
[email protected]f6c2b5312011-11-16 22:31:39279 void set_forced_error(net::Error error) { forced_error_ = error; }
280 void clear_forced_error() { forced_error_ = net::OK; }
281 net::Error forced_error() const { return forced_error_; }
[email protected]47a881b2011-08-29 22:59:21282
[email protected]f6c2b5312011-11-16 22:31:39283 private:
284 net::Error ReturnError(net::Error function_error) {
285 if (forced_error_ != net::OK) {
286 net::Error ret = forced_error_;
287 clear_forced_error();
288 return ret;
289 }
290
291 return function_error;
292 }
293
294 net::Error forced_error_;
[email protected]47a881b2011-08-29 22:59:21295};
296
[email protected]f6c2b5312011-11-16 22:31:39297DownloadFileWithErrors::DownloadFileWithErrors(DownloadCreateInfo* info,
[email protected]443853c62011-12-22 19:22:41298 DownloadManager* manager,
299 bool calculate_hash)
300 : DownloadFileImpl(info,
301 new DownloadRequestHandle(),
302 manager,
303 calculate_hash),
[email protected]f6c2b5312011-11-16 22:31:39304 forced_error_(net::OK) {
[email protected]47a881b2011-08-29 22:59:21305}
306
[email protected]443853c62011-12-22 19:22:41307net::Error DownloadFileWithErrors::Initialize() {
308 return ReturnError(DownloadFileImpl::Initialize());
[email protected]47a881b2011-08-29 22:59:21309}
[email protected]f6c2b5312011-11-16 22:31:39310
311net::Error DownloadFileWithErrors::AppendDataToFile(const char* data,
312 size_t data_len) {
313 return ReturnError(DownloadFileImpl::AppendDataToFile(data, data_len));
314}
315
316net::Error DownloadFileWithErrors::Rename(const FilePath& full_path) {
317 return ReturnError(DownloadFileImpl::Rename(full_path));
[email protected]47a881b2011-08-29 22:59:21318}
319
[email protected]763f946a2009-01-06 19:04:39320namespace {
321
322const struct {
[email protected]2941c2392010-07-15 22:54:30323 const char* url;
324 const char* mime_type;
325 bool save_as;
326 bool prompt_for_download;
327 bool expected_save_as;
328} kStartDownloadCases[] = {
329 { "http://www.foo.com/dont-open.html",
330 "text/html",
331 false,
332 false,
333 false, },
334 { "http://www.foo.com/save-as.html",
335 "text/html",
336 true,
337 false,
338 true, },
339 { "http://www.foo.com/always-prompt.html",
340 "text/html",
341 false,
342 true,
343 true, },
[email protected]bac4f4b2011-03-05 02:01:40344 { "http://www.foo.com/user-script-text-html-mimetype.user.js",
[email protected]2941c2392010-07-15 22:54:30345 "text/html",
346 false,
[email protected]bac4f4b2011-03-05 02:01:40347 false,
[email protected]2941c2392010-07-15 22:54:30348 false, },
349 { "http://www.foo.com/extensionless-extension",
350 "application/x-chrome-extension",
351 true,
352 false,
353 true, },
354 { "http://www.foo.com/save-as.pdf",
355 "application/pdf",
356 true,
357 false,
358 true, },
[email protected]2fc93852011-01-08 22:13:56359 { "http://www.foo.com/sometimes_prompt.pdf",
[email protected]2941c2392010-07-15 22:54:30360 "application/pdf",
361 false,
362 true,
[email protected]2fc93852011-01-08 22:13:56363 false, },
364 { "http://www.foo.com/always_prompt.jar",
365 "application/jar",
366 false,
367 true,
[email protected]3366aca62010-10-20 01:18:24368 true, },
[email protected]2941c2392010-07-15 22:54:30369};
370
[email protected]594cd7d2010-07-21 03:23:56371const struct {
372 FilePath::StringType suggested_path;
[email protected]3ab4c0a2011-11-17 22:47:40373 DownloadStateInfo::DangerType danger;
[email protected]594cd7d2010-07-21 03:23:56374 bool finish_before_rename;
[email protected]594cd7d2010-07-21 03:23:56375 int expected_rename_count;
376} kDownloadRenameCases[] = {
[email protected]adb2f3d12011-01-23 16:24:54377 // Safe download, download finishes BEFORE file name determined.
378 // Renamed twice (linear path through UI). Crdownload file does not need
379 // to be deleted.
[email protected]3ab4c0a2011-11-17 22:47:40380 { FILE_PATH_LITERAL("foo.zip"), DownloadStateInfo::NOT_DANGEROUS, true, 2, },
381 // Potentially dangerous download (e.g., file is dangerous), download finishes
382 // BEFORE file name determined. Needs to be renamed only once.
383 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
384 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT, true, 1, },
385 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
386 DownloadStateInfo::DANGEROUS_FILE, true, 1, },
[email protected]adb2f3d12011-01-23 16:24:54387 // Safe download, download finishes AFTER file name determined.
[email protected]594cd7d2010-07-21 03:23:56388 // Needs to be renamed twice.
[email protected]3ab4c0a2011-11-17 22:47:40389 { FILE_PATH_LITERAL("foo.zip"), DownloadStateInfo::NOT_DANGEROUS, false, 2, },
390 // Potentially dangerous download, download finishes AFTER file name
391 // determined. Needs to be renamed only once.
392 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
393 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT, false, 1, },
394 { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
395 DownloadStateInfo::DANGEROUS_FILE, false, 1, },
[email protected]594cd7d2010-07-21 03:23:56396};
397
[email protected]f5920322011-03-24 20:34:16398// This is an observer that records what download IDs have opened a select
399// file dialog.
[email protected]e582fdd2011-12-20 16:48:17400class SelectFileObserver : public content::DownloadManager::Observer {
[email protected]f5920322011-03-24 20:34:16401 public:
402 explicit SelectFileObserver(DownloadManager* download_manager)
403 : download_manager_(download_manager) {
[email protected]bf68a00b2011-04-07 17:28:26404 DCHECK(download_manager_.get());
[email protected]f5920322011-03-24 20:34:16405 download_manager_->AddObserver(this);
406 }
407
408 ~SelectFileObserver() {
409 download_manager_->RemoveObserver(this);
410 }
411
412 // Downloadmanager::Observer functions.
413 virtual void ModelChanged() {}
414 virtual void ManagerGoingDown() {}
[email protected]fed38252011-07-08 17:26:50415 virtual void SelectFileDialogDisplayed(int32 id) {
[email protected]f5920322011-03-24 20:34:16416 file_dialog_ids_.insert(id);
417 }
418
419 bool ShowedFileDialogForId(int32 id) {
420 return file_dialog_ids_.find(id) != file_dialog_ids_.end();
421 }
422
423 private:
424 std::set<int32> file_dialog_ids_;
[email protected]bf68a00b2011-04-07 17:28:26425 scoped_refptr<DownloadManager> download_manager_;
426};
427
428// This observer tracks the progress of |DownloadItem|s.
429class ItemObserver : public DownloadItem::Observer {
430 public:
431 explicit ItemObserver(DownloadItem* tracked)
432 : tracked_(tracked), states_hit_(0),
[email protected]48837962011-04-19 17:03:29433 was_updated_(false), was_opened_(false) {
[email protected]bf68a00b2011-04-07 17:28:26434 DCHECK(tracked_);
435 tracked_->AddObserver(this);
436 // Record the initial state.
437 OnDownloadUpdated(tracked_);
438 }
439 ~ItemObserver() {
440 tracked_->RemoveObserver(this);
441 }
442
443 bool hit_state(int state) const {
444 return (1 << state) & states_hit_;
445 }
446 bool was_updated() const { return was_updated_; }
[email protected]bf68a00b2011-04-07 17:28:26447 bool was_opened() const { return was_opened_; }
448
449 private:
450 // DownloadItem::Observer methods
451 virtual void OnDownloadUpdated(DownloadItem* download) {
452 DCHECK_EQ(tracked_, download);
[email protected]c09a8fd2011-11-21 19:54:50453 states_hit_ |= (1 << download->GetState());
[email protected]bf68a00b2011-04-07 17:28:26454 was_updated_ = true;
455 }
[email protected]bf68a00b2011-04-07 17:28:26456 virtual void OnDownloadOpened(DownloadItem* download) {
457 DCHECK_EQ(tracked_, download);
[email protected]c09a8fd2011-11-21 19:54:50458 states_hit_ |= (1 << download->GetState());
[email protected]bf68a00b2011-04-07 17:28:26459 was_opened_ = true;
460 }
461
462 DownloadItem* tracked_;
463 int states_hit_;
464 bool was_updated_;
[email protected]bf68a00b2011-04-07 17:28:26465 bool was_opened_;
[email protected]f5920322011-03-24 20:34:16466};
467
[email protected]594cd7d2010-07-21 03:23:56468} // namespace
469
[email protected]e8c75812011-11-23 20:30:47470TEST_F(DownloadManagerTest, MAYBE_StartDownload) {
[email protected]c38831a12011-10-28 12:44:49471 content::TestBrowserThread io_thread(BrowserThread::IO, &message_loop_);
[email protected]f5920322011-03-24 20:34:16472 PrefService* prefs = profile_->GetPrefs();
[email protected]fed38252011-07-08 17:26:50473 prefs->SetFilePath(prefs::kDownloadDefaultDirectory, FilePath());
[email protected]e7557f172011-08-19 23:42:01474 DownloadPrefs* download_prefs =
475 DownloadPrefs::FromDownloadManager(download_manager_);
476 download_prefs->EnableAutoOpenBasedOnExtension(
[email protected]f5920322011-03-24 20:34:16477 FilePath(FILE_PATH_LITERAL("example.pdf")));
478
479 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kStartDownloadCases); ++i) {
480 prefs->SetBoolean(prefs::kPromptForDownload,
481 kStartDownloadCases[i].prompt_for_download);
482
483 SelectFileObserver observer(download_manager_);
[email protected]c9994e02011-05-24 20:52:19484 // Normally, the download system takes ownership of info, and is
485 // responsible for deleting it. In these unit tests, however, we
486 // don't call the function that deletes it, so we do so ourselves.
487 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:53488 info->download_id = DownloadId(kValidIdDomain, static_cast<int>(i));
[email protected]f5920322011-03-24 20:34:16489 info->prompt_user_for_save_location = kStartDownloadCases[i].save_as;
[email protected]8799e542011-04-20 03:47:34490 info->url_chain.push_back(GURL(kStartDownloadCases[i].url));
[email protected]f5920322011-03-24 20:34:16491 info->mime_type = kStartDownloadCases[i].mime_type;
[email protected]594e66fe2011-10-25 22:49:41492 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]f5920322011-03-24 20:34:16493
[email protected]c9994e02011-05-24 20:52:19494 DownloadFile* download_file(
[email protected]f6c2b5312011-11-16 22:31:39495 new DownloadFileImpl(info.get(), new DownloadRequestHandle(),
[email protected]443853c62011-12-22 19:22:41496 download_manager_, false));
[email protected]2909e342011-10-29 00:46:53497 AddDownloadToFileManager(info->download_id.local(), download_file);
[email protected]443853c62011-12-22 19:22:41498 download_file->Initialize();
[email protected]2909e342011-10-29 00:46:53499 download_manager_->StartDownload(info->download_id.local());
[email protected]f5920322011-03-24 20:34:16500 message_loop_.RunAllPending();
501
[email protected]c9994e02011-05-24 20:52:19502 // SelectFileObserver will have recorded any attempt to open the
[email protected]f5920322011-03-24 20:34:16503 // select file dialog.
[email protected]c9994e02011-05-24 20:52:19504 // Note that DownloadManager::FileSelectionCanceled() is never called.
[email protected]f5920322011-03-24 20:34:16505 EXPECT_EQ(kStartDownloadCases[i].expected_save_as,
506 observer.ShowedFileDialogForId(i));
[email protected]f5920322011-03-24 20:34:16507 }
508}
509
[email protected]795b76a2011-12-14 16:52:53510namespace {
511
512enum PromptForSaveLocation {
513 DONT_PROMPT,
514 PROMPT
515};
516
517enum ValidateDangerousDownload {
518 DONT_VALIDATE,
519 VALIDATE
520};
521
522// Test cases to be used with DownloadFilenameTest. The paths that are used in
523// test cases can contain "$dl" and "$alt" tokens which are replaced by a
524// default download path, and an alternate download path in
525// ExpandFilenameTestPath() below.
526const struct DownloadFilenameTestCase {
527
528 // Fields to be set in DownloadStateInfo when calling SetFileCheckResults().
529 const FilePath::CharType* suggested_path;
530 const FilePath::CharType* target_name;
531 PromptForSaveLocation prompt_user_for_save_location;
532 DownloadStateInfo::DangerType danger_type;
533
534 // If we receive a ChooseDownloadPath() call to prompt the user for a download
535 // location, |prompt_path| is the expected prompt path. The
536 // TestDownloadManagerDelegate will respond with |final_path|. If |final_path|
537 // is empty, then the file choose dialog be cancelled.
538 const FilePath::CharType* prompt_path;
539
540 // The expected intermediate path for the download.
541 const FilePath::CharType* intermediate_path;
542
543 // The expected final path for the download.
544 const FilePath::CharType* final_path;
545
546 // If this is a dangerous download, then we will either validate the download
547 // or delete it depending on the value of |validate_dangerous_download|.
548 ValidateDangerousDownload validate_dangerous_download;
549} kDownloadFilenameTestCases[] = {
550 {
551 // 0: A safe file is downloaded with no prompting.
552 FILE_PATH_LITERAL("$dl/foo.txt"),
553 FILE_PATH_LITERAL(""),
554 DONT_PROMPT,
555 DownloadStateInfo::NOT_DANGEROUS,
556 FILE_PATH_LITERAL(""),
557 FILE_PATH_LITERAL("$dl/foo.txt.crdownload"),
558 FILE_PATH_LITERAL("$dl/foo.txt"),
559 DONT_VALIDATE
560 },
561 {
562 // 1: A safe file is downloaded with prompting.
563 FILE_PATH_LITERAL("$dl/foo.txt"),
564 FILE_PATH_LITERAL(""),
565 PROMPT,
566 DownloadStateInfo::NOT_DANGEROUS,
567 FILE_PATH_LITERAL("$dl/foo.txt"),
568 FILE_PATH_LITERAL("$dl/foo.txt.crdownload"),
569 FILE_PATH_LITERAL("$dl/foo.txt"),
570 DONT_VALIDATE
571 },
572 {
573 // 2: A safe file is downloaded. The filename is changed before the dialog
574 // completes.
575 FILE_PATH_LITERAL("$dl/foo.txt"),
576 FILE_PATH_LITERAL(""),
577 PROMPT,
578 DownloadStateInfo::NOT_DANGEROUS,
579 FILE_PATH_LITERAL("$dl/foo.txt"),
580 FILE_PATH_LITERAL("$dl/bar.txt.crdownload"),
581 FILE_PATH_LITERAL("$dl/bar.txt"),
582 DONT_VALIDATE
583 },
584 {
585 // 3: A safe file is downloaded. The download path is changed before the
586 // dialog completes.
587 FILE_PATH_LITERAL("$dl/foo.txt"),
588 FILE_PATH_LITERAL(""),
589 PROMPT,
590 DownloadStateInfo::NOT_DANGEROUS,
591 FILE_PATH_LITERAL("$dl/foo.txt"),
592 FILE_PATH_LITERAL("$alt/bar.txt.crdownload"),
593 FILE_PATH_LITERAL("$alt/bar.txt"),
594 DONT_VALIDATE
595 },
596 {
597 // 4: Potentially dangerous content.
598 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
599 FILE_PATH_LITERAL("foo.exe"),
600 DONT_PROMPT,
601 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT,
602 FILE_PATH_LITERAL(""),
603 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
604 FILE_PATH_LITERAL("$dl/foo.exe"),
605 DONT_VALIDATE
606 },
607 {
608 // 5: Potentially dangerous content. Uses "Save as."
609 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
610 FILE_PATH_LITERAL("foo.exe"),
611 PROMPT,
612 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT,
613 FILE_PATH_LITERAL("$dl/foo.exe"),
614 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
615 FILE_PATH_LITERAL("$dl/foo.exe"),
616 DONT_VALIDATE
617 },
618 {
619 // 6: Potentially dangerous content. Uses "Save as." The download filename
620 // is changed before the dialog completes.
621 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
622 FILE_PATH_LITERAL("foo.exe"),
623 PROMPT,
624 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT,
625 FILE_PATH_LITERAL("$dl/foo.exe"),
626 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
627 FILE_PATH_LITERAL("$dl/bar.exe"),
628 DONT_VALIDATE
629 },
630 {
631 // 7: Potentially dangerous content. Uses "Save as." The download directory
632 // is changed before the dialog completes.
633 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
634 FILE_PATH_LITERAL("foo.exe"),
635 PROMPT,
636 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT,
637 FILE_PATH_LITERAL("$dl/foo.exe"),
638 FILE_PATH_LITERAL("$alt/Unconfirmed xxx.download"),
639 FILE_PATH_LITERAL("$alt/bar.exe"),
640 DONT_VALIDATE
641 },
642 {
643 // 8: Dangerous content. Saved directly.
644 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
645 FILE_PATH_LITERAL("foo.exe"),
646 PROMPT,
647 DownloadStateInfo::DANGEROUS_URL,
648 FILE_PATH_LITERAL(""),
649 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
650 FILE_PATH_LITERAL("$dl/foo.exe"),
651 VALIDATE
652 },
653 {
654 // 9: Dangerous content. Saved directly. Not validated.
655 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
656 FILE_PATH_LITERAL("foo.exe"),
657 DONT_PROMPT,
658 DownloadStateInfo::DANGEROUS_URL,
659 FILE_PATH_LITERAL(""),
660 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
661 FILE_PATH_LITERAL(""),
662 DONT_VALIDATE
663 },
664 {
665 // 10: Dangerous content. Uses "Save as." The download directory is changed
666 // before the dialog completes.
667 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
668 FILE_PATH_LITERAL("foo.exe"),
669 PROMPT,
670 DownloadStateInfo::DANGEROUS_URL,
671 FILE_PATH_LITERAL("$dl/foo.exe"),
672 FILE_PATH_LITERAL("$alt/Unconfirmed xxx.download"),
673 FILE_PATH_LITERAL("$alt/bar.exe"),
674 VALIDATE
675 },
676 {
677 // 11: A safe file is download. The target file exists, but we don't
678 // uniquify. Safe downloads are uniquified in ChromeDownloadManagerDelegate
679 // instead of DownloadManagerImpl.
680 FILE_PATH_LITERAL("$dl/exists.txt"),
681 FILE_PATH_LITERAL(""),
682 DONT_PROMPT,
683 DownloadStateInfo::NOT_DANGEROUS,
684 FILE_PATH_LITERAL(""),
685 FILE_PATH_LITERAL("$dl/exists.txt.crdownload"),
686 FILE_PATH_LITERAL("$dl/exists.txt"),
687 DONT_VALIDATE
688 },
689 {
690 // 12: A potentially dangerous file is download. The target file exists. The
691 // target path is uniquified.
692 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
693 FILE_PATH_LITERAL("exists.exe"),
694 DONT_PROMPT,
695 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT,
696 FILE_PATH_LITERAL(""),
697 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
698 FILE_PATH_LITERAL("$dl/exists (1).exe"),
699 DONT_VALIDATE
700 },
701 {
702 // 13: A dangerous file is download. The target file exists. The target path
703 // is uniquified.
704 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
705 FILE_PATH_LITERAL("exists.exe"),
706 DONT_PROMPT,
707 DownloadStateInfo::DANGEROUS_CONTENT,
708 FILE_PATH_LITERAL(""),
709 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
710 FILE_PATH_LITERAL("$dl/exists (1).exe"),
711 VALIDATE
712 },
713 {
714 // 14: A potentially dangerous file is download with prompting. The target
715 // file exists. The target path is not uniquified because the filename was
716 // given to us by the user.
717 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
718 FILE_PATH_LITERAL("exists.exe"),
719 PROMPT,
720 DownloadStateInfo::MAYBE_DANGEROUS_CONTENT,
721 FILE_PATH_LITERAL("$dl/exists.exe"),
722 FILE_PATH_LITERAL("$dl/Unconfirmed xxx.download"),
723 FILE_PATH_LITERAL("$dl/exists.exe"),
724 DONT_VALIDATE
725 },
726};
727
728FilePath ExpandFilenameTestPath(const FilePath::CharType* template_path,
729 const FilePath& downloads_dir,
730 const FilePath& alternate_dir) {
731 FilePath::StringType path(template_path);
732 ReplaceSubstringsAfterOffset(&path, 0, FILE_PATH_LITERAL("$dl"),
733 downloads_dir.value());
734 ReplaceSubstringsAfterOffset(&path, 0, FILE_PATH_LITERAL("$alt"),
735 alternate_dir.value());
736 FilePath file_path(path);
737#if defined(FILE_PATH_USES_WIN_SEPARATORS)
738 file_path = file_path.NormalizeWindowsPathSeparators();
739#endif
740 return file_path;
741}
742
743} // namespace
744
745TEST_F(DownloadManagerTest, DownloadFilenameTest) {
746 ScopedTempDir scoped_dl_dir;
747 ASSERT_TRUE(scoped_dl_dir.CreateUniqueTempDir());
748
749 FilePath downloads_dir(scoped_dl_dir.path());
750 FilePath alternate_dir(downloads_dir.Append(FILE_PATH_LITERAL("Foo")));
751
752 // We create a known file to test file uniquification.
753 file_util::WriteFile(downloads_dir.Append(FILE_PATH_LITERAL("exists.txt")),
754 "", 0);
755 file_util::WriteFile(downloads_dir.Append(FILE_PATH_LITERAL("exists.exe")),
756 "", 0);
757
758 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDownloadFilenameTestCases); ++i) {
759 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
760 info->download_id = DownloadId(kValidIdDomain, i);
761 info->url_chain.push_back(GURL());
762
763 MockDownloadFile::StatisticsRecorder recorder;
764 MockDownloadFile* download_file(new MockDownloadFile(
765 info.get(), DownloadRequestHandle(), download_manager_, &recorder));
766 FilePath suggested_path(ExpandFilenameTestPath(
767 kDownloadFilenameTestCases[i].suggested_path,
768 downloads_dir, alternate_dir));
769 FilePath prompt_path(ExpandFilenameTestPath(
770 kDownloadFilenameTestCases[i].prompt_path,
771 downloads_dir, alternate_dir));
772 FilePath intermediate_path(ExpandFilenameTestPath(
773 kDownloadFilenameTestCases[i].intermediate_path,
774 downloads_dir, alternate_dir));
775 FilePath final_path(ExpandFilenameTestPath(
776 kDownloadFilenameTestCases[i].final_path,
777 downloads_dir, alternate_dir));
778 // If |final_path| is empty, its a signal that the download doesn't
779 // complete. Therefore it will only go through a single rename.
780 int expected_rename_count = (final_path.empty() ? 1 : 2);
781
782 AddDownloadToFileManager(info->download_id.local(), download_file);
783
784 download_file->SetExpectedPath(0, intermediate_path);
785 if (!final_path.empty())
786 download_file->SetExpectedPath(1, final_path);
787
788 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
789 DownloadItem* download = GetActiveDownloadItem(i);
790 ASSERT_TRUE(download != NULL);
791
792 DownloadStateInfo state = download->GetStateInfo();
793 state.suggested_path = suggested_path;
794 state.danger = kDownloadFilenameTestCases[i].danger_type;
795 state.prompt_user_for_save_location =
796 (kDownloadFilenameTestCases[i].prompt_user_for_save_location == PROMPT);
797 state.target_name = FilePath(kDownloadFilenameTestCases[i].target_name);
798 if (state.danger == DownloadStateInfo::DANGEROUS_CONTENT) {
799 // DANGEROUS_CONTENT will only be known once we have all the data. We let
800 // our TestDownloadManagerDelegate handle it.
801 state.danger = DownloadStateInfo::MAYBE_DANGEROUS_CONTENT;
802 download_manager_delegate_->SetMarkContentsDangerous(true);
803 }
804 download->SetFileCheckResults(state);
805 download_manager_delegate_->SetFileSelectionExpectation(
806 prompt_path, final_path);
807 download_manager_->RestartDownload(i);
808 message_loop_.RunAllPending();
809
810 OnResponseCompleted(i, 1024, std::string("fake_hash"));
811 message_loop_.RunAllPending();
812
813 if (download->GetSafetyState() == DownloadItem::DANGEROUS) {
814 if (kDownloadFilenameTestCases[i].validate_dangerous_download == VALIDATE)
815 download->DangerousDownloadValidated();
816 else
817 download->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
818 message_loop_.RunAllPending();
819 // |download| might be deleted when we get here.
820 }
821
822 EXPECT_EQ(
823 expected_rename_count,
824 recorder.Count(MockDownloadFile::StatisticsRecorder::STAT_RENAME))
825 << "For test run " << i;
826 }
827}
828
[email protected]594cd7d2010-07-21 03:23:56829TEST_F(DownloadManagerTest, DownloadRenameTest) {
830 using ::testing::_;
831 using ::testing::CreateFunctor;
832 using ::testing::Invoke;
833 using ::testing::Return;
834
[email protected]594cd7d2010-07-21 03:23:56835 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDownloadRenameCases); ++i) {
[email protected]c9994e02011-05-24 20:52:19836 // Normally, the download system takes ownership of info, and is
837 // responsible for deleting it. In these unit tests, however, we
838 // don't call the function that deletes it, so we do so ourselves.
839 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:53840 info->download_id = DownloadId(kValidIdDomain, static_cast<int>(i));
[email protected]594cd7d2010-07-21 03:23:56841 info->prompt_user_for_save_location = false;
[email protected]30917cb2011-05-10 21:40:47842 info->url_chain.push_back(GURL());
[email protected]4cd82f72011-05-23 19:15:01843 const FilePath new_path(kDownloadRenameCases[i].suggested_path);
[email protected]594cd7d2010-07-21 03:23:56844
[email protected]f6c2b5312011-11-16 22:31:39845 MockDownloadFile::StatisticsRecorder recorder;
[email protected]bf68a00b2011-04-07 17:28:26846 MockDownloadFile* download_file(
[email protected]f6c2b5312011-11-16 22:31:39847 new MockDownloadFile(info.get(),
848 DownloadRequestHandle(),
849 download_manager_,
850 &recorder));
[email protected]2909e342011-10-29 00:46:53851 AddDownloadToFileManager(info->download_id.local(), download_file);
[email protected]594cd7d2010-07-21 03:23:56852
[email protected]bf68a00b2011-04-07 17:28:26853 // |download_file| is owned by DownloadFileManager.
[email protected]594cd7d2010-07-21 03:23:56854 if (kDownloadRenameCases[i].expected_rename_count == 1) {
[email protected]f6c2b5312011-11-16 22:31:39855 download_file->SetExpectedPath(0, new_path);
[email protected]594cd7d2010-07-21 03:23:56856 } else {
857 ASSERT_EQ(2, kDownloadRenameCases[i].expected_rename_count);
858 FilePath crdownload(download_util::GetCrDownloadPath(new_path));
[email protected]f6c2b5312011-11-16 22:31:39859 download_file->SetExpectedPath(0, crdownload);
860 download_file->SetExpectedPath(1, new_path);
[email protected]594cd7d2010-07-21 03:23:56861 }
[email protected]594e66fe2011-10-25 22:49:41862 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]88008002011-05-24 23:14:15863 DownloadItem* download = GetActiveDownloadItem(i);
864 ASSERT_TRUE(download != NULL);
[email protected]c09a8fd2011-11-21 19:54:50865 DownloadStateInfo state = download->GetStateInfo();
[email protected]3ab4c0a2011-11-17 22:47:40866 state.danger = kDownloadRenameCases[i].danger;
867 download->SetFileCheckResults(state);
[email protected]c2e76012010-12-23 21:10:29868
[email protected]4cd82f72011-05-23 19:15:01869 int32* id_ptr = new int32;
870 *id_ptr = i; // Deleted in FileSelected().
[email protected]594cd7d2010-07-21 03:23:56871 if (kDownloadRenameCases[i].finish_before_rename) {
[email protected]47a881b2011-08-29 22:59:21872 OnResponseCompleted(i, 1024, std::string("fake_hash"));
[email protected]f5920322011-03-24 20:34:16873 message_loop_.RunAllPending();
[email protected]99cb7f82011-07-28 17:27:26874 FileSelected(new_path, id_ptr);
[email protected]594cd7d2010-07-21 03:23:56875 } else {
[email protected]99cb7f82011-07-28 17:27:26876 FileSelected(new_path, id_ptr);
[email protected]f5920322011-03-24 20:34:16877 message_loop_.RunAllPending();
[email protected]47a881b2011-08-29 22:59:21878 OnResponseCompleted(i, 1024, std::string("fake_hash"));
[email protected]594cd7d2010-07-21 03:23:56879 }
[email protected]594cd7d2010-07-21 03:23:56880 message_loop_.RunAllPending();
[email protected]f6c2b5312011-11-16 22:31:39881 EXPECT_EQ(
882 kDownloadRenameCases[i].expected_rename_count,
883 recorder.Count(MockDownloadFile::StatisticsRecorder::STAT_RENAME));
[email protected]594cd7d2010-07-21 03:23:56884 }
885}
[email protected]bf68a00b2011-04-07 17:28:26886
887TEST_F(DownloadManagerTest, DownloadInterruptTest) {
888 using ::testing::_;
889 using ::testing::CreateFunctor;
890 using ::testing::Invoke;
891 using ::testing::Return;
892
[email protected]c9994e02011-05-24 20:52:19893 // Normally, the download system takes ownership of info, and is
894 // responsible for deleting it. In these unit tests, however, we
895 // don't call the function that deletes it, so we do so ourselves.
896 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:53897 info->download_id = DownloadId(kValidIdDomain, 0);
[email protected]bf68a00b2011-04-07 17:28:26898 info->prompt_user_for_save_location = false;
[email protected]30917cb2011-05-10 21:40:47899 info->url_chain.push_back(GURL());
[email protected]9fc114672011-06-15 08:17:48900 info->total_bytes = static_cast<int64>(kTestDataLen);
[email protected]bf68a00b2011-04-07 17:28:26901 const FilePath new_path(FILE_PATH_LITERAL("foo.zip"));
902 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
903
[email protected]f6c2b5312011-11-16 22:31:39904 MockDownloadFile::StatisticsRecorder recorder;
[email protected]bf68a00b2011-04-07 17:28:26905 MockDownloadFile* download_file(
[email protected]f6c2b5312011-11-16 22:31:39906 new MockDownloadFile(info.get(),
907 DownloadRequestHandle(),
908 download_manager_,
909 &recorder));
[email protected]2909e342011-10-29 00:46:53910 AddDownloadToFileManager(info->download_id.local(), download_file);
[email protected]bf68a00b2011-04-07 17:28:26911
912 // |download_file| is owned by DownloadFileManager.
[email protected]f6c2b5312011-11-16 22:31:39913 download_file->SetExpectedPath(0, cr_path);
[email protected]bf68a00b2011-04-07 17:28:26914
[email protected]594e66fe2011-10-25 22:49:41915 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]bf68a00b2011-04-07 17:28:26916
917 DownloadItem* download = GetActiveDownloadItem(0);
918 ASSERT_TRUE(download != NULL);
[email protected]9fc114672011-06-15 08:17:48919 scoped_ptr<DownloadItemModel> download_item_model(
920 new DownloadItemModel(download));
[email protected]bf68a00b2011-04-07 17:28:26921
[email protected]c09a8fd2011-11-21 19:54:50922 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
[email protected]d8ca4d12011-04-07 22:05:13923 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
[email protected]bf68a00b2011-04-07 17:28:26924
925 download_file->AppendDataToFile(kTestData, kTestDataLen);
926
[email protected]4cd82f72011-05-23 19:15:01927 ContinueDownloadWithPath(download, new_path);
[email protected]bf68a00b2011-04-07 17:28:26928 message_loop_.RunAllPending();
[email protected]f6c2b5312011-11-16 22:31:39929 EXPECT_EQ(1,
930 recorder.Count(MockDownloadFile::StatisticsRecorder::STAT_RENAME));
[email protected]bf68a00b2011-04-07 17:28:26931 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
932
[email protected]9fc114672011-06-15 08:17:48933 int64 error_size = 3;
[email protected]443853c62011-12-22 19:22:41934 OnDownloadInterrupted(0, error_size, "",
[email protected]be76b7e2011-10-13 12:57:57935 DOWNLOAD_INTERRUPT_REASON_FILE_ACCESS_DENIED);
[email protected]bf68a00b2011-04-07 17:28:26936 message_loop_.RunAllPending();
937
938 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
[email protected]bf68a00b2011-04-07 17:28:26939 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
940 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
941 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
942 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
943 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
944 EXPECT_TRUE(observer->was_updated());
[email protected]bf68a00b2011-04-07 17:28:26945 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:50946 EXPECT_FALSE(download->GetFileExternallyRemoved());
947 EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
[email protected]7a3b2632011-06-22 20:40:22948 ui::DataUnits amount_units = ui::GetByteDisplayUnits(kTestDataLen);
949 string16 simple_size =
950 ui::FormatBytesWithUnits(error_size, amount_units, false);
[email protected]9fc114672011-06-15 08:17:48951 string16 simple_total = base::i18n::GetDisplayStringInLTRDirectionality(
[email protected]7a3b2632011-06-22 20:40:22952 ui::FormatBytesWithUnits(kTestDataLen, amount_units, true));
[email protected]9fc114672011-06-15 08:17:48953 EXPECT_EQ(download_item_model->GetStatusText(),
954 l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED,
955 simple_size,
956 simple_total));
[email protected]bf68a00b2011-04-07 17:28:26957
[email protected]93af2272011-09-21 18:29:17958 download->Cancel(true);
[email protected]bf68a00b2011-04-07 17:28:26959
[email protected]bf68a00b2011-04-07 17:28:26960 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
961 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
962 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
963 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
964 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
965 EXPECT_TRUE(observer->was_updated());
[email protected]bf68a00b2011-04-07 17:28:26966 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:50967 EXPECT_FALSE(download->GetFileExternallyRemoved());
968 EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
969 EXPECT_EQ(download->GetReceivedBytes(), error_size);
970 EXPECT_EQ(download->GetTotalBytes(), static_cast<int64>(kTestDataLen));
[email protected]bf68a00b2011-04-07 17:28:26971}
972
[email protected]47a881b2011-08-29 22:59:21973// Test the behavior of DownloadFileManager and DownloadManager in the event
974// of a file error while writing the download to disk.
975TEST_F(DownloadManagerTest, DownloadFileErrorTest) {
976 // Create a temporary file and a mock stream.
977 FilePath path;
978 ASSERT_TRUE(file_util::CreateTemporaryFile(&path));
979
980 // This file stream will be used, until the first rename occurs.
[email protected]f6c2b5312011-11-16 22:31:39981 net::FileStream* stream = new net::FileStream;
982 ASSERT_EQ(0, stream->Open(
[email protected]47a881b2011-08-29 22:59:21983 path,
984 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE));
985
986 // Normally, the download system takes ownership of info, and is
987 // responsible for deleting it. In these unit tests, however, we
988 // don't call the function that deletes it, so we do so ourselves.
989 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:53990 static const int32 local_id = 0;
991 info->download_id = DownloadId(kValidIdDomain, local_id);
[email protected]47a881b2011-08-29 22:59:21992 info->prompt_user_for_save_location = false;
993 info->url_chain.push_back(GURL());
994 info->total_bytes = static_cast<int64>(kTestDataLen * 3);
995 info->save_info.file_path = path;
[email protected]f6c2b5312011-11-16 22:31:39996 info->save_info.file_stream.reset(stream);
[email protected]47a881b2011-08-29 22:59:21997
998 // Create a download file that we can insert errors into.
[email protected]f6c2b5312011-11-16 22:31:39999 DownloadFileWithErrors* download_file(new DownloadFileWithErrors(
[email protected]443853c62011-12-22 19:22:411000 info.get(), download_manager_, false));
1001 download_file->Initialize();
[email protected]2909e342011-10-29 00:46:531002 AddDownloadToFileManager(local_id, download_file);
[email protected]47a881b2011-08-29 22:59:211003
1004 // |download_file| is owned by DownloadFileManager.
[email protected]594e66fe2011-10-25 22:49:411005 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]47a881b2011-08-29 22:59:211006
1007 DownloadItem* download = GetActiveDownloadItem(0);
1008 ASSERT_TRUE(download != NULL);
1009 // This will keep track of what should be displayed on the shelf.
1010 scoped_ptr<DownloadItemModel> download_item_model(
1011 new DownloadItemModel(download));
1012
[email protected]c09a8fd2011-11-21 19:54:501013 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
[email protected]47a881b2011-08-29 22:59:211014 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
1015
1016 // Add some data before finalizing the file name.
[email protected]2909e342011-10-29 00:46:531017 UpdateData(local_id, kTestData, kTestDataLen);
[email protected]47a881b2011-08-29 22:59:211018
1019 // Finalize the file name.
1020 ContinueDownloadWithPath(download, path);
1021 message_loop_.RunAllPending();
1022 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
1023
1024 // Add more data.
[email protected]2909e342011-10-29 00:46:531025 UpdateData(local_id, kTestData, kTestDataLen);
[email protected]47a881b2011-08-29 22:59:211026
1027 // Add more data, but an error occurs.
[email protected]f6c2b5312011-11-16 22:31:391028 download_file->set_forced_error(net::ERR_FAILED);
[email protected]2909e342011-10-29 00:46:531029 UpdateData(local_id, kTestData, kTestDataLen);
[email protected]47a881b2011-08-29 22:59:211030
1031 // Check the state. The download should have been interrupted.
1032 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
1033 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
1034 EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
1035 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
1036 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
1037 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
1038 EXPECT_TRUE(observer->was_updated());
1039 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:501040 EXPECT_FALSE(download->GetFileExternallyRemoved());
1041 EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
[email protected]47a881b2011-08-29 22:59:211042
1043 // Check the download shelf's information.
[email protected]f6c2b5312011-11-16 22:31:391044 size_t error_size = kTestDataLen * 3;
[email protected]e5e120f2011-09-23 23:08:151045 size_t total_size = kTestDataLen * 3;
[email protected]47a881b2011-08-29 22:59:211046 ui::DataUnits amount_units = ui::GetByteDisplayUnits(kTestDataLen);
1047 string16 simple_size =
1048 ui::FormatBytesWithUnits(error_size, amount_units, false);
1049 string16 simple_total = base::i18n::GetDisplayStringInLTRDirectionality(
[email protected]e5e120f2011-09-23 23:08:151050 ui::FormatBytesWithUnits(total_size, amount_units, true));
[email protected]47a881b2011-08-29 22:59:211051 EXPECT_EQ(l10n_util::GetStringFUTF16(IDS_DOWNLOAD_STATUS_INTERRUPTED,
1052 simple_size,
1053 simple_total),
1054 download_item_model->GetStatusText());
1055
1056 // Clean up.
[email protected]93af2272011-09-21 18:29:171057 download->Cancel(true);
[email protected]47a881b2011-08-29 22:59:211058 message_loop_.RunAllPending();
1059}
1060
[email protected]bf68a00b2011-04-07 17:28:261061TEST_F(DownloadManagerTest, DownloadCancelTest) {
1062 using ::testing::_;
1063 using ::testing::CreateFunctor;
1064 using ::testing::Invoke;
1065 using ::testing::Return;
1066
[email protected]c9994e02011-05-24 20:52:191067 // Normally, the download system takes ownership of info, and is
1068 // responsible for deleting it. In these unit tests, however, we
1069 // don't call the function that deletes it, so we do so ourselves.
1070 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:531071 info->download_id = DownloadId(kValidIdDomain, 0);
[email protected]bf68a00b2011-04-07 17:28:261072 info->prompt_user_for_save_location = false;
[email protected]30917cb2011-05-10 21:40:471073 info->url_chain.push_back(GURL());
[email protected]bf68a00b2011-04-07 17:28:261074 const FilePath new_path(FILE_PATH_LITERAL("foo.zip"));
1075 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
1076
1077 MockDownloadFile* download_file(
[email protected]f6c2b5312011-11-16 22:31:391078 new MockDownloadFile(info.get(),
1079 DownloadRequestHandle(),
1080 download_manager_,
1081 NULL));
[email protected]2909e342011-10-29 00:46:531082 AddDownloadToFileManager(info->download_id.local(), download_file);
[email protected]bf68a00b2011-04-07 17:28:261083
1084 // |download_file| is owned by DownloadFileManager.
[email protected]f6c2b5312011-11-16 22:31:391085 download_file->SetExpectedPath(0, cr_path);
[email protected]bf68a00b2011-04-07 17:28:261086
[email protected]594e66fe2011-10-25 22:49:411087 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]bf68a00b2011-04-07 17:28:261088
1089 DownloadItem* download = GetActiveDownloadItem(0);
1090 ASSERT_TRUE(download != NULL);
[email protected]9fc114672011-06-15 08:17:481091 scoped_ptr<DownloadItemModel> download_item_model(
1092 new DownloadItemModel(download));
[email protected]bf68a00b2011-04-07 17:28:261093
[email protected]c09a8fd2011-11-21 19:54:501094 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
[email protected]d8ca4d12011-04-07 22:05:131095 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
[email protected]bf68a00b2011-04-07 17:28:261096
[email protected]4cd82f72011-05-23 19:15:011097 ContinueDownloadWithPath(download, new_path);
[email protected]bf68a00b2011-04-07 17:28:261098 message_loop_.RunAllPending();
1099 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
1100
1101 download_file->AppendDataToFile(kTestData, kTestDataLen);
1102
[email protected]93af2272011-09-21 18:29:171103 download->Cancel(false);
[email protected]bf68a00b2011-04-07 17:28:261104 message_loop_.RunAllPending();
1105
[email protected]93af2272011-09-21 18:29:171106 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
[email protected]bf68a00b2011-04-07 17:28:261107 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
1108 EXPECT_TRUE(observer->hit_state(DownloadItem::CANCELLED));
1109 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
1110 EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
1111 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
1112 EXPECT_TRUE(observer->was_updated());
[email protected]bf68a00b2011-04-07 17:28:261113 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:501114 EXPECT_FALSE(download->GetFileExternallyRemoved());
1115 EXPECT_EQ(DownloadItem::CANCELLED, download->GetState());
[email protected]9fc114672011-06-15 08:17:481116 EXPECT_EQ(download_item_model->GetStatusText(),
1117 l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_CANCELED));
[email protected]bf68a00b2011-04-07 17:28:261118
1119 EXPECT_FALSE(file_util::PathExists(new_path));
1120 EXPECT_FALSE(file_util::PathExists(cr_path));
1121}
[email protected]8fa1eeb52011-04-13 14:18:021122
[email protected]e8c75812011-11-23 20:30:471123TEST_F(DownloadManagerTest, MAYBE_DownloadOverwriteTest) {
[email protected]8fa1eeb52011-04-13 14:18:021124 using ::testing::_;
1125 using ::testing::CreateFunctor;
1126 using ::testing::Invoke;
1127 using ::testing::Return;
1128
1129 // Create a temporary directory.
1130 ScopedTempDir temp_dir_;
1131 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1132
1133 // File names we're using.
1134 const FilePath new_path(temp_dir_.path().AppendASCII("foo.txt"));
1135 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
1136 EXPECT_FALSE(file_util::PathExists(new_path));
1137
1138 // Create the file that we will overwrite. Will be automatically cleaned
1139 // up when temp_dir_ is destroyed.
1140 FILE* fp = file_util::OpenFile(new_path, "w");
1141 file_util::CloseFile(fp);
1142 EXPECT_TRUE(file_util::PathExists(new_path));
1143
1144 // Construct the unique file name that normally would be created, but
1145 // which we will override.
[email protected]ec865262011-08-23 20:01:481146 int uniquifier = DownloadFile::GetUniquePathNumber(new_path);
[email protected]8fa1eeb52011-04-13 14:18:021147 FilePath unique_new_path = new_path;
1148 EXPECT_NE(0, uniquifier);
[email protected]ec865262011-08-23 20:01:481149 DownloadFile::AppendNumberToPath(&unique_new_path, uniquifier);
[email protected]8fa1eeb52011-04-13 14:18:021150
[email protected]c9994e02011-05-24 20:52:191151 // Normally, the download system takes ownership of info, and is
1152 // responsible for deleting it. In these unit tests, however, we
1153 // don't call the function that deletes it, so we do so ourselves.
1154 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:531155 info->download_id = DownloadId(kValidIdDomain, 0);
[email protected]8fa1eeb52011-04-13 14:18:021156 info->prompt_user_for_save_location = true;
[email protected]30917cb2011-05-10 21:40:471157 info->url_chain.push_back(GURL());
[email protected]8fa1eeb52011-04-13 14:18:021158
[email protected]594e66fe2011-10-25 22:49:411159 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]8fa1eeb52011-04-13 14:18:021160
1161 DownloadItem* download = GetActiveDownloadItem(0);
1162 ASSERT_TRUE(download != NULL);
[email protected]9fc114672011-06-15 08:17:481163 scoped_ptr<DownloadItemModel> download_item_model(
1164 new DownloadItemModel(download));
[email protected]8fa1eeb52011-04-13 14:18:021165
[email protected]c09a8fd2011-11-21 19:54:501166 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
[email protected]8fa1eeb52011-04-13 14:18:021167 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
1168
1169 // Create and initialize the download file. We're bypassing the first part
1170 // of the download process and skipping to the part after the final file
1171 // name has been chosen, so we need to initialize the download file
1172 // properly.
1173 DownloadFile* download_file(
[email protected]f6c2b5312011-11-16 22:31:391174 new DownloadFileImpl(info.get(), new DownloadRequestHandle(),
[email protected]443853c62011-12-22 19:22:411175 download_manager_, false));
[email protected]8fa1eeb52011-04-13 14:18:021176 download_file->Rename(cr_path);
1177 // This creates the .crdownload version of the file.
[email protected]443853c62011-12-22 19:22:411178 download_file->Initialize();
[email protected]8fa1eeb52011-04-13 14:18:021179 // |download_file| is owned by DownloadFileManager.
[email protected]2909e342011-10-29 00:46:531180 AddDownloadToFileManager(info->download_id.local(), download_file);
[email protected]8fa1eeb52011-04-13 14:18:021181
[email protected]4cd82f72011-05-23 19:15:011182 ContinueDownloadWithPath(download, new_path);
[email protected]8fa1eeb52011-04-13 14:18:021183 message_loop_.RunAllPending();
1184 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
1185
1186 download_file->AppendDataToFile(kTestData, kTestDataLen);
1187
1188 // Finish the download.
[email protected]47a881b2011-08-29 22:59:211189 OnResponseCompleted(0, kTestDataLen, "");
[email protected]8fa1eeb52011-04-13 14:18:021190 message_loop_.RunAllPending();
1191
1192 // Download is complete.
1193 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
1194 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
1195 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
1196 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
1197 EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
1198 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
1199 EXPECT_TRUE(observer->was_updated());
[email protected]8fa1eeb52011-04-13 14:18:021200 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:501201 EXPECT_FALSE(download->GetFileExternallyRemoved());
1202 EXPECT_EQ(DownloadItem::COMPLETE, download->GetState());
[email protected]7a8edaf2011-11-28 20:58:481203 EXPECT_EQ(download_item_model->GetStatusText(), string16());
[email protected]8fa1eeb52011-04-13 14:18:021204
1205 EXPECT_TRUE(file_util::PathExists(new_path));
1206 EXPECT_FALSE(file_util::PathExists(cr_path));
1207 EXPECT_FALSE(file_util::PathExists(unique_new_path));
1208 std::string file_contents;
1209 EXPECT_TRUE(file_util::ReadFileToString(new_path, &file_contents));
1210 EXPECT_EQ(std::string(kTestData), file_contents);
1211}
[email protected]9fc114672011-06-15 08:17:481212
[email protected]e8c75812011-11-23 20:30:471213TEST_F(DownloadManagerTest, MAYBE_DownloadRemoveTest) {
[email protected]9fc114672011-06-15 08:17:481214 using ::testing::_;
1215 using ::testing::CreateFunctor;
1216 using ::testing::Invoke;
1217 using ::testing::Return;
1218
1219 // Create a temporary directory.
1220 ScopedTempDir temp_dir_;
1221 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
1222
1223 // File names we're using.
1224 const FilePath new_path(temp_dir_.path().AppendASCII("foo.txt"));
1225 const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
1226 EXPECT_FALSE(file_util::PathExists(new_path));
1227
1228 // Normally, the download system takes ownership of info, and is
1229 // responsible for deleting it. In these unit tests, however, we
1230 // don't call the function that deletes it, so we do so ourselves.
1231 scoped_ptr<DownloadCreateInfo> info(new DownloadCreateInfo);
[email protected]2909e342011-10-29 00:46:531232 info->download_id = DownloadId(kValidIdDomain, 0);
[email protected]9fc114672011-06-15 08:17:481233 info->prompt_user_for_save_location = true;
1234 info->url_chain.push_back(GURL());
1235
[email protected]594e66fe2011-10-25 22:49:411236 download_manager_->CreateDownloadItem(info.get(), DownloadRequestHandle());
[email protected]9fc114672011-06-15 08:17:481237
1238 DownloadItem* download = GetActiveDownloadItem(0);
1239 ASSERT_TRUE(download != NULL);
1240 scoped_ptr<DownloadItemModel> download_item_model(
1241 new DownloadItemModel(download));
1242
[email protected]c09a8fd2011-11-21 19:54:501243 EXPECT_EQ(DownloadItem::IN_PROGRESS, download->GetState());
[email protected]9fc114672011-06-15 08:17:481244 scoped_ptr<ItemObserver> observer(new ItemObserver(download));
1245
1246 // Create and initialize the download file. We're bypassing the first part
1247 // of the download process and skipping to the part after the final file
1248 // name has been chosen, so we need to initialize the download file
1249 // properly.
1250 DownloadFile* download_file(
[email protected]f6c2b5312011-11-16 22:31:391251 new DownloadFileImpl(info.get(), new DownloadRequestHandle(),
[email protected]443853c62011-12-22 19:22:411252 download_manager_, false));
[email protected]9fc114672011-06-15 08:17:481253 download_file->Rename(cr_path);
1254 // This creates the .crdownload version of the file.
[email protected]443853c62011-12-22 19:22:411255 download_file->Initialize();
[email protected]9fc114672011-06-15 08:17:481256 // |download_file| is owned by DownloadFileManager.
[email protected]2909e342011-10-29 00:46:531257 AddDownloadToFileManager(info->download_id.local(), download_file);
[email protected]9fc114672011-06-15 08:17:481258
1259 ContinueDownloadWithPath(download, new_path);
1260 message_loop_.RunAllPending();
1261 EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
1262
1263 download_file->AppendDataToFile(kTestData, kTestDataLen);
1264
1265 // Finish the download.
[email protected]47a881b2011-08-29 22:59:211266 OnResponseCompleted(0, kTestDataLen, "");
[email protected]9fc114672011-06-15 08:17:481267 message_loop_.RunAllPending();
1268
1269 // Download is complete.
1270 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
1271 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
1272 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
1273 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
1274 EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
1275 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
1276 EXPECT_TRUE(observer->was_updated());
1277 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:501278 EXPECT_FALSE(download->GetFileExternallyRemoved());
1279 EXPECT_EQ(DownloadItem::COMPLETE, download->GetState());
[email protected]7a8edaf2011-11-28 20:58:481280 EXPECT_EQ(download_item_model->GetStatusText(), string16());
[email protected]9fc114672011-06-15 08:17:481281
1282 EXPECT_TRUE(file_util::PathExists(new_path));
1283 EXPECT_FALSE(file_util::PathExists(cr_path));
1284
1285 // Remove the downloaded file.
1286 ASSERT_TRUE(file_util::Delete(new_path, false));
1287 download->OnDownloadedFileRemoved();
1288 message_loop_.RunAllPending();
1289
1290 EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
1291 EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
1292 EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
1293 EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
1294 EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
1295 EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
1296 EXPECT_TRUE(observer->was_updated());
1297 EXPECT_FALSE(observer->was_opened());
[email protected]c09a8fd2011-11-21 19:54:501298 EXPECT_TRUE(download->GetFileExternallyRemoved());
1299 EXPECT_EQ(DownloadItem::COMPLETE, download->GetState());
[email protected]9fc114672011-06-15 08:17:481300 EXPECT_EQ(download_item_model->GetStatusText(),
1301 l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_REMOVED));
1302
1303 EXPECT_FALSE(file_util::PathExists(new_path));
1304}