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