• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <string>
6 #include <set>
7 
8 #include "base/file_util.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util-inl.h"
11 #include "base/string_util.h"
12 #include "build/build_config.h"
13 #include "chrome/browser/download/download_file.h"
14 #include "chrome/browser/download/download_file_manager.h"
15 #include "chrome/browser/download/download_item.h"
16 #include "chrome/browser/download/download_manager.h"
17 #include "chrome/browser/download/download_prefs.h"
18 #include "chrome/browser/download/download_status_updater.h"
19 #include "chrome/browser/download/download_util.h"
20 #include "chrome/browser/download/mock_download_manager.h"
21 #include "chrome/browser/history/download_create_info.h"
22 #include "chrome/browser/prefs/pref_service.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/test/testing_profile.h"
25 #include "content/browser/browser_thread.h"
26 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gmock_mutant.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29 
30 class DownloadManagerTest : public testing::Test {
31  public:
32   static const char* kTestData;
33   static const size_t kTestDataLen;
34 
DownloadManagerTest()35   DownloadManagerTest()
36       : profile_(new TestingProfile()),
37         download_manager_(new MockDownloadManager(&download_status_updater_)),
38         ui_thread_(BrowserThread::UI, &message_loop_),
39         file_thread_(BrowserThread::FILE, &message_loop_) {
40     download_manager_->Init(profile_.get());
41   }
42 
~DownloadManagerTest()43   ~DownloadManagerTest() {
44     download_manager_->Shutdown();
45     // profile_ must outlive download_manager_, so we explicitly delete
46     // download_manager_ first.
47     download_manager_ = NULL;
48     profile_.reset(NULL);
49     message_loop_.RunAllPending();
50   }
51 
AddDownloadToFileManager(int id,DownloadFile * download_file)52   void AddDownloadToFileManager(int id, DownloadFile* download_file) {
53     file_manager()->downloads_[id] = download_file;
54   }
55 
OnAllDataSaved(int32 download_id,int64 size,const std::string & hash)56   void OnAllDataSaved(int32 download_id, int64 size, const std::string& hash) {
57     download_manager_->OnAllDataSaved(download_id, size, hash);
58   }
59 
FileSelected(const FilePath & path,int index,void * params)60   void FileSelected(const FilePath& path, int index, void* params) {
61     download_manager_->FileSelected(path, index, params);
62   }
63 
AttachDownloadItem(DownloadCreateInfo * info)64   void AttachDownloadItem(DownloadCreateInfo* info) {
65     download_manager_->AttachDownloadItem(info);
66   }
67 
OnDownloadError(int32 download_id,int64 size,int os_error)68   void OnDownloadError(int32 download_id, int64 size, int os_error) {
69     download_manager_->OnDownloadError(download_id, size, os_error);
70   }
71 
72   // Get the download item with ID |id|.
GetActiveDownloadItem(int32 id)73   DownloadItem* GetActiveDownloadItem(int32 id) {
74     if (ContainsKey(download_manager_->active_downloads_, id))
75       return download_manager_->active_downloads_[id];
76     return NULL;
77   }
78 
79  protected:
80   DownloadStatusUpdater download_status_updater_;
81   scoped_ptr<TestingProfile> profile_;
82   scoped_refptr<DownloadManager> download_manager_;
83   scoped_refptr<DownloadFileManager> file_manager_;
84   MessageLoopForUI message_loop_;
85   BrowserThread ui_thread_;
86   BrowserThread file_thread_;
87 
file_manager()88   DownloadFileManager* file_manager() {
89     if (!file_manager_) {
90       file_manager_ = new DownloadFileManager(NULL);
91       download_manager_->file_manager_ = file_manager_;
92     }
93     return file_manager_;
94   }
95 
96   // Make sure download item |id| was set with correct safety state for
97   // given |is_dangerous_file| and |is_dangerous_url|.
VerifySafetyState(bool is_dangerous_file,bool is_dangerous_url,int id)98   bool VerifySafetyState(bool is_dangerous_file,
99                          bool is_dangerous_url,
100                          int id) {
101     DownloadItem::SafetyState safety_state =
102         download_manager_->GetDownloadItem(id)->safety_state();
103     return (is_dangerous_file || is_dangerous_url) ?
104         safety_state != DownloadItem::SAFE : safety_state == DownloadItem::SAFE;
105   }
106 
107   DISALLOW_COPY_AND_ASSIGN(DownloadManagerTest);
108 };
109 
110 const char* DownloadManagerTest::kTestData = "a;sdlfalsdfjalsdkfjad";
111 const size_t DownloadManagerTest::kTestDataLen =
112     strlen(DownloadManagerTest::kTestData);
113 
114 namespace {
115 
116 const struct {
117   const char* url;
118   const char* mime_type;
119   bool save_as;
120   bool prompt_for_download;
121   bool expected_save_as;
122 } kStartDownloadCases[] = {
123   { "http://www.foo.com/dont-open.html",
124     "text/html",
125     false,
126     false,
127     false, },
128   { "http://www.foo.com/save-as.html",
129     "text/html",
130     true,
131     false,
132     true, },
133   { "http://www.foo.com/always-prompt.html",
134     "text/html",
135     false,
136     true,
137     true, },
138   { "http://www.foo.com/user-script-text-html-mimetype.user.js",
139     "text/html",
140     false,
141     false,
142     false, },
143   { "http://www.foo.com/extensionless-extension",
144     "application/x-chrome-extension",
145     true,
146     false,
147     true, },
148   { "http://www.foo.com/save-as.pdf",
149     "application/pdf",
150     true,
151     false,
152     true, },
153   { "http://www.foo.com/sometimes_prompt.pdf",
154     "application/pdf",
155     false,
156     true,
157     false, },
158   { "http://www.foo.com/always_prompt.jar",
159     "application/jar",
160     false,
161     true,
162     true, },
163 };
164 
165 const struct {
166   FilePath::StringType suggested_path;
167   bool is_dangerous_file;
168   bool is_dangerous_url;
169   bool finish_before_rename;
170   int expected_rename_count;
171 } kDownloadRenameCases[] = {
172   // Safe download, download finishes BEFORE file name determined.
173   // Renamed twice (linear path through UI).  Crdownload file does not need
174   // to be deleted.
175   { FILE_PATH_LITERAL("foo.zip"),
176     false, false, true, 2, },
177   // Dangerous download (file is dangerous or download URL is not safe or both),
178   // download finishes BEFORE file name determined. Needs to be renamed only
179   // once.
180   { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
181     true, false, true, 1, },
182   { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
183     false, true, true, 1, },
184   { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
185     true, true, true, 1, },
186   // Safe download, download finishes AFTER file name determined.
187   // Needs to be renamed twice.
188   { FILE_PATH_LITERAL("foo.zip"),
189     false, false, false, 2, },
190   // Dangerous download, download finishes AFTER file name determined.
191   // Needs to be renamed only once.
192   { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
193     true, false, false, 1, },
194   { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
195     false, true, false, 1, },
196   { FILE_PATH_LITERAL("Unconfirmed xxx.crdownload"),
197     true, true, false, 1, },
198 };
199 
200 class MockDownloadFile : public DownloadFile {
201  public:
MockDownloadFile(DownloadCreateInfo * info,DownloadManager * manager)202   MockDownloadFile(DownloadCreateInfo* info, DownloadManager* manager)
203       : DownloadFile(info, manager), renamed_count_(0) { }
~MockDownloadFile()204   virtual ~MockDownloadFile() { Destructed(); }
205   MOCK_METHOD1(Rename, bool(const FilePath&));
206   MOCK_METHOD0(Destructed, void());
207 
TestMultipleRename(int expected_count,const FilePath & expected,const FilePath & path)208   bool TestMultipleRename(
209       int expected_count, const FilePath& expected,
210       const FilePath& path) {
211     ++renamed_count_;
212     EXPECT_EQ(expected_count, renamed_count_);
213     EXPECT_EQ(expected.value(), path.value());
214     return true;
215   }
216 
217  private:
218   int renamed_count_;
219 };
220 
221 // This is an observer that records what download IDs have opened a select
222 // file dialog.
223 class SelectFileObserver : public DownloadManager::Observer {
224  public:
SelectFileObserver(DownloadManager * download_manager)225   explicit SelectFileObserver(DownloadManager* download_manager)
226       : download_manager_(download_manager) {
227     DCHECK(download_manager_.get());
228     download_manager_->AddObserver(this);
229   }
230 
~SelectFileObserver()231   ~SelectFileObserver() {
232     download_manager_->RemoveObserver(this);
233   }
234 
235   // Downloadmanager::Observer functions.
ModelChanged()236   virtual void ModelChanged() {}
ManagerGoingDown()237   virtual void ManagerGoingDown() {}
SelectFileDialogDisplayed(int32 id)238   virtual void SelectFileDialogDisplayed(int32 id) {
239     file_dialog_ids_.insert(id);
240   }
241 
ShowedFileDialogForId(int32 id)242   bool ShowedFileDialogForId(int32 id) {
243     return file_dialog_ids_.find(id) != file_dialog_ids_.end();
244   }
245 
246  private:
247   std::set<int32> file_dialog_ids_;
248   scoped_refptr<DownloadManager> download_manager_;
249 };
250 
251 // This observer tracks the progress of |DownloadItem|s.
252 class ItemObserver : public DownloadItem::Observer {
253  public:
ItemObserver(DownloadItem * tracked)254   explicit ItemObserver(DownloadItem* tracked)
255       : tracked_(tracked), states_hit_(0),
256         was_updated_(false), was_opened_(false) {
257     DCHECK(tracked_);
258     tracked_->AddObserver(this);
259     // Record the initial state.
260     OnDownloadUpdated(tracked_);
261   }
~ItemObserver()262   ~ItemObserver() {
263     tracked_->RemoveObserver(this);
264   }
265 
hit_state(int state) const266   bool hit_state(int state) const {
267     return (1 << state) & states_hit_;
268   }
was_updated() const269   bool was_updated() const { return was_updated_; }
was_opened() const270   bool was_opened() const { return was_opened_; }
271 
272  private:
273   // DownloadItem::Observer methods
OnDownloadUpdated(DownloadItem * download)274   virtual void OnDownloadUpdated(DownloadItem* download) {
275     DCHECK_EQ(tracked_, download);
276     states_hit_ |= (1 << download->state());
277     was_updated_ = true;
278   }
OnDownloadOpened(DownloadItem * download)279   virtual void OnDownloadOpened(DownloadItem* download) {
280     DCHECK_EQ(tracked_, download);
281     states_hit_ |= (1 << download->state());
282     was_opened_ = true;
283   }
284 
285   DownloadItem* tracked_;
286   int states_hit_;
287   bool was_updated_;
288   bool was_opened_;
289 };
290 
291 }  // namespace
292 
293 #if !defined(OS_CHROMEOS)
294 
TEST_F(DownloadManagerTest,StartDownload)295 TEST_F(DownloadManagerTest, StartDownload) {
296   BrowserThread io_thread(BrowserThread::IO, &message_loop_);
297   PrefService* prefs = profile_->GetPrefs();
298   prefs->SetFilePath(prefs::kDownloadDefaultDirectory, FilePath());
299   download_manager_->download_prefs()->EnableAutoOpenBasedOnExtension(
300       FilePath(FILE_PATH_LITERAL("example.pdf")));
301 
302   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kStartDownloadCases); ++i) {
303     prefs->SetBoolean(prefs::kPromptForDownload,
304                       kStartDownloadCases[i].prompt_for_download);
305 
306     SelectFileObserver observer(download_manager_);
307     DownloadCreateInfo* info = new DownloadCreateInfo;
308     info->download_id = static_cast<int>(i);
309     info->prompt_user_for_save_location = kStartDownloadCases[i].save_as;
310     info->url_chain.push_back(GURL(kStartDownloadCases[i].url));
311     info->mime_type = kStartDownloadCases[i].mime_type;
312     download_manager_->CreateDownloadItem(info);
313 
314     DownloadFile* download_file(new DownloadFile(info, download_manager_));
315     AddDownloadToFileManager(info->download_id, download_file);
316     download_file->Initialize(false);
317     download_manager_->StartDownload(info);
318     message_loop_.RunAllPending();
319 
320     // NOTE: At this point, |AttachDownloadItem| will have been run if we don't
321     // need to prompt the user, so |info| could have been destructed.
322     // This means that we can't check any of its values.
323     // However, SelectFileObserver will have recorded any attempt to open the
324     // select file dialog.
325     EXPECT_EQ(kStartDownloadCases[i].expected_save_as,
326               observer.ShowedFileDialogForId(i));
327 
328     // If the Save As dialog pops up, it never reached
329     // DownloadManager::AttachDownloadItem(), and never deleted info or
330     // completed.  This cleans up info.
331     // Note that DownloadManager::FileSelectionCanceled() is never called.
332     if (observer.ShowedFileDialogForId(i)) {
333       delete info;
334     }
335   }
336 }
337 
338 #endif // !defined(OS_CHROMEOS)
339 
TEST_F(DownloadManagerTest,DownloadRenameTest)340 TEST_F(DownloadManagerTest, DownloadRenameTest) {
341   using ::testing::_;
342   using ::testing::CreateFunctor;
343   using ::testing::Invoke;
344   using ::testing::Return;
345 
346   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDownloadRenameCases); ++i) {
347     // |info| will be destroyed in download_manager_.
348     DownloadCreateInfo* info(new DownloadCreateInfo);
349     info->download_id = static_cast<int>(i);
350     info->prompt_user_for_save_location = false;
351     info->url_chain.push_back(GURL());
352     info->is_dangerous_file = kDownloadRenameCases[i].is_dangerous_file;
353     info->is_dangerous_url = kDownloadRenameCases[i].is_dangerous_url;
354     FilePath new_path(kDownloadRenameCases[i].suggested_path);
355 
356     MockDownloadFile* download_file(
357         new MockDownloadFile(info, download_manager_));
358     AddDownloadToFileManager(info->download_id, download_file);
359 
360     // |download_file| is owned by DownloadFileManager.
361     ::testing::Mock::AllowLeak(download_file);
362     EXPECT_CALL(*download_file, Destructed()).Times(1);
363 
364     if (kDownloadRenameCases[i].expected_rename_count == 1) {
365       EXPECT_CALL(*download_file, Rename(new_path)).WillOnce(Return(true));
366     } else {
367       ASSERT_EQ(2, kDownloadRenameCases[i].expected_rename_count);
368       FilePath crdownload(download_util::GetCrDownloadPath(new_path));
369       EXPECT_CALL(*download_file, Rename(_))
370           .WillOnce(testing::WithArgs<0>(Invoke(CreateFunctor(
371               download_file, &MockDownloadFile::TestMultipleRename,
372               1, crdownload))))
373           .WillOnce(testing::WithArgs<0>(Invoke(CreateFunctor(
374               download_file, &MockDownloadFile::TestMultipleRename,
375               2, new_path))));
376     }
377     download_manager_->CreateDownloadItem(info);
378 
379     if (kDownloadRenameCases[i].finish_before_rename) {
380       OnAllDataSaved(i, 1024, std::string("fake_hash"));
381       message_loop_.RunAllPending();
382       FileSelected(new_path, i, info);
383     } else {
384       FileSelected(new_path, i, info);
385       message_loop_.RunAllPending();
386       OnAllDataSaved(i, 1024, std::string("fake_hash"));
387     }
388 
389     message_loop_.RunAllPending();
390     EXPECT_TRUE(VerifySafetyState(kDownloadRenameCases[i].is_dangerous_file,
391                                   kDownloadRenameCases[i].is_dangerous_url,
392                                   i));
393   }
394 }
395 
TEST_F(DownloadManagerTest,DownloadInterruptTest)396 TEST_F(DownloadManagerTest, DownloadInterruptTest) {
397   using ::testing::_;
398   using ::testing::CreateFunctor;
399   using ::testing::Invoke;
400   using ::testing::Return;
401 
402   // |info| will be destroyed in download_manager_.
403   DownloadCreateInfo* info(new DownloadCreateInfo);
404   info->download_id = static_cast<int>(0);
405   info->prompt_user_for_save_location = false;
406   info->url_chain.push_back(GURL());
407   info->is_dangerous_file = false;
408   info->is_dangerous_url = false;
409   const FilePath new_path(FILE_PATH_LITERAL("foo.zip"));
410   const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
411 
412   MockDownloadFile* download_file(
413       new MockDownloadFile(info, download_manager_));
414   AddDownloadToFileManager(info->download_id, download_file);
415 
416   // |download_file| is owned by DownloadFileManager.
417   ::testing::Mock::AllowLeak(download_file);
418   EXPECT_CALL(*download_file, Destructed()).Times(1);
419 
420   EXPECT_CALL(*download_file, Rename(cr_path)).WillOnce(Return(true));
421 
422   download_manager_->CreateDownloadItem(info);
423 
424   DownloadItem* download = GetActiveDownloadItem(0);
425   ASSERT_TRUE(download != NULL);
426 
427   EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
428   scoped_ptr<ItemObserver> observer(new ItemObserver(download));
429 
430   download_file->AppendDataToFile(kTestData, kTestDataLen);
431 
432   info->path = new_path;
433   AttachDownloadItem(info);
434   message_loop_.RunAllPending();
435   EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
436 
437   OnDownloadError(0, 1024, -6);
438   message_loop_.RunAllPending();
439 
440   EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
441   EXPECT_EQ(DownloadItem::INTERRUPTED, download->state());
442   EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
443   EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
444   EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
445   EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
446   EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
447   EXPECT_TRUE(observer->was_updated());
448   EXPECT_FALSE(observer->was_opened());
449 
450   download->Cancel(true);
451 
452   EXPECT_EQ(DownloadItem::INTERRUPTED, download->state());
453   EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
454   EXPECT_TRUE(observer->hit_state(DownloadItem::INTERRUPTED));
455   EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
456   EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
457   EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
458   EXPECT_TRUE(observer->was_updated());
459   EXPECT_FALSE(observer->was_opened());
460 }
461 
TEST_F(DownloadManagerTest,DownloadCancelTest)462 TEST_F(DownloadManagerTest, DownloadCancelTest) {
463   using ::testing::_;
464   using ::testing::CreateFunctor;
465   using ::testing::Invoke;
466   using ::testing::Return;
467 
468   // |info| will be destroyed in download_manager_.
469   DownloadCreateInfo* info(new DownloadCreateInfo);
470   info->download_id = static_cast<int>(0);
471   info->prompt_user_for_save_location = false;
472   info->url_chain.push_back(GURL());
473   info->is_dangerous_file = false;
474   info->is_dangerous_url = false;
475   const FilePath new_path(FILE_PATH_LITERAL("foo.zip"));
476   const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
477 
478   MockDownloadFile* download_file(
479       new MockDownloadFile(info, download_manager_));
480   AddDownloadToFileManager(info->download_id, download_file);
481 
482   // |download_file| is owned by DownloadFileManager.
483   ::testing::Mock::AllowLeak(download_file);
484   EXPECT_CALL(*download_file, Destructed()).Times(1);
485 
486   EXPECT_CALL(*download_file, Rename(cr_path)).WillOnce(Return(true));
487 
488   download_manager_->CreateDownloadItem(info);
489 
490   DownloadItem* download = GetActiveDownloadItem(0);
491   ASSERT_TRUE(download != NULL);
492 
493   EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
494   scoped_ptr<ItemObserver> observer(new ItemObserver(download));
495 
496   info->path = new_path;
497   AttachDownloadItem(info);
498   message_loop_.RunAllPending();
499   EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
500 
501   download_file->AppendDataToFile(kTestData, kTestDataLen);
502 
503   download->Cancel(false);
504   message_loop_.RunAllPending();
505 
506   EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
507   EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
508   EXPECT_TRUE(observer->hit_state(DownloadItem::CANCELLED));
509   EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
510   EXPECT_FALSE(observer->hit_state(DownloadItem::COMPLETE));
511   EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
512   EXPECT_TRUE(observer->was_updated());
513   EXPECT_FALSE(observer->was_opened());
514 
515   EXPECT_FALSE(file_util::PathExists(new_path));
516   EXPECT_FALSE(file_util::PathExists(cr_path));
517 }
518 
TEST_F(DownloadManagerTest,DownloadOverwriteTest)519 TEST_F(DownloadManagerTest, DownloadOverwriteTest) {
520   using ::testing::_;
521   using ::testing::CreateFunctor;
522   using ::testing::Invoke;
523   using ::testing::Return;
524 
525   // Create a temporary directory.
526   ScopedTempDir temp_dir_;
527   ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
528 
529   // File names we're using.
530   const FilePath new_path(temp_dir_.path().AppendASCII("foo.txt"));
531   const FilePath cr_path(download_util::GetCrDownloadPath(new_path));
532   EXPECT_FALSE(file_util::PathExists(new_path));
533 
534   // Create the file that we will overwrite.  Will be automatically cleaned
535   // up when temp_dir_ is destroyed.
536   FILE* fp = file_util::OpenFile(new_path, "w");
537   file_util::CloseFile(fp);
538   EXPECT_TRUE(file_util::PathExists(new_path));
539 
540   // Construct the unique file name that normally would be created, but
541   // which we will override.
542   int uniquifier = download_util::GetUniquePathNumber(new_path);
543   FilePath unique_new_path = new_path;
544   EXPECT_NE(0, uniquifier);
545   download_util::AppendNumberToPath(&unique_new_path, uniquifier);
546 
547   // |info| will be destroyed in download_manager_.
548   DownloadCreateInfo* info(new DownloadCreateInfo);
549   info->download_id = static_cast<int>(0);
550   info->prompt_user_for_save_location = true;
551   info->url_chain.push_back(GURL());
552   info->is_dangerous_file = false;
553   info->is_dangerous_url = false;
554 
555   download_manager_->CreateDownloadItem(info);
556 
557   DownloadItem* download = GetActiveDownloadItem(0);
558   ASSERT_TRUE(download != NULL);
559 
560   EXPECT_EQ(DownloadItem::IN_PROGRESS, download->state());
561   scoped_ptr<ItemObserver> observer(new ItemObserver(download));
562 
563   // Create and initialize the download file.  We're bypassing the first part
564   // of the download process and skipping to the part after the final file
565   // name has been chosen, so we need to initialize the download file
566   // properly.
567   DownloadFile* download_file(
568       new DownloadFile(info, download_manager_));
569   download_file->Rename(cr_path);
570   // This creates the .crdownload version of the file.
571   download_file->Initialize(false);
572   // |download_file| is owned by DownloadFileManager.
573   AddDownloadToFileManager(info->download_id, download_file);
574 
575   info->path = new_path;
576   AttachDownloadItem(info);
577   message_loop_.RunAllPending();
578   EXPECT_TRUE(GetActiveDownloadItem(0) != NULL);
579 
580   download_file->AppendDataToFile(kTestData, kTestDataLen);
581 
582   // Finish the download.
583   OnAllDataSaved(0, kTestDataLen, "");
584   message_loop_.RunAllPending();
585 
586   // Download is complete.
587   EXPECT_TRUE(GetActiveDownloadItem(0) == NULL);
588   EXPECT_TRUE(observer->hit_state(DownloadItem::IN_PROGRESS));
589   EXPECT_FALSE(observer->hit_state(DownloadItem::CANCELLED));
590   EXPECT_FALSE(observer->hit_state(DownloadItem::INTERRUPTED));
591   EXPECT_TRUE(observer->hit_state(DownloadItem::COMPLETE));
592   EXPECT_FALSE(observer->hit_state(DownloadItem::REMOVING));
593   EXPECT_TRUE(observer->was_updated());
594   EXPECT_FALSE(observer->was_opened());
595   EXPECT_EQ(DownloadItem::COMPLETE, download->state());
596 
597   EXPECT_TRUE(file_util::PathExists(new_path));
598   EXPECT_FALSE(file_util::PathExists(cr_path));
599   EXPECT_FALSE(file_util::PathExists(unique_new_path));
600   std::string file_contents;
601   EXPECT_TRUE(file_util::ReadFileToString(new_path, &file_contents));
602   EXPECT_EQ(std::string(kTestData), file_contents);
603 }
604