1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// found in the LICENSE file.
4201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
5201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/file_path.h"
6201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/file_util.h"
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_temp_dir.h"
9201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/path_service.h"
10201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/test/test_file_util.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/utf_string_conversions.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/browser_process.h"
13201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/download/download_item.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/download/download_file_manager.h"
15201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/download/download_manager.h"
16201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/download/download_prefs.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/download/download_shelf.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/history/download_create_info.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/history/history.h"
20201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/net/url_request_mock_http_job.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/net/url_request_slow_download_job.h"
22201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/prefs/pref_service.h"
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser_list.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
27201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/chrome_paths.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/common/pref_names.h"
29201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/url_constants.h"
30201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/test/in_process_browser_test.h"
31201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/test/ui_test_utils.h"
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/cancelable_request.h"
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/resource_dispatcher_host.h"
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/page_transition_types.h"
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/base/net_util.h"
36201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "testing/gtest/include/gtest/gtest.h"
37201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochnamespace {
39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
40201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Variation of DownloadsCompleteObserver from ui_test_utils.cc; the
41201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// specifically targeted download tests need finer granularity on waiting.
42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Construction of this class defines a system state, based on some number
43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// of downloads being seen in a particular state + other events that
44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// may occur in the download system.  That state will be recorded if it
45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// occurs at any point after construction.  When that state occurs, the class
46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// is considered finished.  Callers may either probe for the finished state, or
47201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// wait on it.
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// TODO(rdsmith): Detect manager going down, remove pointer to
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// DownloadManager, transition to finished.  (For right now we
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// just use a scoped_refptr<> to keep it around, but that may cause
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// timeouts on waiting if a DownloadManager::Shutdown() occurs which
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// cancels our in-progress downloads.)
54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass DownloadsObserver : public DownloadManager::Observer,
55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                          public DownloadItem::Observer {
56201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch public:
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create an object that will be considered finished when |wait_count|
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // download items have entered state |download_finished_state|.
59201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // If |finish_on_select_file| is true, the object will also be
60201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // considered finished if the DownloadManager raises a
61201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // SelectFileDialogDisplayed() notification.
62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
63201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // TODO(rdsmith): Add option of "dangerous accept/reject dialog" as
64201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // a unblocking event; if that shows up when you aren't expecting it,
65201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // it'll result in a hang/timeout as we'll never get to final rename.
66201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // This probably means rewriting the interface to take a list of events
67201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // to treat as completion events.
68201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DownloadsObserver(DownloadManager* download_manager,
69201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                    size_t wait_count,
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    DownloadItem::DownloadState download_finished_state,
71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                    bool finish_on_select_file)
72201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      : download_manager_(download_manager),
73201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        wait_count_(wait_count),
74201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        finished_downloads_at_construction_(0),
75201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        waiting_(false),
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        download_finished_state_(download_finished_state),
77201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        finish_on_select_file_(finish_on_select_file),
78201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        select_file_dialog_seen_(false) {
79201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    download_manager_->AddObserver(this);  // Will call initial ModelChanged().
80201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    finished_downloads_at_construction_ = finished_downloads_.size();
81201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ~DownloadsObserver() {
84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
85201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    for (; it != downloads_observed_.end(); ++it) {
86201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      (*it)->RemoveObserver(this);
87201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
88201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    download_manager_->RemoveObserver(this);
89201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
90201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
91201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // State accessors.
92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool select_file_dialog_seen() { return select_file_dialog_seen_; }
93201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
94201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Wait for whatever state was specified in the constructor.
95201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void WaitForFinished() {
96201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (!IsFinished()) {
97201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      waiting_ = true;
98201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      ui_test_utils::RunMessageLoop();
99201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      waiting_ = false;
100201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
101201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
102201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
103201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Return true if everything's happened that we're configured for.
104201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool IsFinished() {
105201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (finished_downloads_.size() - finished_downloads_at_construction_
106201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        >= wait_count_)
107201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return true;
108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return (finish_on_select_file_ && select_file_dialog_seen_);
109201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
110201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
111201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // DownloadItem::Observer
112201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void OnDownloadUpdated(DownloadItem* download) {
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (download->state() == download_finished_state_)
114201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      DownloadInFinalState(download);
115201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
116201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
117201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void OnDownloadOpened(DownloadItem* download) {}
118201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
119201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // DownloadManager::Observer
120201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  virtual void ModelChanged() {
121201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Regenerate DownloadItem observers.  If there are any download items
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // in our final state, note them in |finished_downloads_|
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // (done by |OnDownloadUpdated()|).
124201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::vector<DownloadItem*> downloads;
125201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    download_manager_->SearchDownloads(string16(), &downloads);
126201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
127201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    std::vector<DownloadItem*>::iterator it = downloads.begin();
128201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    for (; it != downloads.end(); ++it) {
129201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      OnDownloadUpdated(*it);  // Safe to call multiple times; checks state.
130201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
131201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      std::set<DownloadItem*>::const_iterator
132201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          finished_it(finished_downloads_.find(*it));
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      std::set<DownloadItem*>::iterator
134201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          observed_it(downloads_observed_.find(*it));
135201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
136201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      // If it isn't finished and we're aren't observing it, start.
137201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (finished_it == finished_downloads_.end() &&
138201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          observed_it == downloads_observed_.end()) {
139201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        (*it)->AddObserver(this);
140201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        downloads_observed_.insert(*it);
141201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        continue;
142201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      }
143201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
144201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      // If it is finished and we are observing it, stop.
145201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      if (finished_it != finished_downloads_.end() &&
146201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch          observed_it != downloads_observed_.end()) {
147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        (*it)->RemoveObserver(this);
148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        downloads_observed_.erase(observed_it);
149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        continue;
150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      }
151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void SelectFileDialogDisplayed(int32 /* id */) {
155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    select_file_dialog_seen_ = true;
156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SignalIfFinished();
157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private:
160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Called when we know that a download item is in a final state.
161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Note that this is not the same as it first transitioning in to the
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // final state; multiple notifications may occur once the item is in
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // that state.  So we keep our own track of transitions into final.
164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void DownloadInFinalState(DownloadItem* download) {
165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (finished_downloads_.find(download) != finished_downloads_.end()) {
166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      // We've already seen terminal state on this download.
167201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      return;
168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    }
169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Record the transition.
171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    finished_downloads_.insert(download);
172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    SignalIfFinished();
174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  void SignalIfFinished() {
177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    if (waiting_ && IsFinished())
178201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      MessageLoopForUI::current()->Quit();
179201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
180201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
181201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // The observed download manager.
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<DownloadManager> download_manager_;
183201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
184201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // The set of DownloadItem's that have transitioned to their finished state
185201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // since construction of this object.  When the size of this array
186201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // reaches wait_count_, we're done.
187201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<DownloadItem*> finished_downloads_;
188201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
189201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // The set of DownloadItem's we are currently observing.  Generally there
190201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // won't be any overlap with the above; once we see the final state
191201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // on a DownloadItem, we'll stop observing it.
192201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  std::set<DownloadItem*> downloads_observed_;
193201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
194201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // The number of downloads to wait on completing.
195201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  size_t wait_count_;
196201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
197201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // The number of downloads entered in final state in initial
198201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // ModelChanged().  We use |finished_downloads_| to track the incoming
199201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // transitions to final state we should ignore, and to track the
200201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // number of final state transitions that occurred between
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // construction and return from wait.  But some downloads may be in our
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // final state (and thus be entered into |finished_downloads_|) when we
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // construct this class.  We don't want to count those in our transition
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // to finished.
205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  int finished_downloads_at_construction_;
206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
207201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Whether an internal message loop has been started and must be quit upon
208201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // all downloads completing.
209201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool waiting_;
210201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The state on which to consider the DownloadItem finished.
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadItem::DownloadState download_finished_state_;
213201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
214201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // True if we should transition the DownloadsObserver to finished if
215201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // the select file dialog comes up.
216201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool finish_on_select_file_;
217201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
218201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // True if we've seen the select file dialog.
219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  bool select_file_dialog_seen_;
220201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
221201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(DownloadsObserver);
222201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch};
223201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// WaitForFlush() returns after:
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//      * There are no IN_PROGRESS download items remaining on the
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//        DownloadManager.
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//      * There have been two round trip messages through the file and
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen//        IO threads.
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// This almost certainly means that a Download cancel has propagated through
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// the system.
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass DownloadsFlushObserver
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : public DownloadManager::Observer,
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      public DownloadItem::Observer,
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      public base::RefCountedThreadSafe<DownloadsFlushObserver> {
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit DownloadsFlushObserver(DownloadManager* download_manager)
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : download_manager_(download_manager),
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        waiting_for_zero_inprogress_(true) { }
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void WaitForFlush() {
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_manager_->AddObserver(this);
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui_test_utils::RunMessageLoop();
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DownloadsManager observer methods.
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void ModelChanged() {
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Model has changed, so there may be more DownloadItems to observe.
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CheckDownloadsInProgress(true);
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DownloadItem observer methods.
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnDownloadUpdated(DownloadItem* download) {
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // No change in DownloadItem set on manager.
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    CheckDownloadsInProgress(false);
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void OnDownloadOpened(DownloadItem* download) {}
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  friend class base::RefCountedThreadSafe<DownloadsFlushObserver>;
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ~DownloadsFlushObserver() {
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_manager_->RemoveObserver(this);
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         it != downloads_observed_.end(); ++it) {
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (*it)->RemoveObserver(this);
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If we're waiting for that flush point, check the number
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // of downloads in the IN_PROGRESS state and take appropriate
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // action.  If requested, also observes all downloads while iterating.
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void CheckDownloadsInProgress(bool observe_downloads) {
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (waiting_for_zero_inprogress_) {
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      int count = 0;
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::vector<DownloadItem*> downloads;
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      download_manager_->SearchDownloads(string16(), &downloads);
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::vector<DownloadItem*>::iterator it = downloads.begin();
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      for (; it != downloads.end(); ++it) {
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if ((*it)->state() == DownloadItem::IN_PROGRESS)
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          count++;
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (observe_downloads) {
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          if (downloads_observed_.find(*it) == downloads_observed_.end()) {
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            (*it)->AddObserver(this);
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          }
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // Download items are forever, and we don't want to make
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // assumptions about future state transitions, so once we
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          // start observing them, we don't stop until destruction.
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (count == 0) {
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        waiting_for_zero_inprogress_ = false;
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Stop observing DownloadItems.  We maintain the observation
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // of DownloadManager so that we don't have to independently track
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // whether we are observing it for conditional destruction.
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        for (std::set<DownloadItem*>::iterator it = downloads_observed_.begin();
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             it != downloads_observed_.end(); ++it) {
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          (*it)->RemoveObserver(this);
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        }
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        downloads_observed_.clear();
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // Trigger next step.  We need to go past the IO thread twice, as
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        // there's a self-task posting in the IO thread cancel path.
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::PostTask(
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            BrowserThread::FILE, FROM_HERE,
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            NewRunnableMethod(this,
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              &DownloadsFlushObserver::PingFileThread, 2));
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void PingFileThread(int cycle) {
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::IO, FROM_HERE,
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &DownloadsFlushObserver::PingIOThread,
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          cycle));
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void PingIOThread(int cycle) {
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (--cycle) {
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::PostTask(
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          BrowserThread::UI, FROM_HERE,
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          NewRunnableMethod(this, &DownloadsFlushObserver::PingFileThread,
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            cycle));
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::PostTask(
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask());
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadManager* download_manager_;
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::set<DownloadItem*> downloads_observed_;
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool waiting_for_zero_inprogress_;
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(DownloadsFlushObserver);
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Collect the information from FILE and IO threads needed for the Cancel
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test, specifically the number of outstanding requests on the
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// ResourceDispatcherHost and the number of pending downloads on the
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// DownloadFileManager.
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass CancelTestDataCollector
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : public base::RefCountedThreadSafe<CancelTestDataCollector> {
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CancelTestDataCollector()
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : resource_dispatcher_host_(
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          g_browser_process->resource_dispatcher_host()),
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        rdh_pending_requests_(0),
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        dfm_pending_downloads_(0) { }
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void WaitForDataCollected() {
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::IO, FROM_HERE,
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &CancelTestDataCollector::IOInfoCollector));
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui_test_utils::RunMessageLoop();
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int rdh_pending_requests() { return rdh_pending_requests_; }
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int dfm_pending_downloads() { return dfm_pending_downloads_; }
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen protected:
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  friend class base::RefCountedThreadSafe<CancelTestDataCollector>;
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual ~CancelTestDataCollector() {}
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void IOInfoCollector() {
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    download_file_manager_ = resource_dispatcher_host_->download_file_manager();
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    rdh_pending_requests_ = resource_dispatcher_host_->pending_requests();
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::FILE, FROM_HERE,
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableMethod(this, &CancelTestDataCollector::FileInfoCollector));
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void FileInfoCollector() {
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dfm_pending_downloads_ = download_file_manager_->NumberOfActiveDownloads();
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::PostTask(
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::UI, FROM_HERE, new MessageLoop::QuitTask());
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ResourceDispatcherHost* resource_dispatcher_host_;
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadFileManager* download_file_manager_;
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int rdh_pending_requests_;
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int dfm_pending_downloads_;
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(CancelTestDataCollector);
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
396201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochclass DownloadTest : public InProcessBrowserTest {
39772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public:
39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  enum SelectExpectation {
39972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_NO_SELECT_DIALOG = -1,
40072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_NOTHING,
40172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_SELECT_DIALOG
40272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  };
40372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
40472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Returning false indicates a failure of the setup, and should be asserted
40572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // in the caller.
40672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  virtual bool InitialSetup(bool prompt_for_download) {
40772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool have_test_dir = PathService::Get(chrome::DIR_TEST_DATA, &test_dir_);
40872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(have_test_dir);
40972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!have_test_dir)
41072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
41172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
41272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Sanity check default values for window / tab count and shelf visibility.
41372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    int window_count = BrowserList::size();
41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_EQ(1, window_count);
41572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_EQ(1, browser()->tab_count());
41672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool is_shelf_visible = browser()->window()->IsDownloadShelfVisible();
41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_FALSE(is_shelf_visible);
41872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
41972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Set up the temporary download folder.
42072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool created_downloads_dir = CreateAndSetDownloadsDirectory(browser());
42172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(created_downloads_dir);
42272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!created_downloads_dir)
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    browser()->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
42572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                 prompt_for_download);
42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
428201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
43072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen protected:
43172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  enum SizeTestType {
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SIZE_TEST_TYPE_KNOWN,
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SIZE_TEST_TYPE_UNKNOWN,
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  };
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Location of the file source (the place from which it is downloaded).
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath OriginFile(FilePath file) {
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return test_dir_.Append(file);
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Location of the file destination (place to which it is downloaded).
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath DestinationFile(Browser* browser, FilePath file) {
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return GetDownloadDirectory(browser).Append(file);
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
447201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Must be called after browser creation.  Creates a temporary
448201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // directory for downloads that is auto-deleted on destruction.
44972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Returning false indicates a failure of the function, and should be asserted
45072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // in the caller.
45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool CreateAndSetDownloadsDirectory(Browser* browser) {
45272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!browser)
45372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
45472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
45572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!downloads_directory_.CreateUniqueTempDir())
45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
45772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
45872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    browser->profile()->GetPrefs()->SetFilePath(
45972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        prefs::kDownloadDefaultDirectory,
46072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        downloads_directory_.path());
46172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
46272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
464201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
46572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath GetDownloadDirectory(Browser* browser) {
466201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DownloadManager* download_mananger =
46772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        browser->profile()->GetDownloadManager();
468201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return download_mananger->download_prefs()->download_path();
469201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
470201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create a DownloadsObserver that will wait for the
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // specified number of downloads to finish.
47372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadsObserver* CreateWaiter(Browser* browser, int num_downloads) {
474201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    DownloadManager* download_manager =
47572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        browser->profile()->GetDownloadManager();
476201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return new DownloadsObserver(
477201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        download_manager, num_downloads,
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        DownloadItem::COMPLETE,          // Really done
47972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        true);                           // Bail on select file
48072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
48172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create a DownloadsObserver that will wait for the
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // specified number of downloads to start.
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadsObserver* CreateInProgressWaiter(Browser* browser,
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                            int num_downloads) {
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadManager* download_manager =
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        browser->profile()->GetDownloadManager();
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return new DownloadsObserver(
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        download_manager, num_downloads,
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        DownloadItem::IN_PROGRESS,      // Has started
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        true);                          // Bail on select file
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
49472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download |url|, then wait for the download to finish.
49572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // |disposition| indicates where the navigation occurs (current tab, new
49672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // foreground tab, etc).
49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // |expectation| indicates whether or not a Select File dialog should be
49872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // open when the download is finished, or if we don't care.
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If the dialog appears, the routine exits.  The only effect |expectation|
50072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // has is whether or not the test succeeds.
50172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // |browser_test_flags| indicate what to wait for, and is an OR of 0 or more
50272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // values in the ui_test_utils::BrowserTestWaitFlags enum.
50372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void DownloadAndWaitWithDisposition(Browser* browser,
50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                      const GURL& url,
50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                      WindowOpenDisposition disposition,
50672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                      SelectExpectation expectation,
50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                      int browser_test_flags) {
50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Setup notification, navigate, and block.
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    scoped_ptr<DownloadsObserver> observer(CreateWaiter(browser, 1));
51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // This call will block until the condition specified by
51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // |browser_test_flags|, but will not wait for the download to finish.
51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui_test_utils::NavigateToURLWithDisposition(browser,
51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                url,
51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                disposition,
51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                browser_test_flags);
51672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Waits for the download to complete.
51772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    observer->WaitForFinished();
51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // If specified, check the state of the select file dialog.
52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (expectation != EXPECT_NOTHING) {
52172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      EXPECT_EQ(expectation == EXPECT_SELECT_DIALOG,
52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                observer->select_file_dialog_seen());
52372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
52472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file in the current tab, then wait for the download to finish.
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void DownloadAndWait(Browser* browser,
52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       const GURL& url,
52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                       SelectExpectation expectation) {
53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    DownloadAndWaitWithDisposition(
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        browser,
53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        url,
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        CURRENT_TAB,
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        expectation,
53572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
536201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
537201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
538201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Should only be called when the download is known to have finished
539201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // (in error or not).
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Returning false indicates a failure of the function, and should be asserted
54172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // in the caller.
54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool CheckDownload(Browser* browser,
54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                     const FilePath& downloaded_filename,
544201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     const FilePath& origin_filename) {
545201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Find the path to which the data will be downloaded.
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FilePath downloaded_file(DestinationFile(browser, downloaded_filename));
547201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
548201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Find the origin path (from which the data comes).
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FilePath origin_file(OriginFile(origin_filename));
55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool origin_file_exists = file_util::PathExists(origin_file);
55172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(origin_file_exists);
55272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!origin_file_exists)
55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
554201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
555201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Confirm the downloaded data file exists.
55672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool downloaded_file_exists = file_util::PathExists(downloaded_file);
55772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(downloaded_file_exists);
55872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!downloaded_file_exists)
55972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
56072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
561201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    int64 origin_file_size = 0;
562201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    int64 downloaded_file_size = 0;
563201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_TRUE(file_util::GetFileSize(origin_file, &origin_file_size));
564201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_TRUE(file_util::GetFileSize(downloaded_file, &downloaded_file_size));
565201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_EQ(origin_file_size, downloaded_file_size);
566201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    EXPECT_TRUE(file_util::ContentsEqual(downloaded_file, origin_file));
567201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
568201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Delete the downloaded copy of the file.
56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool downloaded_file_deleted =
57072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        file_util::DieFileDie(downloaded_file, false);
57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(downloaded_file_deleted);
57272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return downloaded_file_deleted;
57372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
57472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
57572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool RunSizeTest(Browser* browser,
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   SizeTestType type,
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   const std::string& partial_indication,
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   const std::string& total_indication) {
57972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!InitialSetup(false))
58072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
58172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(type == SIZE_TEST_TYPE_UNKNOWN || type == SIZE_TEST_TYPE_KNOWN);
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (type != SIZE_TEST_TYPE_KNOWN && type != SIZE_TEST_TYPE_UNKNOWN)
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return false;
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GURL url(type == SIZE_TEST_TYPE_KNOWN ?
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             URLRequestSlowDownloadJob::kKnownSizeUrl :
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen             URLRequestSlowDownloadJob::kUnknownSizeUrl);
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(ahendrickson) -- |expected_title_in_progress| and
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // |expected_title_finished| need to be checked.
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FilePath filename;
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::FileURLToFilePath(url, &filename);
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    string16 expected_title_in_progress(
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ASCIIToUTF16(partial_indication) + filename.LossyDisplayName());
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    string16 expected_title_finished(
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ASCIIToUTF16(total_indication) + filename.LossyDisplayName());
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
59872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Download a partial web page in a background tab and wait.
59972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // The mock system will not complete until it gets a special URL.
60072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    scoped_ptr<DownloadsObserver> observer(CreateWaiter(browser, 1));
60172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui_test_utils::NavigateToURL(browser, url);
60272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
60372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // TODO(ahendrickson): check download status text before downloading.
60472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Need to:
60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    //  - Add a member function to the |DownloadShelf| interface class, that
60672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    //    indicates how many members it has.
60772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    //  - Add a member function to |DownloadShelf| to get the status text
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    //    of a given member (for example, via the name in |DownloadItemView|'s
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    //    GetAccessibleState() member function), by index.
61072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    //  - Iterate over browser->window()->GetDownloadShelf()'s members
61172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    //    to see if any match the status text we want.  Start with the last one.
61272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Allow the request to finish.  We do this by loading a second URL in a
61472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // separate tab.
61572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
61672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ui_test_utils::NavigateToURLWithDisposition(
61772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        browser,
61872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        finish_url,
61972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        NEW_FOREGROUND_TAB,
62072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
62172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    observer->WaitForFinished();
62272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_EQ(2, browser->tab_count());
62472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // TODO(ahendrickson): check download status text after downloading.
62672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
62772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Make sure the download shelf is showing.
628dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_TRUE(IsDownloadUIVisible(browser));
62972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FilePath basefilename(filename.BaseName());
63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    net::FileURLToFilePath(url, &filename);
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FilePath download_path = downloads_directory_.path().Append(basefilename);
63372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
63472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool downloaded_path_exists = file_util::PathExists(download_path);
63572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(downloaded_path_exists);
63672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!downloaded_path_exists)
63772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return false;
63872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
63972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Delete the file we just downloaded.
64072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(file_util::DieFileDie(download_path, true));
64172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_FALSE(file_util::PathExists(download_path));
64272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
64372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return true;
644201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
645201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void GetDownloads(Browser* browser, std::vector<DownloadItem*>* downloads) {
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(downloads);
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DownloadManager* manager = browser->profile()->GetDownloadManager();
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    manager->SearchDownloads(string16(), downloads);
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
652dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Figure out if the appropriate download visibility was done.  A
653dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // utility function to support ChromeOS variations.  On ChromeOS
654dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // a webui panel is used instead of the download shelf; the
655dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // test for TYPE_APP_PANEL detects this type of panel.
656dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  static bool IsDownloadUIVisible(Browser* browser) {
657dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_CHROMEOS)
658dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    for (BrowserList::const_iterator it = BrowserList::begin();
659dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen         it != BrowserList::end(); ++it) {
660dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      if ((*it)->type() == Browser::TYPE_APP_PANEL) {
661dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        return true;
662dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      }
663dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
664dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return false;
665dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else
666dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return browser->window()->IsDownloadShelfVisible();
667dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
668dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
669dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
670dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  static void ExpectWindowCountAfterDownload(size_t expected) {
671dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_CHROMEOS)
672dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // On ChromeOS, a download panel is created to display
673dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // download information, and this counts as a window.
674dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    expected++;
675dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
676dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    EXPECT_EQ(expected, BrowserList::size());
677dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
678dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
679201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch private:
680201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Location of the test data.
681201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FilePath test_dir_;
682201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
683201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Location of the downloads directory for these tests
684201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ScopedTempDir downloads_directory_;
685201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch};
686201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Get History Information.
688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass DownloadsHistoryDataCollector {
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  explicit DownloadsHistoryDataCollector(int64 download_db_handle,
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         DownloadManager* manager)
692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      : result_valid_(false),
693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        download_db_handle_(download_db_handle) {
694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    HistoryService* hs =
695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        manager->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(hs);
697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    hs->QueryDownloads(
698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        &callback_consumer_,
699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewCallback(this,
700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                    &DownloadsHistoryDataCollector::OnQueryDownloadsComplete));
701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Cannot complete immediately because the history backend runs on a
703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // separate thread, so we can assume that the RunMessageLoop below will
704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // be exited by the Quit in OnQueryDownloadsComplete.
705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui_test_utils::RunMessageLoop();
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool GetDownloadsHistoryEntry(DownloadCreateInfo* result) {
709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(result);
710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    *result = result_;
711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return result_valid_;
712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void OnQueryDownloadsComplete(
716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      std::vector<DownloadCreateInfo>* entries) {
717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    result_valid_ = false;
718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (std::vector<DownloadCreateInfo>::const_iterator it = entries->begin();
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         it != entries->end(); ++it) {
720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (it->db_handle == download_db_handle_) {
721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        result_ = *it;
722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        result_valid_ = true;
723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    MessageLoopForUI::current()->Quit();
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadCreateInfo result_;
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool result_valid_;
730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int64 download_db_handle_;
731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CancelableRequestConsumer callback_consumer_;
732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector);
734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
73672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// NOTES:
73772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
73872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Files for these tests are found in DIR_TEST_DATA (currently
73972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// "chrome\test\data\", see chrome_paths.cc).
74072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Mock responses have extension .mock-http-headers appended to the file name.
74172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
74272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Download a file due to the associated MIME type.
743dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeType) {
74472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
745201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
74672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
747201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
74872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download the file and wait.  We do not expect the Select File dialog.
74972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
75072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
75172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check state.
752201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, browser()->tab_count());
75372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
754dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
75572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
75672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
75772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_WIN)
75872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Download a file and confirm that the zone identifier (on windows)
75972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// is set to internet.
760dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, CheckInternetZone) {
76172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
76272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
76372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
764201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
76572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download the file and wait.  We do not expect the Select File dialog.
76672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
767201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
768dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Check state.  Special file state must be checked before CheckDownload,
769dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // as CheckDownload will delete the output file.
770201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, browser()->tab_count());
771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath downloaded_file(DestinationFile(browser(), file));
77272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (file_util::VolumeSupportsADS(downloaded_file))
77372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_TRUE(file_util::HasInternetZoneIdentifier(downloaded_file));
774dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  CheckDownload(browser(), file, file);
775dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
776201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
77772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
778201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
77972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Put up a Select File dialog when the file is downloaded, due to its MIME
78072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// type.
78172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
782201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// This test runs correctly, but leaves behind turds in the test user's
783201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// download directory because of http://crbug.com/62099.  No big loss; it
784201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// was primarily confirming DownloadsObserver wait on select file dialog
785201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// functionality anyway.
786201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochIN_PROC_BROWSER_TEST_F(DownloadTest, DISABLED_DownloadMimeTypeSelect) {
78772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(true));
78872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
78972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
79072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
79172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download the file and wait.  We expect the Select File dialog to appear
79272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // due to the MIME type.
79372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWait(browser(), url, EXPECT_SELECT_DIALOG);
79472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
79572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check state.
79672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
79772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Since we exited while the Select File dialog was visible, there should not
79872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // be anything in the download shelf and so it should not be visible.
799dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
80072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
80172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
80272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Access a file with a viewable mime-type, verify that a download
80372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// did not initiate.
80472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) {
80572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
80672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test2.html"));
80772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath file_path(DestinationFile(browser(), file));
80972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
81072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a web page and wait.
81172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURL(browser(), url);
81272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
81372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check that we did not download the web page.
81472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(file_util::PathExists(file_path));
81572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
81672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check state.
81772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
818dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
81972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
82072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
82172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Download a 0-size file with a content-disposition header, verify that the
82272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// download tab opened and the file exists as the filename specified in the
82372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// header.  This also ensures we properly handle empty file downloads.
82472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The download shelf should be visible in the current tab.
825dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, ContentDisposition) {
82672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
82772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
82872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
82972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));
83072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
83172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file and wait.
83272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
83372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
83472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), download_file, file);
83572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
83672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check state.
83772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
838dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
83972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
84072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
841dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if !defined(OS_CHROMEOS)  // Download shelf is not per-window on ChromeOS.
84272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that the download shelf is per-window by starting a download in one
84372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tab, opening a second tab, closing the shelf, going back to the first tab,
84472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// and checking that the shelf is closed.
845dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, PerWindowShelf) {
84672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
84772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
84872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
84972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath download_file(FILE_PATH_LITERAL("download-test3-attachment.gif"));
85072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
85172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file and wait.
85272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
85372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
85472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), download_file, file);
85572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
85672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check state.
85772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
858dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
85972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
86072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a second tab and wait.
86172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_NE(static_cast<TabContentsWrapper*>(NULL),
86272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            browser()->AddSelectedTabWithURL(GURL(), PageTransition::TYPED));
86372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, browser()->tab_count());
864dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
86572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
86672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Hide the download shelf.
86772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  browser()->window()->GetDownloadShelf()->Close();
868dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
86972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
87072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Go to the first tab.
871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser()->ActivateTabAt(0, true);
87272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, browser()->tab_count());
87372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
87472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The download shelf should not be visible.
875dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
87672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
877dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif  // !OS_CHROMEOS
87872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
87972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// UnknownSize and KnownSize are tests which depend on
88072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// URLRequestSlowDownloadJob to serve content in a certain way. Data will be
88172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// sent in two chunks where the first chunk is 35K and the second chunk is 10K.
88272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The test will first attempt to download a file; but the server will "pause"
88372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// in the middle until the server receives a second request for
88472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// "download-finish".  At that time, the download will finish.
88572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// These tests don't currently test much due to holes in |RunSizeTest()|.  See
88672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// comments in that routine for details.
887dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, UnknownSize) {
888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_UNKNOWN,
889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          "32.0 KB - ", "100% - "));
89072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
89172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
892dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, KnownSize) {
893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_KNOWN,
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          "71% - ", "100% - "));
89572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
89672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
89772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Test that when downloading an item in Incognito mode, we don't crash when
89872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// closing the last Incognito window (http://crbug.com/13983).
89972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Also check that the download shelf is not visible after closing the
90072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Incognito window.
901dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, IncognitoDownload) {
90272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
90372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
90472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open an Incognito window.
90572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Browser* incognito = CreateIncognitoBrowser();  // Waits.
90672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(incognito);
90772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int window_count = BrowserList::size();
90872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, window_count);
90972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
91072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file in the Incognito window and wait.
91172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CreateAndSetDownloadsDirectory(incognito);
912201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
91372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
91472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Since |incognito| is a separate browser, we have to set it up explicitly.
91572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  incognito->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
91672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                               false);
91772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWait(incognito, url, EXPECT_NO_SELECT_DIALOG);
91872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
91972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We should still have 2 windows.
920dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExpectWindowCountAfterDownload(2);
92172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
92272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Verify that the download shelf is showing for the Incognito window.
923dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  bool is_shelf_visible = IsDownloadUIVisible(incognito);
92472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(is_shelf_visible);
92572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
92672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Close the Incognito window and don't crash.
92772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  incognito->CloseWindow();
92872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if !defined(OS_MACOSX)
92972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // On Mac OS X, the UI window close is delayed until the outermost
93072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // message loop runs.  So it isn't possible to get a BROWSER_CLOSED
93172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // notification inside of a test.
93272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED,
93372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         Source<Browser>(incognito));
93472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
935dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExpectWindowCountAfterDownload(1);
93672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
93772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
93872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Verify that the regular window does not have a download shelf.
939dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  is_shelf_visible = IsDownloadUIVisible(browser());
940dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
941dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_CHROMEOS)
942dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // On ChromeOS it's a popup rather than a download shelf, and it sticks
943dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // around.
944dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(is_shelf_visible);
945dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else
94672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(is_shelf_visible);
947dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
948201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
94972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
95072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
95172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
95272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Navigate to a new background page, but don't download.  Confirm that the
95372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// download shelf is not visible and that we have two tabs.
95472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab1) {
95572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
95672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Because it's an HTML link, it should open a web page rather than
95772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // downloading.
95872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file1(FILE_PATH_LITERAL("download-test2.html"));
95972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
96072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
96172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a web page and wait.
96272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURLWithDisposition(
96372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      browser(),
96472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      url,
96572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NEW_BACKGROUND_TAB,
96672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
96772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
96872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We should have two tabs now.
96972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, browser()->tab_count());
970dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
97172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
97272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
97372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Download a file in a background tab. Verify that the tab is closed
97472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// automatically, and that the download shelf is visible in the current tab.
975dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab1) {
97672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
97772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
97872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file in a new background tab and wait.  The tab is automatically
97972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // closed when the download begins.
98072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
98172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
98272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWaitWithDisposition(
98372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      browser(),
98472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      url,
98572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NEW_BACKGROUND_TAB,
98672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      EXPECT_NO_SELECT_DIALOG,
98772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
98872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
98972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When the download finishes, we should still have one tab.
990dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
991201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, browser()->tab_count());
992201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
99372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
99472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
99572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
99672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Open a web page in the current tab, then download a file in another tab via
99772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// a Javascript call.
99872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Verify that we have 2 tabs, and the download shelf is visible in the current
99972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tab.
100072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
100172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The download_page1.html page contains an openNew() function that opens a
100272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tab and then downloads download-test1.lib.
1003dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab2) {
100472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
100572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Because it's an HTML link, it should open a web page rather than
100672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // downloading.
100772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file1(FILE_PATH_LITERAL("download_page1.html"));
100872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
1009201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
101072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a web page and wait.
101172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURL(browser(), url);
101272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
101372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file in a new tab and wait (via Javascript).
101472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
101572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWaitWithDisposition(browser(),
101672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 GURL("javascript:openNew()"),
101772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 CURRENT_TAB,
101872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 EXPECT_NO_SELECT_DIALOG,
101972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
102072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
102172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When the download finishes, we should have two tabs.
1022dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
102372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, browser()->tab_count());
102472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
102572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
102672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
102772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
102872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Open a web page in the current tab, open another tab via a Javascript call,
102972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// then download a file in the new tab.
103072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Verify that we have 2 tabs, and the download shelf is visible in the current
103172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tab.
103272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
103372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The download_page2.html page contains an openNew() function that opens a
103472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tab.
1035dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab3) {
103672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
103772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Because it's an HTML link, it should open a web page rather than
103872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // downloading.
103972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file1(FILE_PATH_LITERAL("download_page2.html"));
104072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url1(URLRequestMockHTTPJob::GetMockUrl(file1));
104172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
104272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a web page and wait.
104372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURL(browser(), url1);
104472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
104572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a new tab and wait.
104672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURLWithDisposition(
104772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      browser(),
104872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      GURL("javascript:openNew()"),
104972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CURRENT_TAB,
105072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
105172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
105272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, browser()->tab_count());
105372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
105472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file and wait.
105572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
105672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
105772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWaitWithDisposition(browser(),
105872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 url,
105972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 CURRENT_TAB,
106072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 EXPECT_NO_SELECT_DIALOG,
106172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 ui_test_utils::BROWSER_TEST_NONE);
106272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
106372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When the download finishes, we should have two tabs.
1064dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
106572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(2, browser()->tab_count());
106672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
106772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
106872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
106972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
107072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Open a web page in the current tab, then download a file via Javascript,
107172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// which will do so in a temporary tab.
107272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Verify that we have 1 tab, and the download shelf is visible.
107372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
107472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The download_page3.html page contains an openNew() function that opens a
107572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tab with download-test1.lib in the URL.  When the URL is determined to be
107672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// a download, the tab is closed automatically.
1077dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab2) {
107872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
107972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Because it's an HTML link, it should open a web page rather than
108072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // downloading.
108172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file1(FILE_PATH_LITERAL("download_page3.html"));
108272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
108372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
108472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a web page and wait.
108572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURL(browser(), url);
108672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
108772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file and wait.
108872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The file to download is "download-test1.lib".
108972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
109072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWaitWithDisposition(browser(),
109172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 GURL("javascript:openNew()"),
109272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 CURRENT_TAB,
109372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 EXPECT_NO_SELECT_DIALOG,
109472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
109572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
109672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When the download finishes, we should still have one tab.
1097dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
109872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
109972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
110072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
110172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
110272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
110372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Open a web page in the current tab, then call Javascript via a button to
110472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// download a file in a new tab, which is closed automatically when the
110572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// download begins.
110672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Verify that we have 1 tab, and the download shelf is visible.
110772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
110872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// The download_page4.html page contains a form with download-test1.lib as the
110972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// action.
1110dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab3) {
111172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
111272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Because it's an HTML link, it should open a web page rather than
111372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // downloading.
111472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file1(FILE_PATH_LITERAL("download_page4.html"));
111572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
111672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
111772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Open a web page and wait.
111872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::NavigateToURL(browser(), url);
111972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
112072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file in a new tab and wait.  The tab will automatically close
112172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // when the download begins.
112272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The file to download is "download-test1.lib".
112372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
112472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWaitWithDisposition(
112572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      browser(),
112672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      GURL("javascript:document.getElementById('form').submit()"),
112772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      CURRENT_TAB,
112872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      EXPECT_NO_SELECT_DIALOG,
112972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
113072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
113172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When the download finishes, we should still have one tab.
1132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
1133201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(1, browser()->tab_count());
113472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
113572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
113672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
113772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
113872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Download a file in a new window.
113972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Verify that we have 2 windows, and the download shelf is not visible in the
114072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// first window, but is visible in the second window.
114172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Close the new window.
114272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Verify that we have 1 window, and the download shelf is not visible.
114372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
114472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Regression test for http://crbug.com/44454
1145dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, NewWindow) {
114672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
114772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
114872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
114972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if !defined(OS_MACOSX)
115072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // See below.
115172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Browser* first_browser = browser();
115272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
115372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
115472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Download a file in a new window and wait.
115572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DownloadAndWaitWithDisposition(browser(),
115672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 url,
115772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 NEW_WINDOW,
115872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 EXPECT_NO_SELECT_DIALOG,
115972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                 ui_test_utils::BROWSER_TEST_NONE);
116072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
116172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // When the download finishes, the download shelf SHOULD NOT be visible in
116272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // the first window.
1163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExpectWindowCountAfterDownload(2);
116472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
1165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_CHROMEOS)
1166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Except on chromeos the download UI isn't window-specific.
1167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
1168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else
1169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
1170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
117172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
117272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // The download shelf SHOULD be visible in the second window.
117372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::set<Browser*> original_browsers;
117472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  original_browsers.insert(browser());
117572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Browser* download_browser =
117672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ui_test_utils::GetBrowserNotInSet(original_browsers);
117772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ASSERT_TRUE(download_browser != NULL);
117872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_NE(download_browser, browser());
117972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, download_browser->tab_count());
1180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(download_browser));
118172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
118272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Close the new window.
118372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  download_browser->CloseWindow();
118472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if !defined(OS_MACOSX)
118572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // On Mac OS X, the UI window close is delayed until the outermost
118672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // message loop runs.  So it isn't possible to get a BROWSER_CLOSED
118772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // notification inside of a test.
118872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui_test_utils::WaitForNotificationFrom(NotificationType::BROWSER_CLOSED,
118972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         Source<Browser>(download_browser));
119072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(first_browser, browser());
1191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  ExpectWindowCountAfterDownload(1);
119272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
119372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
119472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
1195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_CHROMEOS)
1196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // On ChromeOS the popup sticks around.
1197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
1198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#else
1199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Otherwise, the download shelf should not be visible in the
1200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // remaining window.
1201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
1202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#endif
120372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
120472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CheckDownload(browser(), file, file);
1205201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
1206201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, DownloadCancelled) {
1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(rdsmith): Fragile code warning!  The code below relies on the
1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DownloadsObserver only finishing when the new download has reached
1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the state of being entered into the history and being user-visible
1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // (that's what's required for the Remove to be valid and for the
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // download shelf to be visible).  By the pure semantics of
1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DownloadsObserver, that's not guaranteed; DownloadItems are created
1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // in the IN_PROGRESS state and made known to the DownloadManager
1218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // immediately, so any ModelChanged event on the DownloadManager after
1219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // navigation would allow the observer to return.  However, the only
1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // ModelChanged() event the code will currently fire is in
1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // OnCreateDownloadEntryComplete, at which point the download item will
1222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // be in the state we need.
1223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The right way to fix this is to create finer grained states on the
1224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // DownloadItem, and wait for the state that indicates the item has been
1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // entered in the history and made visible in the UI.
1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Create a download, wait until it's started, and confirm
1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // we're in the expected state.
1229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<DownloadsObserver> observer(CreateInProgressWaiter(browser(), 1));
1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ui_test_utils::NavigateToURL(
1231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browser(), GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl));
1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  observer->WaitForFinished();
1233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DownloadItem*> downloads;
1235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  browser()->profile()->GetDownloadManager()->SearchDownloads(
1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      string16(), &downloads);
1237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1u, downloads.size());
1238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(DownloadItem::IN_PROGRESS, downloads[0]->state());
1239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
1240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Cancel the download and wait for download system quiesce.
1242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  downloads[0]->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
1243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<DownloadsFlushObserver> flush_observer(
1244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new DownloadsFlushObserver(browser()->profile()->GetDownloadManager()));
1245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  flush_observer->WaitForFlush();
1246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Get the important info from other threads and check it.
1248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<CancelTestDataCollector> info(new CancelTestDataCollector());
1249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  info->WaitForDataCollected();
1250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, info->rdh_pending_requests());
1251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0, info->dfm_pending_downloads());
1252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Using "DownloadItem::Remove" follows the discard dangerous download path,
1254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // which completely removes the browser from the shelf and closes the shelf
1255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // if it was there.
1256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
1257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Except under ChromeOS in which case if we've brought up the file
1258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // picker panel, it stays.
1259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
1260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
1261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(IsDownloadUIVisible(browser()));
1262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Confirm a download makes it into the history properly.
1266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenIN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) {
1267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(InitialSetup(false));
1268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath origin_file(OriginFile(file));
1271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int64 origin_size;
1272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  file_util::GetFileSize(origin_file, &origin_size);
1273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Download the file and wait.  We do not expect the Select File dialog.
1275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadAndWait(browser(), url, EXPECT_NO_SELECT_DIALOG);
1276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Get details of what downloads have just happened.
1278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<DownloadItem*> downloads;
1279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GetDownloads(browser(), &downloads);
1280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_EQ(1u, downloads.size());
1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  int64 db_handle = downloads[0]->db_handle();
1282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Check state.
1284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(1, browser()->tab_count());
1285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  CheckDownload(browser(), file, file);
1286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(IsDownloadUIVisible(browser()));
1287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Check history results.
1289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadsHistoryDataCollector history_collector(
1290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      db_handle,
1291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browser()->profile()->GetDownloadManager());
1292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DownloadCreateInfo info;
1293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(history_collector.GetDownloadsHistoryEntry(&info)) << db_handle;
1294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(file, info.path.BaseName());
1295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(url, info.url());
1296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ignore start_time.
1297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(origin_size, info.received_bytes);
1298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(origin_size, info.total_bytes);
1299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(DownloadItem::COMPLETE, info.state);
1300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1301