144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
47c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org
55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#include <sstream>
65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org
77c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org#include "base/bind.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "base/bind_helpers.h"
9a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "base/command_line.h"
10357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org#include "base/files/file.h"
1171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "base/files/file_path.h"
1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "base/files/file_util.h"
137c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org#include "base/files/scoped_temp_dir.h"
147c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org#include "base/memory/ref_counted.h"
153bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org#include "base/path_service.h"
16013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org#include "base/prefs/pref_service.h"
177be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org#include "base/stl_util.h"
181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/strings/string_number_conversions.h"
191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/strings/string_split.h"
201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/strings/string_util.h"
211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/strings/stringprintf.h"
221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/strings/utf_string_conversions.h"
231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/sys_info.h"
241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "base/test/test_file_util.h"
251b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/app/chrome_command_ids.h"
261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/browser_process.h"
271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/chrome_notification_types.h"
281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/download/chrome_download_manager_delegate.h"
291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/download/download_browsertest.h"
301b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/download/download_crx_util.h"
311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/download/download_history.h"
321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org#include "chrome/browser/download/download_item_model.h"
331f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/download/download_prefs.h"
341f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/download/download_request_limiter.h"
351f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/download/download_service.h"
363d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org#include "chrome/browser/download/download_service_factory.h"
371f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/download/download_shelf.h"
38a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include "chrome/browser/download/download_target_determiner.h"
39a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include "chrome/browser/download/download_test_file_activity_observer.h"
40a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include "chrome/browser/extensions/extension_install_prompt.h"
41a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org#include "chrome/browser/extensions/extension_service.h"
421f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/history/download_row.h"
431f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/history/history_service.h"
441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/history/history_service_factory.h"
451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/infobars/infobar_service.h"
461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/net/url_request_mock_util.h"
471f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/profiles/profile.h"
481f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/renderer_context_menu/render_view_context_menu_browsertest_util.h"
491f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org#include "chrome/browser/renderer_context_menu/render_view_context_menu_test_util.h"
507c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org#include "chrome/browser/ui/browser.h"
517c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org#include "chrome/browser/ui/browser_commands.h"
525ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#include "chrome/browser/ui/browser_finder.h"
53#include "chrome/browser/ui/browser_list.h"
54#include "chrome/browser/ui/browser_tabstrip.h"
55#include "chrome/browser/ui/browser_window.h"
56#include "chrome/browser/ui/chrome_pages.h"
57#include "chrome/browser/ui/host_desktop.h"
58#include "chrome/browser/ui/tabs/tab_strip_model.h"
59#include "chrome/common/chrome_paths.h"
60#include "chrome/common/pref_names.h"
61#include "chrome/common/safe_browsing/csd.pb.h"
62#include "chrome/common/url_constants.h"
63#include "chrome/grit/generated_resources.h"
64#include "chrome/test/base/in_process_browser_test.h"
65#include "chrome/test/base/test_switches.h"
66#include "chrome/test/base/ui_test_utils.h"
67#include "components/infobars/core/confirm_infobar_delegate.h"
68#include "components/infobars/core/infobar.h"
69#include "content/public/browser/download_interrupt_reasons.h"
70#include "content/public/browser/download_item.h"
71#include "content/public/browser/download_manager.h"
72#include "content/public/browser/download_save_info.h"
73#include "content/public/browser/download_url_parameters.h"
74#include "content/public/browser/notification_source.h"
75#include "content/public/browser/render_frame_host.h"
76#include "content/public/browser/render_view_host.h"
77#include "content/public/browser/resource_context.h"
78#include "content/public/browser/web_contents.h"
79#include "content/public/common/content_switches.h"
80#include "content/public/common/context_menu_params.h"
81#include "content/public/test/browser_test_utils.h"
82#include "content/public/test/download_test_observer.h"
83#include "content/public/test/test_file_error_injector.h"
84#include "content/public/test/test_navigation_observer.h"
85#include "content/test/net/url_request_slow_download_job.h"
86#include "extensions/browser/extension_system.h"
87#include "extensions/common/feature_switch.h"
88#include "net/base/filename_util.h"
89#include "net/test/spawned_test_server/spawned_test_server.h"
90#include "net/test/url_request/url_request_mock_http_job.h"
91#include "testing/gtest/include/gtest/gtest.h"
92#include "ui/base/l10n/l10n_util.h"
93#include "ui/base/page_transition_types.h"
94
95#if defined(FULL_SAFE_BROWSING)
96#include "chrome/browser/safe_browsing/download_feedback_service.h"
97#include "chrome/browser/safe_browsing/download_protection_service.h"
98#include "chrome/browser/safe_browsing/safe_browsing_database.h"
99#include "chrome/browser/safe_browsing/safe_browsing_service.h"
100#endif
101
102using content::BrowserContext;
103using content::BrowserThread;
104using content::DownloadItem;
105using content::DownloadManager;
106using content::DownloadUrlParameters;
107using content::URLRequestSlowDownloadJob;
108using content::WebContents;
109using extensions::Extension;
110using extensions::FeatureSwitch;
111using net::URLRequestMockHTTPJob;
112
113namespace {
114
115class CreatedObserver : public content::DownloadManager::Observer {
116 public:
117  explicit CreatedObserver(content::DownloadManager* manager)
118      : manager_(manager),
119        waiting_(false) {
120    manager->AddObserver(this);
121  }
122  virtual ~CreatedObserver() {
123    if (manager_)
124      manager_->RemoveObserver(this);
125  }
126
127  void Wait() {
128    std::vector<DownloadItem*> downloads;
129    manager_->GetAllDownloads(&downloads);
130    if (!downloads.empty())
131      return;
132    waiting_ = true;
133    content::RunMessageLoop();
134    waiting_ = false;
135  }
136
137 private:
138  virtual void OnDownloadCreated(content::DownloadManager* manager,
139                                 content::DownloadItem* item) OVERRIDE {
140    DCHECK_EQ(manager_, manager);
141    if (waiting_)
142      base::MessageLoopForUI::current()->Quit();
143  }
144
145  content::DownloadManager* manager_;
146  bool waiting_;
147
148  DISALLOW_COPY_AND_ASSIGN(CreatedObserver);
149};
150
151class PercentWaiter : public content::DownloadItem::Observer {
152 public:
153  explicit PercentWaiter(DownloadItem* item)
154    : item_(item),
155      waiting_(false),
156      error_(false),
157      prev_percent_(0) {
158    item_->AddObserver(this);
159  }
160  virtual ~PercentWaiter() {
161    if (item_)
162      item_->RemoveObserver(this);
163  }
164
165  bool WaitForFinished() {
166    if (item_->GetState() == DownloadItem::COMPLETE) {
167      return item_->PercentComplete() == 100;
168    }
169    waiting_ = true;
170    content::RunMessageLoop();
171    waiting_ = false;
172    return !error_;
173  }
174
175 private:
176  virtual void OnDownloadUpdated(content::DownloadItem* item) OVERRIDE {
177    DCHECK_EQ(item_, item);
178    if (!error_ &&
179        ((prev_percent_ > item_->PercentComplete()) ||
180         (item_->GetState() == DownloadItem::COMPLETE &&
181          (item_->PercentComplete() != 100)))) {
182      error_ = true;
183      if (waiting_)
184        base::MessageLoopForUI::current()->Quit();
185    }
186    if (item_->GetState() == DownloadItem::COMPLETE && waiting_)
187      base::MessageLoopForUI::current()->Quit();
188  }
189
190  virtual void OnDownloadDestroyed(content::DownloadItem* item) OVERRIDE {
191    DCHECK_EQ(item_, item);
192    item_->RemoveObserver(this);
193    item_ = NULL;
194  }
195
196  content::DownloadItem* item_;
197  bool waiting_;
198  bool error_;
199  int prev_percent_;
200
201  DISALLOW_COPY_AND_ASSIGN(PercentWaiter);
202};
203
204// DownloadTestObserver subclass that observes one download until it transitions
205// from a non-resumable state to a resumable state a specified number of
206// times. Note that this observer can only observe a single download.
207class DownloadTestObserverResumable : public content::DownloadTestObserver {
208 public:
209  // Construct a new observer. |transition_count| is the number of times the
210  // download should transition from a non-resumable state to a resumable state.
211  DownloadTestObserverResumable(DownloadManager* download_manager,
212                                size_t transition_count)
213      : DownloadTestObserver(download_manager, 1,
214                             ON_DANGEROUS_DOWNLOAD_FAIL),
215        was_previously_resumable_(false),
216        transitions_left_(transition_count) {
217    Init();
218  }
219  virtual ~DownloadTestObserverResumable() {}
220
221 private:
222  virtual bool IsDownloadInFinalState(DownloadItem* download) OVERRIDE {
223    bool is_resumable_now = download->CanResume();
224    if (!was_previously_resumable_ && is_resumable_now)
225      --transitions_left_;
226    was_previously_resumable_ = is_resumable_now;
227    return transitions_left_ == 0;
228  }
229
230  bool was_previously_resumable_;
231  size_t transitions_left_;
232
233  DISALLOW_COPY_AND_ASSIGN(DownloadTestObserverResumable);
234};
235
236// IDs and paths of CRX files used in tests.
237const char kGoodCrxId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
238const base::FilePath kGoodCrxPath(FILE_PATH_LITERAL("extensions/good.crx"));
239
240const char kLargeThemeCrxId[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
241const base::FilePath kLargeThemePath(
242    FILE_PATH_LITERAL("extensions/theme2.crx"));
243
244// Get History Information.
245class DownloadsHistoryDataCollector {
246 public:
247  explicit DownloadsHistoryDataCollector(Profile* profile)
248      : profile_(profile), result_valid_(false) {}
249
250  bool WaitForDownloadInfo(
251      scoped_ptr<std::vector<history::DownloadRow> >* results) {
252    HistoryService* hs = HistoryServiceFactory::GetForProfile(
253        profile_, Profile::EXPLICIT_ACCESS);
254    DCHECK(hs);
255    hs->QueryDownloads(
256        base::Bind(&DownloadsHistoryDataCollector::OnQueryDownloadsComplete,
257                   base::Unretained(this)));
258
259    content::RunMessageLoop();
260    if (result_valid_) {
261      *results = results_.Pass();
262    }
263    return result_valid_;
264  }
265
266 private:
267  void OnQueryDownloadsComplete(
268      scoped_ptr<std::vector<history::DownloadRow> > entries) {
269    result_valid_ = true;
270    results_ = entries.Pass();
271    base::MessageLoopForUI::current()->Quit();
272  }
273
274  Profile* profile_;
275  scoped_ptr<std::vector<history::DownloadRow> > results_;
276  bool result_valid_;
277
278  DISALLOW_COPY_AND_ASSIGN(DownloadsHistoryDataCollector);
279};
280
281// Mock that simulates a permissions dialog where the user denies
282// permission to install.  TODO(skerner): This could be shared with
283// extensions tests.  Find a common place for this class.
284class MockAbortExtensionInstallPrompt : public ExtensionInstallPrompt {
285 public:
286  MockAbortExtensionInstallPrompt() :
287      ExtensionInstallPrompt(NULL) {
288  }
289
290  // Simulate a user abort on an extension installation.
291  virtual void ConfirmInstall(
292      Delegate* delegate,
293      const Extension* extension,
294      const ShowDialogCallback& show_dialog_callback) OVERRIDE {
295    delegate->InstallUIAbort(true);
296    base::MessageLoopForUI::current()->Quit();
297  }
298
299  virtual void OnInstallSuccess(const Extension* extension,
300                                SkBitmap* icon) OVERRIDE {
301  }
302  virtual void OnInstallFailure(
303      const extensions::CrxInstallerError& error) OVERRIDE {
304  }
305};
306
307// Mock that simulates a permissions dialog where the user allows
308// installation.
309class MockAutoConfirmExtensionInstallPrompt : public ExtensionInstallPrompt {
310 public:
311  explicit MockAutoConfirmExtensionInstallPrompt(
312      content::WebContents* web_contents)
313      : ExtensionInstallPrompt(web_contents) {}
314
315  // Proceed without confirmation prompt.
316  virtual void ConfirmInstall(
317      Delegate* delegate,
318      const Extension* extension,
319      const ShowDialogCallback& show_dialog_callback) OVERRIDE {
320    delegate->InstallUIProceed();
321  }
322
323  virtual void OnInstallSuccess(const Extension* extension,
324                                SkBitmap* icon) OVERRIDE {
325  }
326  virtual void OnInstallFailure(
327      const extensions::CrxInstallerError& error) OVERRIDE {
328  }
329};
330
331static DownloadManager* DownloadManagerForBrowser(Browser* browser) {
332  return BrowserContext::GetDownloadManager(browser->profile());
333}
334
335bool WasAutoOpened(DownloadItem* item) {
336  return item->GetAutoOpened();
337}
338
339// Called when a download starts. Marks the download as hidden.
340void SetHiddenDownloadCallback(DownloadItem* item,
341                               content::DownloadInterruptReason reason) {
342  DownloadItemModel(item).SetShouldShowInShelf(false);
343}
344
345// Callback for HistoryObserver; used in DownloadHistoryCheck
346bool HasDataAndName(const history::DownloadRow& row) {
347  return row.received_bytes > 0 && !row.target_path.empty();
348}
349
350}  // namespace
351
352DownloadTestObserverNotInProgress::DownloadTestObserverNotInProgress(
353    DownloadManager* download_manager,
354    size_t count)
355    : DownloadTestObserver(download_manager, count, ON_DANGEROUS_DOWNLOAD_FAIL),
356      started_observing_(false) {
357  Init();
358}
359
360DownloadTestObserverNotInProgress::~DownloadTestObserverNotInProgress() {}
361
362void DownloadTestObserverNotInProgress::StartObserving() {
363  started_observing_ = true;
364}
365
366bool DownloadTestObserverNotInProgress::IsDownloadInFinalState(
367    DownloadItem* download) {
368  return started_observing_ &&
369         download->GetState() != DownloadItem::IN_PROGRESS;
370}
371
372class HistoryObserver : public DownloadHistory::Observer {
373 public:
374  typedef base::Callback<bool(const history::DownloadRow&)> FilterCallback;
375
376  explicit HistoryObserver(Profile* profile)
377      : profile_(profile),
378        waiting_(false),
379        seen_stored_(false) {
380    DownloadServiceFactory::GetForBrowserContext(profile_)->
381      GetDownloadHistory()->AddObserver(this);
382  }
383
384  virtual ~HistoryObserver() {
385    DownloadService* service = DownloadServiceFactory::GetForBrowserContext(
386        profile_);
387    if (service && service->GetDownloadHistory())
388      service->GetDownloadHistory()->RemoveObserver(this);
389  }
390
391  void SetFilterCallback(const FilterCallback& callback) {
392    callback_ = callback;
393  }
394
395  virtual void OnDownloadStored(
396      content::DownloadItem* item,
397      const history::DownloadRow& info) OVERRIDE {
398    if (!callback_.is_null() && (!callback_.Run(info)))
399        return;
400
401    seen_stored_ = true;
402    if (waiting_)
403      base::MessageLoopForUI::current()->Quit();
404  }
405
406  virtual void OnDownloadHistoryDestroyed() OVERRIDE {
407    DownloadServiceFactory::GetForBrowserContext(profile_)->
408      GetDownloadHistory()->RemoveObserver(this);
409  }
410
411  void WaitForStored() {
412    if (seen_stored_)
413      return;
414    waiting_ = true;
415    content::RunMessageLoop();
416    waiting_ = false;
417  }
418
419 private:
420  Profile* profile_;
421  bool waiting_;
422  bool seen_stored_;
423  FilterCallback callback_;
424
425  DISALLOW_COPY_AND_ASSIGN(HistoryObserver);
426};
427
428class DownloadTest : public InProcessBrowserTest {
429 public:
430  // Choice of navigation or direct fetch.  Used by |DownloadFileCheckErrors()|.
431  enum DownloadMethod {
432    DOWNLOAD_NAVIGATE,
433    DOWNLOAD_DIRECT
434  };
435
436  // Information passed in to |DownloadFileCheckErrors()|.
437  struct DownloadInfo {
438    const char* url_name;  // URL for the download.
439    DownloadMethod download_method;  // Navigation or Direct.
440    // Download interrupt reason (NONE is OK).
441    content::DownloadInterruptReason reason;
442    bool show_download_item;  // True if the download item appears on the shelf.
443    bool should_redirect_to_documents;  // True if we save it in "My Documents".
444  };
445
446  struct FileErrorInjectInfo {
447    DownloadInfo download_info;
448    content::TestFileErrorInjector::FileErrorInfo error_info;
449  };
450
451  DownloadTest() {}
452
453  virtual void SetUpOnMainThread() OVERRIDE {
454    BrowserThread::PostTask(
455        BrowserThread::IO, FROM_HERE,
456        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
457    ASSERT_TRUE(InitialSetup());
458  }
459
460  virtual void TearDownOnMainThread() OVERRIDE {
461    // Needs to be torn down on the main thread. file_activity_observer_ holds a
462    // reference to the ChromeDownloadManagerDelegate which should be destroyed
463    // on the UI thread.
464    file_activity_observer_.reset();
465  }
466
467  virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
468    command_line->AppendSwitch(switches::kDisablePluginsDiscovery);
469  }
470
471  // Returning false indicates a failure of the setup, and should be asserted
472  // in the caller.
473  virtual bool InitialSetup() {
474    bool have_test_dir = PathService::Get(chrome::DIR_TEST_DATA, &test_dir_);
475    EXPECT_TRUE(have_test_dir);
476    if (!have_test_dir)
477      return false;
478
479    // Sanity check default values for window / tab count and shelf visibility.
480    int window_count = chrome::GetTotalBrowserCount();
481    EXPECT_EQ(1, window_count);
482    EXPECT_EQ(1, browser()->tab_strip_model()->count());
483    EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
484
485    // Set up the temporary download folder.
486    bool created_downloads_dir = CreateAndSetDownloadsDirectory(browser());
487    EXPECT_TRUE(created_downloads_dir);
488    if (!created_downloads_dir)
489      return false;
490    browser()->profile()->GetPrefs()->SetBoolean(
491        prefs::kPromptForDownload, false);
492
493    DownloadManager* manager = DownloadManagerForBrowser(browser());
494    DownloadPrefs::FromDownloadManager(manager)->ResetAutoOpen();
495    manager->RemoveAllDownloads();
496
497    file_activity_observer_.reset(
498        new DownloadTestFileActivityObserver(browser()->profile()));
499
500    return true;
501  }
502
503 protected:
504  enum SizeTestType {
505    SIZE_TEST_TYPE_KNOWN,
506    SIZE_TEST_TYPE_UNKNOWN,
507  };
508
509  base::FilePath GetDownloadsDirectory() {
510    return downloads_directory_.path();
511  }
512
513  // Location of the file source (the place from which it is downloaded).
514  base::FilePath OriginFile(base::FilePath file) {
515    return test_dir_.Append(file);
516  }
517
518  // Location of the file destination (place to which it is downloaded).
519  base::FilePath DestinationFile(Browser* browser, base::FilePath file) {
520    return GetDownloadDirectory(browser).Append(file.BaseName());
521  }
522
523  // Must be called after browser creation.  Creates a temporary
524  // directory for downloads that is auto-deleted on destruction.
525  // Returning false indicates a failure of the function, and should be asserted
526  // in the caller.
527  bool CreateAndSetDownloadsDirectory(Browser* browser) {
528    if (!browser)
529      return false;
530
531    if (!downloads_directory_.CreateUniqueTempDir())
532      return false;
533
534    browser->profile()->GetPrefs()->SetFilePath(
535        prefs::kDownloadDefaultDirectory,
536        downloads_directory_.path());
537    browser->profile()->GetPrefs()->SetFilePath(
538        prefs::kSaveFileDefaultDirectory,
539        downloads_directory_.path());
540
541    return true;
542  }
543
544  DownloadPrefs* GetDownloadPrefs(Browser* browser) {
545    return DownloadPrefs::FromDownloadManager(
546        DownloadManagerForBrowser(browser));
547  }
548
549  base::FilePath GetDownloadDirectory(Browser* browser) {
550    return GetDownloadPrefs(browser)->DownloadPath();
551  }
552
553  // Create a DownloadTestObserverTerminal that will wait for the
554  // specified number of downloads to finish.
555  content::DownloadTestObserver* CreateWaiter(
556      Browser* browser, int num_downloads) {
557    DownloadManager* download_manager = DownloadManagerForBrowser(browser);
558    return new content::DownloadTestObserverTerminal(
559        download_manager, num_downloads,
560        content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
561  }
562
563  // Create a DownloadTestObserverInProgress that will wait for the
564  // specified number of downloads to start.
565  content::DownloadTestObserver* CreateInProgressWaiter(
566      Browser* browser, int num_downloads) {
567    DownloadManager* download_manager = DownloadManagerForBrowser(browser);
568    return new content::DownloadTestObserverInProgress(
569        download_manager, num_downloads);
570  }
571
572  // Create a DownloadTestObserverTerminal that will wait for the
573  // specified number of downloads to finish, or for
574  // a dangerous download warning to be shown.
575  content::DownloadTestObserver* DangerousDownloadWaiter(
576      Browser* browser,
577      int num_downloads,
578      content::DownloadTestObserver::DangerousDownloadAction
579          dangerous_download_action) {
580    DownloadManager* download_manager = DownloadManagerForBrowser(browser);
581    return new content::DownloadTestObserverTerminal(
582        download_manager, num_downloads, dangerous_download_action);
583  }
584
585  void CheckDownloadStatesForBrowser(Browser* browser,
586                                     size_t num,
587                                     DownloadItem::DownloadState state) {
588    std::vector<DownloadItem*> download_items;
589    GetDownloads(browser, &download_items);
590
591    EXPECT_EQ(num, download_items.size());
592
593    for (size_t i = 0; i < download_items.size(); ++i) {
594      EXPECT_EQ(state, download_items[i]->GetState()) << " Item " << i;
595    }
596  }
597
598  void CheckDownloadStates(size_t num, DownloadItem::DownloadState state) {
599    CheckDownloadStatesForBrowser(browser(), num, state);
600  }
601
602  // Download |url|, then wait for the download to finish.
603  // |disposition| indicates where the navigation occurs (current tab, new
604  // foreground tab, etc).
605  // |browser_test_flags| indicate what to wait for, and is an OR of 0 or more
606  // values in the ui_test_utils::BrowserTestWaitFlags enum.
607  void DownloadAndWaitWithDisposition(Browser* browser,
608                                      const GURL& url,
609                                      WindowOpenDisposition disposition,
610                                      int browser_test_flags) {
611    // Setup notification, navigate, and block.
612    scoped_ptr<content::DownloadTestObserver> observer(
613        CreateWaiter(browser, 1));
614    // This call will block until the condition specified by
615    // |browser_test_flags|, but will not wait for the download to finish.
616    ui_test_utils::NavigateToURLWithDisposition(browser,
617                                                url,
618                                                disposition,
619                                                browser_test_flags);
620    // Waits for the download to complete.
621    observer->WaitForFinished();
622    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
623    // We don't expect a file chooser to be shown.
624    EXPECT_FALSE(DidShowFileChooser());
625  }
626
627  // Download a file in the current tab, then wait for the download to finish.
628  void DownloadAndWait(Browser* browser,
629                       const GURL& url) {
630    DownloadAndWaitWithDisposition(
631        browser,
632        url,
633        CURRENT_TAB,
634        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
635  }
636
637  // Should only be called when the download is known to have finished
638  // (in error or not).
639  // Returning false indicates a failure of the function, and should be asserted
640  // in the caller.
641  bool CheckDownload(Browser* browser,
642                     const base::FilePath& downloaded_filename,
643                     const base::FilePath& origin_filename) {
644    // Find the path to which the data will be downloaded.
645    base::FilePath downloaded_file(
646        DestinationFile(browser, downloaded_filename));
647
648    // Find the origin path (from which the data comes).
649    base::FilePath origin_file(OriginFile(origin_filename));
650    return CheckDownloadFullPaths(browser, downloaded_file, origin_file);
651  }
652
653  // A version of CheckDownload that allows complete path specification.
654  bool CheckDownloadFullPaths(Browser* browser,
655                              const base::FilePath& downloaded_file,
656                              const base::FilePath& origin_file) {
657    bool origin_file_exists = base::PathExists(origin_file);
658    EXPECT_TRUE(origin_file_exists) << origin_file.value();
659    if (!origin_file_exists)
660      return false;
661
662    // Confirm the downloaded data file exists.
663    bool downloaded_file_exists = base::PathExists(downloaded_file);
664    EXPECT_TRUE(downloaded_file_exists) << downloaded_file.value();
665    if (!downloaded_file_exists)
666      return false;
667
668    int64 origin_file_size = 0;
669    EXPECT_TRUE(base::GetFileSize(origin_file, &origin_file_size));
670    std::string original_file_contents;
671    EXPECT_TRUE(base::ReadFileToString(origin_file, &original_file_contents));
672    EXPECT_TRUE(
673        VerifyFile(downloaded_file, original_file_contents, origin_file_size));
674
675    // Delete the downloaded copy of the file.
676    bool downloaded_file_deleted = base::DieFileDie(downloaded_file, false);
677    EXPECT_TRUE(downloaded_file_deleted);
678    return downloaded_file_deleted;
679  }
680
681  content::DownloadTestObserver* CreateInProgressDownloadObserver(
682      size_t download_count) {
683    DownloadManager* manager = DownloadManagerForBrowser(browser());
684    return new content::DownloadTestObserverInProgress(
685        manager, download_count);
686  }
687
688  DownloadItem* CreateSlowTestDownload() {
689    scoped_ptr<content::DownloadTestObserver> observer(
690        CreateInProgressDownloadObserver(1));
691    GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
692    DownloadManager* manager = DownloadManagerForBrowser(browser());
693
694    EXPECT_EQ(0, manager->NonMaliciousInProgressCount());
695    EXPECT_EQ(0, manager->InProgressCount());
696    if (manager->InProgressCount() != 0)
697      return NULL;
698
699    ui_test_utils::NavigateToURLWithDisposition(
700        browser(), slow_download_url, CURRENT_TAB,
701        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
702
703    observer->WaitForFinished();
704    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
705
706    DownloadManager::DownloadVector items;
707    manager->GetAllDownloads(&items);
708
709    DownloadItem* new_item = NULL;
710    for (DownloadManager::DownloadVector::iterator iter = items.begin();
711         iter != items.end(); ++iter) {
712      if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
713        // There should be only one IN_PROGRESS item.
714        EXPECT_EQ(NULL, new_item);
715        new_item = *iter;
716      }
717    }
718    return new_item;
719  }
720
721  bool RunSizeTest(Browser* browser,
722                   SizeTestType type,
723                   const std::string& partial_indication,
724                   const std::string& total_indication) {
725    EXPECT_TRUE(type == SIZE_TEST_TYPE_UNKNOWN || type == SIZE_TEST_TYPE_KNOWN);
726    if (type != SIZE_TEST_TYPE_KNOWN && type != SIZE_TEST_TYPE_UNKNOWN)
727      return false;
728    GURL url(type == SIZE_TEST_TYPE_KNOWN ?
729             URLRequestSlowDownloadJob::kKnownSizeUrl :
730             URLRequestSlowDownloadJob::kUnknownSizeUrl);
731
732    // TODO(ahendrickson) -- |expected_title_in_progress| and
733    // |expected_title_finished| need to be checked.
734    base::FilePath filename;
735    net::FileURLToFilePath(url, &filename);
736    base::string16 expected_title_in_progress(
737        base::ASCIIToUTF16(partial_indication) + filename.LossyDisplayName());
738    base::string16 expected_title_finished(
739        base::ASCIIToUTF16(total_indication) + filename.LossyDisplayName());
740
741    // Download a partial web page in a background tab and wait.
742    // The mock system will not complete until it gets a special URL.
743    scoped_ptr<content::DownloadTestObserver> observer(
744        CreateWaiter(browser, 1));
745    ui_test_utils::NavigateToURL(browser, url);
746
747    // TODO(ahendrickson): check download status text before downloading.
748    // Need to:
749    //  - Add a member function to the |DownloadShelf| interface class, that
750    //    indicates how many members it has.
751    //  - Add a member function to |DownloadShelf| to get the status text
752    //    of a given member (for example, via the name in |DownloadItemView|'s
753    //    GetAccessibleState() member function), by index.
754    //  - Iterate over browser->window()->GetDownloadShelf()'s members
755    //    to see if any match the status text we want.  Start with the last one.
756
757    // Allow the request to finish.  We do this by loading a second URL in a
758    // separate tab.
759    GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
760    ui_test_utils::NavigateToURLWithDisposition(
761        browser,
762        finish_url,
763        NEW_FOREGROUND_TAB,
764        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
765    observer->WaitForFinished();
766    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
767    CheckDownloadStatesForBrowser(browser, 1, DownloadItem::COMPLETE);
768
769    EXPECT_EQ(2, browser->tab_strip_model()->count());
770
771    // TODO(ahendrickson): check download status text after downloading.
772
773    base::FilePath basefilename(filename.BaseName());
774    net::FileURLToFilePath(url, &filename);
775    base::FilePath download_path =
776        downloads_directory_.path().Append(basefilename);
777    EXPECT_TRUE(browser->window()->IsDownloadShelfVisible());
778
779    bool downloaded_path_exists = base::PathExists(download_path);
780    EXPECT_TRUE(downloaded_path_exists);
781    if (!downloaded_path_exists)
782      return false;
783
784    // Check the file contents.
785    size_t file_size = URLRequestSlowDownloadJob::kFirstDownloadSize +
786                       URLRequestSlowDownloadJob::kSecondDownloadSize;
787    std::string expected_contents(file_size, '*');
788    EXPECT_TRUE(VerifyFile(download_path, expected_contents, file_size));
789
790    // Delete the file we just downloaded.
791    EXPECT_TRUE(base::DieFileDie(download_path, true));
792    EXPECT_FALSE(base::PathExists(download_path));
793
794    return true;
795  }
796
797  void GetDownloads(Browser* browser, std::vector<DownloadItem*>* downloads) {
798    DCHECK(downloads);
799    DownloadManager* manager = DownloadManagerForBrowser(browser);
800    manager->GetAllDownloads(downloads);
801  }
802
803  static void ExpectWindowCountAfterDownload(size_t expected) {
804    EXPECT_EQ(expected, chrome::GetTotalBrowserCount());
805  }
806
807  void EnableFileChooser(bool enable) {
808    file_activity_observer_->EnableFileChooser(enable);
809  }
810
811  bool DidShowFileChooser() {
812    return file_activity_observer_->TestAndResetDidShowFileChooser();
813  }
814
815  // Checks that |path| is has |file_size| bytes, and matches the |value|
816  // string.
817  bool VerifyFile(const base::FilePath& path,
818                  const std::string& value,
819                  const int64 file_size) {
820    std::string file_contents;
821
822    bool read = base::ReadFileToString(path, &file_contents);
823    EXPECT_TRUE(read) << "Failed reading file: " << path.value() << std::endl;
824    if (!read)
825      return false;  // Couldn't read the file.
826
827    // Note: we don't handle really large files (more than size_t can hold)
828    // so we will fail in that case.
829    size_t expected_size = static_cast<size_t>(file_size);
830
831    // Check the size.
832    EXPECT_EQ(expected_size, file_contents.size());
833    if (expected_size != file_contents.size())
834      return false;
835
836    // Check the contents.
837    EXPECT_EQ(value, file_contents);
838    if (memcmp(file_contents.c_str(), value.c_str(), expected_size) != 0)
839      return false;
840
841    return true;
842  }
843
844  // Attempts to download a file, based on information in |download_info|.
845  // If a Select File dialog opens, will automatically choose the default.
846  void DownloadFilesCheckErrorsSetup() {
847    ASSERT_TRUE(test_server()->Start());
848    std::vector<DownloadItem*> download_items;
849    GetDownloads(browser(), &download_items);
850    ASSERT_TRUE(download_items.empty());
851
852    EnableFileChooser(true);
853  }
854
855  void DownloadFilesCheckErrorsLoopBody(const DownloadInfo& download_info,
856                                        size_t i) {
857    std::stringstream s;
858    s << " " << __FUNCTION__ << "()"
859      << " index = " << i
860      << " url = '" << download_info.url_name << "'"
861      << " method = "
862      << ((download_info.download_method == DOWNLOAD_DIRECT) ?
863          "DOWNLOAD_DIRECT" : "DOWNLOAD_NAVIGATE")
864      << " show_item = " << download_info.show_download_item
865      << " reason = " << DownloadInterruptReasonToString(download_info.reason);
866
867    std::vector<DownloadItem*> download_items;
868    GetDownloads(browser(), &download_items);
869    size_t downloads_expected = download_items.size();
870
871    std::string server_path = "files/downloads/";
872    server_path += download_info.url_name;
873    GURL url = test_server()->GetURL(server_path);
874    ASSERT_TRUE(url.is_valid()) << s.str();
875
876    DownloadManager* download_manager = DownloadManagerForBrowser(browser());
877    WebContents* web_contents =
878        browser()->tab_strip_model()->GetActiveWebContents();
879    ASSERT_TRUE(web_contents) << s.str();
880
881    scoped_ptr<content::DownloadTestObserver> observer(
882        new content::DownloadTestObserverTerminal(
883            download_manager,
884            1,
885            content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
886
887    if (download_info.download_method == DOWNLOAD_DIRECT) {
888      // Go directly to download.  Don't wait for navigation.
889      scoped_refptr<content::DownloadTestItemCreationObserver>
890          creation_observer(new content::DownloadTestItemCreationObserver);
891
892      scoped_ptr<DownloadUrlParameters> params(
893          DownloadUrlParameters::FromWebContents(web_contents, url));
894      params->set_callback(creation_observer->callback());
895      DownloadManagerForBrowser(browser())->DownloadUrl(params.Pass());
896
897      // Wait until the item is created, or we have determined that it
898      // won't be.
899      creation_observer->WaitForDownloadItemCreation();
900
901      EXPECT_EQ(download_info.show_download_item,
902                creation_observer->succeeded());
903      if (download_info.show_download_item) {
904        EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NONE,
905                  creation_observer->interrupt_reason());
906        EXPECT_NE(content::DownloadItem::kInvalidId,
907                  creation_observer->download_id());
908      } else {
909        EXPECT_NE(content::DOWNLOAD_INTERRUPT_REASON_NONE,
910                  creation_observer->interrupt_reason());
911        EXPECT_EQ(content::DownloadItem::kInvalidId,
912                  creation_observer->download_id());
913      }
914    } else {
915      // Navigate to URL normally, wait until done.
916      ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(),
917                                                                url,
918                                                                1);
919    }
920
921    if (download_info.show_download_item) {
922      downloads_expected++;
923      observer->WaitForFinished();
924      DownloadItem::DownloadState final_state =
925          (download_info.reason == content::DOWNLOAD_INTERRUPT_REASON_NONE) ?
926              DownloadItem::COMPLETE :
927              DownloadItem::INTERRUPTED;
928      EXPECT_EQ(1u, observer->NumDownloadsSeenInState(final_state));
929    }
930
931    // Wait till the |DownloadFile|s are destroyed.
932    content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
933    content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
934
935    // Validate that the correct files were downloaded.
936    download_items.clear();
937    GetDownloads(browser(), &download_items);
938    ASSERT_EQ(downloads_expected, download_items.size()) << s.str();
939
940    if (download_info.show_download_item) {
941      // Find the last download item.
942      DownloadItem* item = download_items[0];
943      for (size_t d = 1; d < downloads_expected; ++d) {
944        if (download_items[d]->GetStartTime() > item->GetStartTime())
945          item = download_items[d];
946      }
947
948      ASSERT_EQ(url, item->GetOriginalUrl()) << s.str();
949
950      ASSERT_EQ(download_info.reason, item->GetLastReason()) << s.str();
951
952      if (item->GetState() == content::DownloadItem::COMPLETE) {
953        // Clean up the file, in case it ended up in the My Documents folder.
954        base::FilePath destination_folder = GetDownloadDirectory(browser());
955        base::FilePath my_downloaded_file = item->GetTargetFilePath();
956        EXPECT_TRUE(base::PathExists(my_downloaded_file));
957        EXPECT_TRUE(base::DeleteFile(my_downloaded_file, false));
958
959        EXPECT_EQ(download_info.should_redirect_to_documents ?
960                      std::string::npos :
961                      0u,
962                  my_downloaded_file.value().find(destination_folder.value()));
963        if (download_info.should_redirect_to_documents) {
964          // If it's not where we asked it to be, it should be in the
965          // My Documents folder.
966          base::FilePath my_docs_folder;
967          EXPECT_TRUE(PathService::Get(chrome::DIR_USER_DOCUMENTS,
968                                       &my_docs_folder));
969          EXPECT_EQ(0u,
970                    my_downloaded_file.value().find(my_docs_folder.value()));
971        }
972      }
973    }
974  }
975
976  // Attempts to download a set of files, based on information in the
977  // |download_info| array.  |count| is the number of files.
978  // If a Select File dialog appears, it will choose the default and return
979  // immediately.
980  void DownloadFilesCheckErrors(size_t count, DownloadInfo* download_info) {
981    DownloadFilesCheckErrorsSetup();
982
983    for (size_t i = 0; i < count; ++i) {
984      DownloadFilesCheckErrorsLoopBody(download_info[i], i);
985    }
986  }
987
988  void DownloadInsertFilesErrorCheckErrorsLoopBody(
989      scoped_refptr<content::TestFileErrorInjector> injector,
990      const FileErrorInjectInfo& info,
991      size_t i) {
992    std::stringstream s;
993    s << " " << __FUNCTION__ << "()"
994      << " index = " << i
995      << " url = " << info.error_info.url
996      << " operation code = "
997      << content::TestFileErrorInjector::DebugString(info.error_info.code)
998      << " instance = " << info.error_info.operation_instance
999      << " error = "
1000      << content::DownloadInterruptReasonToString(info.error_info.error);
1001
1002    injector->ClearErrors();
1003    injector->AddError(info.error_info);
1004
1005    injector->InjectErrors();
1006
1007    DownloadFilesCheckErrorsLoopBody(info.download_info, i);
1008
1009    size_t expected_successes = info.download_info.show_download_item ? 1u : 0u;
1010    EXPECT_EQ(expected_successes, injector->TotalFileCount()) << s.str();
1011    EXPECT_EQ(0u, injector->CurrentFileCount()) << s.str();
1012
1013    if (info.download_info.show_download_item)
1014      EXPECT_TRUE(injector->HadFile(GURL(info.error_info.url))) << s.str();
1015  }
1016
1017  void DownloadInsertFilesErrorCheckErrors(size_t count,
1018                                           FileErrorInjectInfo* info) {
1019    DownloadFilesCheckErrorsSetup();
1020
1021    // Set up file failures.
1022    scoped_refptr<content::TestFileErrorInjector> injector(
1023        content::TestFileErrorInjector::Create(
1024            DownloadManagerForBrowser(browser())));
1025
1026    for (size_t i = 0; i < count; ++i) {
1027      // Set up the full URL, for download file tracking.
1028      std::string server_path = "files/downloads/";
1029      server_path += info[i].download_info.url_name;
1030      GURL url = test_server()->GetURL(server_path);
1031      info[i].error_info.url = url.spec();
1032
1033      DownloadInsertFilesErrorCheckErrorsLoopBody(injector, info[i], i);
1034    }
1035  }
1036
1037  // Attempts to download a file to a read-only folder, based on information
1038  // in |download_info|.
1039  void DownloadFilesToReadonlyFolder(size_t count,
1040                                     DownloadInfo* download_info) {
1041    DownloadFilesCheckErrorsSetup();
1042
1043    // Make the test folder unwritable.
1044    base::FilePath destination_folder = GetDownloadDirectory(browser());
1045    DVLOG(1) << " " << __FUNCTION__ << "()"
1046             << " folder = '" << destination_folder.value() << "'";
1047    base::FilePermissionRestorer permission_restorer(destination_folder);
1048    EXPECT_TRUE(base::MakeFileUnwritable(destination_folder));
1049
1050    for (size_t i = 0; i < count; ++i) {
1051      DownloadFilesCheckErrorsLoopBody(download_info[i], i);
1052    }
1053  }
1054
1055  // A mock install prompt that simulates the user allowing an install request.
1056  void SetAllowMockInstallPrompt() {
1057    download_crx_util::SetMockInstallPromptForTesting(
1058        scoped_ptr<ExtensionInstallPrompt>(
1059            new MockAutoConfirmExtensionInstallPrompt(
1060                browser()->tab_strip_model()->GetActiveWebContents())));
1061  }
1062
1063  // This method:
1064  // * Starts a mock download by navigating browser() to a URLRequestMockHTTPJob
1065  //   mock URL.
1066  // * Injects |error| on the first write using |error_injector|.
1067  // * Waits for the download to be interrupted.
1068  // * Clears the errors on |error_injector|.
1069  // * Returns the resulting interrupted download.
1070  DownloadItem* StartMockDownloadAndInjectError(
1071      content::TestFileErrorInjector* error_injector,
1072      content::DownloadInterruptReason error) {
1073    base::FilePath file_path(FILE_PATH_LITERAL("download-test1.lib"));
1074    GURL url = URLRequestMockHTTPJob::GetMockUrl(file_path);
1075
1076    content::TestFileErrorInjector::FileErrorInfo error_info;
1077    error_info.url = url.spec();
1078    error_info.code = content::TestFileErrorInjector::FILE_OPERATION_WRITE;
1079    error_info.operation_instance = 0;
1080    error_info.error = error;
1081    error_injector->ClearErrors();
1082    error_injector->AddError(error_info);
1083    error_injector->InjectErrors();
1084
1085    scoped_ptr<content::DownloadTestObserver> observer(
1086        new DownloadTestObserverResumable(
1087            DownloadManagerForBrowser(browser()), 1));
1088    ui_test_utils::NavigateToURL(browser(), url);
1089    observer->WaitForFinished();
1090
1091    content::DownloadManager::DownloadVector downloads;
1092    DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
1093    EXPECT_EQ(1u, downloads.size());
1094
1095    if (downloads.size() != 1)
1096      return NULL;
1097
1098    error_injector->ClearErrors();
1099    error_injector->InjectErrors();
1100    DownloadItem* download = downloads[0];
1101    EXPECT_EQ(DownloadItem::INTERRUPTED, download->GetState());
1102    EXPECT_EQ(error, download->GetLastReason());
1103    return download;
1104  }
1105
1106 private:
1107  static void EnsureNoPendingDownloadJobsOnIO(bool* result) {
1108    if (URLRequestSlowDownloadJob::NumberOutstandingRequests())
1109      *result = false;
1110    BrowserThread::PostTask(
1111        BrowserThread::UI, FROM_HERE, base::MessageLoop::QuitClosure());
1112  }
1113
1114  // Location of the test data.
1115  base::FilePath test_dir_;
1116
1117  // Location of the downloads directory for these tests
1118  base::ScopedTempDir downloads_directory_;
1119
1120  scoped_ptr<DownloadTestFileActivityObserver> file_activity_observer_;
1121};
1122
1123// NOTES:
1124//
1125// Files for these tests are found in DIR_TEST_DATA (currently
1126// "chrome\test\data\", see chrome_paths.cc).
1127// Mock responses have extension .mock-http-headers appended to the file name.
1128
1129// Download a file due to the associated MIME type.
1130IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeType) {
1131  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1132  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1133
1134  // Download the file and wait.  We do not expect the Select File dialog.
1135  DownloadAndWait(browser(), url);
1136
1137  // Check state.
1138  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1139  CheckDownload(browser(), file, file);
1140  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1141}
1142
1143#if defined(OS_WIN)
1144// Download a file and confirm that the zone identifier (on windows)
1145// is set to internet.
1146IN_PROC_BROWSER_TEST_F(DownloadTest, CheckInternetZone) {
1147  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1148  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1149
1150  // Download the file and wait.  We do not expect the Select File dialog.
1151  DownloadAndWait(browser(), url);
1152
1153  // Check state.  Special file state must be checked before CheckDownload,
1154  // as CheckDownload will delete the output file.
1155  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1156  base::FilePath downloaded_file(DestinationFile(browser(), file));
1157  if (base::VolumeSupportsADS(downloaded_file))
1158    EXPECT_TRUE(base::HasInternetZoneIdentifier(downloaded_file));
1159  CheckDownload(browser(), file, file);
1160  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1161}
1162#endif
1163
1164// Put up a Select File dialog when the file is downloaded, due to
1165// downloads preferences settings.
1166IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadMimeTypeSelect) {
1167  // Re-enable prompting.
1168  browser()->profile()->GetPrefs()->SetBoolean(
1169      prefs::kPromptForDownload, true);
1170  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1171  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1172
1173  EnableFileChooser(true);
1174
1175  // Download the file and wait.  We expect the Select File dialog to appear
1176  // due to the MIME type, but we still wait until the download completes.
1177  scoped_ptr<content::DownloadTestObserver> observer(
1178      new content::DownloadTestObserverTerminal(
1179          DownloadManagerForBrowser(browser()),
1180          1,
1181          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
1182  ui_test_utils::NavigateToURLWithDisposition(
1183      browser(), url, CURRENT_TAB,
1184      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1185  observer->WaitForFinished();
1186  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
1187  CheckDownloadStates(1, DownloadItem::COMPLETE);
1188  EXPECT_TRUE(DidShowFileChooser());
1189
1190  // Check state.
1191  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1192  CheckDownload(browser(), file, file);
1193  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1194}
1195
1196// Access a file with a viewable mime-type, verify that a download
1197// did not initiate.
1198IN_PROC_BROWSER_TEST_F(DownloadTest, NoDownload) {
1199  base::FilePath file(FILE_PATH_LITERAL("download-test2.html"));
1200  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1201  base::FilePath file_path(DestinationFile(browser(), file));
1202
1203  // Open a web page and wait.
1204  ui_test_utils::NavigateToURL(browser(), url);
1205
1206  // Check that we did not download the web page.
1207  EXPECT_FALSE(base::PathExists(file_path));
1208
1209  // Check state.
1210  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1211  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1212}
1213
1214IN_PROC_BROWSER_TEST_F(DownloadTest, MimeTypesToShowNotDownload) {
1215  ASSERT_TRUE(test_server()->Start());
1216
1217  // These files should all be displayed in the browser.
1218  const char* mime_types[] = {
1219    // It is unclear whether to display text/css or download it.
1220    //   Firefox 3: Display
1221    //   Internet Explorer 7: Download
1222    //   Safari 3.2: Download
1223    // We choose to match Firefox due to the lot of complains
1224    // from the users if css files are downloaded:
1225    // http://code.google.com/p/chromium/issues/detail?id=7192
1226    "text/css",
1227    "text/javascript",
1228    "text/plain",
1229    "application/x-javascript",
1230    "text/html",
1231    "text/xml",
1232    "text/xsl",
1233    "application/xhtml+xml",
1234    "image/png",
1235    "image/gif",
1236    "image/jpeg",
1237    "image/bmp",
1238  };
1239  for (size_t i = 0; i < arraysize(mime_types); ++i) {
1240    const char* mime_type = mime_types[i];
1241    std::string path("contenttype?");
1242    GURL url(test_server()->GetURL(path + mime_type));
1243    ui_test_utils::NavigateToURL(browser(), url);
1244
1245    // Check state.
1246    EXPECT_EQ(1, browser()->tab_strip_model()->count());
1247    EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1248  }
1249}
1250
1251// Verify that when the DownloadResourceThrottle cancels a download, the
1252// download never makes it to the downloads system.
1253IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadResourceThrottleCancels) {
1254  // Navigate to a page with the same domain as the file to download.  We can't
1255  // navigate directly to the file we don't want to download because cross-site
1256  // navigations reset the TabDownloadState.
1257  base::FilePath same_site_path(FILE_PATH_LITERAL("download_script.html"));
1258  GURL same_site_url(URLRequestMockHTTPJob::GetMockUrl(same_site_path));
1259  ui_test_utils::NavigateToURL(browser(), same_site_url);
1260
1261  // Make sure the initial navigation didn't trigger a download.
1262  std::vector<content::DownloadItem*> items;
1263  DownloadManagerForBrowser(browser())->GetAllDownloads(&items);
1264  EXPECT_EQ(0u, items.size());
1265
1266  // Disable downloads for the tab.
1267  WebContents* web_contents =
1268      browser()->tab_strip_model()->GetActiveWebContents();
1269  DownloadRequestLimiter::TabDownloadState* tab_download_state =
1270      g_browser_process->download_request_limiter()->GetDownloadState(
1271          web_contents, web_contents, true);
1272  ASSERT_TRUE(tab_download_state);
1273  tab_download_state->set_download_status(
1274      DownloadRequestLimiter::DOWNLOADS_NOT_ALLOWED);
1275
1276  // Try to start the download via Javascript and wait for the corresponding
1277  // load stop event.
1278  content::TestNavigationObserver observer(web_contents);
1279  bool download_assempted;
1280  ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1281      browser()->tab_strip_model()->GetActiveWebContents(),
1282      "window.domAutomationController.send(startDownload());",
1283      &download_assempted));
1284  ASSERT_TRUE(download_assempted);
1285  observer.Wait();
1286
1287  // Check that we did not download the file.
1288  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1289  base::FilePath file_path(DestinationFile(browser(), file));
1290  EXPECT_FALSE(base::PathExists(file_path));
1291
1292  // Check state.
1293  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1294  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1295
1296  // Verify that there's no pending download.  The resource throttle
1297  // should have deleted it before it created a download item, so it
1298  // shouldn't be available as a cancelled download either.
1299  DownloadManagerForBrowser(browser())->GetAllDownloads(&items);
1300  EXPECT_EQ(0u, items.size());
1301}
1302
1303// Download a 0-size file with a content-disposition header, verify that the
1304// download tab opened and the file exists as the filename specified in the
1305// header.  This also ensures we properly handle empty file downloads.
1306// The download shelf should be visible in the current tab.
1307IN_PROC_BROWSER_TEST_F(DownloadTest, ContentDisposition) {
1308  base::FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
1309  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1310  base::FilePath download_file(
1311      FILE_PATH_LITERAL("download-test3-attachment.gif"));
1312
1313  // Download a file and wait.
1314  DownloadAndWait(browser(), url);
1315
1316  CheckDownload(browser(), download_file, file);
1317
1318  // Check state.
1319  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1320  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1321}
1322
1323// Test that the download shelf is per-window by starting a download in one
1324// tab, opening a second tab, closing the shelf, going back to the first tab,
1325// and checking that the shelf is closed.
1326IN_PROC_BROWSER_TEST_F(DownloadTest, PerWindowShelf) {
1327  base::FilePath file(FILE_PATH_LITERAL("download-test3.gif"));
1328  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1329  base::FilePath download_file(
1330      FILE_PATH_LITERAL("download-test3-attachment.gif"));
1331
1332  // Download a file and wait.
1333  DownloadAndWait(browser(), url);
1334
1335  CheckDownload(browser(), download_file, file);
1336
1337  // Check state.
1338  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1339  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1340
1341  // Open a second tab and wait.
1342  EXPECT_NE(static_cast<WebContents*>(NULL),
1343            chrome::AddSelectedTabWithURL(browser(),
1344                                          GURL(url::kAboutBlankURL),
1345                                          ui::PAGE_TRANSITION_TYPED));
1346  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1347  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1348
1349  // Hide the download shelf.
1350  browser()->window()->GetDownloadShelf()->Close(DownloadShelf::AUTOMATIC);
1351  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1352
1353  // Go to the first tab.
1354  browser()->tab_strip_model()->ActivateTabAt(0, true);
1355  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1356
1357  // The download shelf should not be visible.
1358  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1359}
1360
1361// Check whether the downloads shelf is closed when the downloads tab is
1362// invoked.
1363IN_PROC_BROWSER_TEST_F(DownloadTest, CloseShelfOnDownloadsTab) {
1364  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1365  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1366
1367  // Download the file and wait.  We do not expect the Select File dialog.
1368  DownloadAndWait(browser(), url);
1369
1370  // Check state.
1371  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1372  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1373
1374  // Open the downloads tab.
1375  chrome::ShowDownloads(browser());
1376  // The shelf should now be closed.
1377  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1378}
1379
1380// UnknownSize and KnownSize are tests which depend on
1381// URLRequestSlowDownloadJob to serve content in a certain way. Data will be
1382// sent in two chunks where the first chunk is 35K and the second chunk is 10K.
1383// The test will first attempt to download a file; but the server will "pause"
1384// in the middle until the server receives a second request for
1385// "download-finish".  At that time, the download will finish.
1386// These tests don't currently test much due to holes in |RunSizeTest()|.  See
1387// comments in that routine for details.
1388IN_PROC_BROWSER_TEST_F(DownloadTest, UnknownSize) {
1389  ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_UNKNOWN,
1390                          "32.0 KB - ", "100% - "));
1391}
1392
1393IN_PROC_BROWSER_TEST_F(DownloadTest, KnownSize) {
1394  ASSERT_TRUE(RunSizeTest(browser(), SIZE_TEST_TYPE_KNOWN,
1395                          "71% - ", "100% - "));
1396}
1397
1398// Test that when downloading an item in Incognito mode, we don't crash when
1399// closing the last Incognito window (http://crbug.com/13983).
1400// Also check that the download shelf is not visible after closing the
1401// Incognito window.
1402IN_PROC_BROWSER_TEST_F(DownloadTest, IncognitoDownload) {
1403  Browser* incognito = CreateIncognitoBrowser();
1404  ASSERT_TRUE(incognito);
1405  int window_count = chrome::GetTotalBrowserCount();
1406  EXPECT_EQ(2, window_count);
1407
1408  // Download a file in the Incognito window and wait.
1409  CreateAndSetDownloadsDirectory(incognito);
1410  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1411  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1412  // Since |incognito| is a separate browser, we have to set it up explicitly.
1413  incognito->profile()->GetPrefs()->SetBoolean(prefs::kPromptForDownload,
1414                                               false);
1415  DownloadAndWait(incognito, url);
1416
1417  // We should still have 2 windows.
1418  ExpectWindowCountAfterDownload(2);
1419
1420  // Verify that the download shelf is showing for the Incognito window.
1421  EXPECT_TRUE(incognito->window()->IsDownloadShelfVisible());
1422
1423#if !defined(OS_MACOSX)
1424  // On Mac OS X, the UI window close is delayed until the outermost
1425  // message loop runs.  So it isn't possible to get a BROWSER_CLOSED
1426  // notification inside of a test.
1427  content::WindowedNotificationObserver signal(
1428      chrome::NOTIFICATION_BROWSER_CLOSED,
1429      content::Source<Browser>(incognito));
1430#endif
1431
1432  // Close the Incognito window and don't crash.
1433  chrome::CloseWindow(incognito);
1434
1435#if !defined(OS_MACOSX)
1436  signal.Wait();
1437  ExpectWindowCountAfterDownload(1);
1438#endif
1439
1440  // Verify that the regular window does not have a download shelf.
1441  // On ChromeOS, the download panel is common to both profiles, so
1442  // it is still visible.
1443  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1444
1445  CheckDownload(browser(), file, file);
1446}
1447
1448// Download one file on-record, then download the same file off-record, and test
1449// that the filename is deduplicated.  The previous test tests for a specific
1450// bug; this next test tests that filename deduplication happens independently
1451// of DownloadManager/CDMD.
1452IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_IncognitoRegular) {
1453  ASSERT_TRUE(test_server()->Start());
1454  GURL url(test_server()->GetURL("files/downloads/a_zip_file.zip"));
1455
1456  // Read the origin file now so that we can compare the downloaded files to it
1457  // later.
1458  base::FilePath origin(OriginFile(base::FilePath(FILE_PATH_LITERAL(
1459      "downloads/a_zip_file.zip"))));
1460  ASSERT_TRUE(base::PathExists(origin));
1461  int64 origin_file_size = 0;
1462  EXPECT_TRUE(base::GetFileSize(origin, &origin_file_size));
1463  std::string original_contents;
1464  EXPECT_TRUE(base::ReadFileToString(origin, &original_contents));
1465
1466  std::vector<DownloadItem*> download_items;
1467  GetDownloads(browser(), &download_items);
1468  ASSERT_TRUE(download_items.empty());
1469
1470  // Download a file in the on-record browser and check that it was downloaded
1471  // correctly.
1472  DownloadAndWaitWithDisposition(browser(),
1473                                 url,
1474                                 CURRENT_TAB,
1475                                 ui_test_utils::BROWSER_TEST_NONE);
1476  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1477  GetDownloads(browser(), &download_items);
1478  ASSERT_EQ(1UL, download_items.size());
1479  ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("a_zip_file.zip")),
1480            download_items[0]->GetTargetFilePath().BaseName());
1481  ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath()));
1482  EXPECT_TRUE(VerifyFile(download_items[0]->GetTargetFilePath(),
1483                         original_contents, origin_file_size));
1484
1485  // Setup an incognito window.
1486  Browser* incognito = CreateIncognitoBrowser();
1487  ASSERT_TRUE(incognito);
1488  int window_count = BrowserList::GetInstance(
1489      browser()->host_desktop_type())->size();
1490  EXPECT_EQ(2, window_count);
1491  incognito->profile()->GetPrefs()->SetFilePath(
1492      prefs::kDownloadDefaultDirectory,
1493      GetDownloadsDirectory());
1494  incognito->profile()->GetPrefs()->SetFilePath(
1495      prefs::kSaveFileDefaultDirectory,
1496      GetDownloadsDirectory());
1497
1498  download_items.clear();
1499  GetDownloads(incognito, &download_items);
1500  ASSERT_TRUE(download_items.empty());
1501
1502  // Download a file in the incognito browser and check that it was downloaded
1503  // correctly.
1504  DownloadAndWaitWithDisposition(incognito,
1505                                 url,
1506                                 CURRENT_TAB,
1507                                 ui_test_utils::BROWSER_TEST_NONE);
1508  EXPECT_TRUE(incognito->window()->IsDownloadShelfVisible());
1509  GetDownloads(incognito, &download_items);
1510  ASSERT_EQ(1UL, download_items.size());
1511  ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("a_zip_file (1).zip")),
1512            download_items[0]->GetTargetFilePath().BaseName());
1513  ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath()));
1514  EXPECT_TRUE(VerifyFile(download_items[0]->GetTargetFilePath(),
1515                         original_contents, origin_file_size));
1516}
1517
1518// Navigate to a new background page, but don't download.  Confirm that the
1519// download shelf is not visible and that we have two tabs.
1520IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab1) {
1521  // Because it's an HTML link, it should open a web page rather than
1522  // downloading.
1523  base::FilePath file1(FILE_PATH_LITERAL("download-test2.html"));
1524  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
1525
1526  // Open a web page and wait.
1527  ui_test_utils::NavigateToURLWithDisposition(
1528      browser(),
1529      url,
1530      NEW_BACKGROUND_TAB,
1531      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1532
1533  // We should have two tabs now.
1534  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1535  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1536}
1537
1538// Download a file in a background tab. Verify that the tab is closed
1539// automatically, and that the download shelf is visible in the current tab.
1540IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab1) {
1541  // Download a file in a new background tab and wait.  The tab is automatically
1542  // closed when the download begins.
1543  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1544  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1545  DownloadAndWaitWithDisposition(
1546      browser(),
1547      url,
1548      NEW_BACKGROUND_TAB,
1549      0);
1550
1551  // When the download finishes, we should still have one tab.
1552  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1553  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1554
1555  CheckDownload(browser(), file, file);
1556}
1557
1558// Open a web page in the current tab, then download a file in another tab via
1559// a Javascript call.
1560// Verify that we have 2 tabs, and the download shelf is visible in the current
1561// tab.
1562//
1563// The download_page1.html page contains an openNew() function that opens a
1564// tab and then downloads download-test1.lib.
1565IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab2) {
1566  // Because it's an HTML link, it should open a web page rather than
1567  // downloading.
1568  base::FilePath file1(FILE_PATH_LITERAL("download_page1.html"));
1569  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
1570
1571  // Open a web page and wait.
1572  ui_test_utils::NavigateToURL(browser(), url);
1573
1574  // Download a file in a new tab and wait (via Javascript).
1575  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1576  DownloadAndWaitWithDisposition(browser(),
1577                                 GURL("javascript:openNew()"),
1578                                 CURRENT_TAB,
1579                                 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
1580
1581  // When the download finishes, we should have two tabs.
1582  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1583  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1584
1585  CheckDownload(browser(), file, file);
1586}
1587
1588// Open a web page in the current tab, open another tab via a Javascript call,
1589// then download a file in the new tab.
1590// Verify that we have 2 tabs, and the download shelf is visible in the current
1591// tab.
1592//
1593// The download_page2.html page contains an openNew() function that opens a
1594// tab.
1595IN_PROC_BROWSER_TEST_F(DownloadTest, DontCloseNewTab3) {
1596  // Because it's an HTML link, it should open a web page rather than
1597  // downloading.
1598  base::FilePath file1(FILE_PATH_LITERAL("download_page2.html"));
1599  GURL url1(URLRequestMockHTTPJob::GetMockUrl(file1));
1600
1601  // Open a web page and wait.
1602  ui_test_utils::NavigateToURL(browser(), url1);
1603
1604  // Open a new tab and wait.
1605  ui_test_utils::NavigateToURLWithDisposition(
1606      browser(),
1607      GURL("javascript:openNew()"),
1608      CURRENT_TAB,
1609      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
1610
1611  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1612
1613  // Download a file and wait.
1614  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1615  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1616  DownloadAndWaitWithDisposition(browser(),
1617                                 url,
1618                                 CURRENT_TAB,
1619                                 ui_test_utils::BROWSER_TEST_NONE);
1620
1621  // When the download finishes, we should have two tabs.
1622  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1623  EXPECT_EQ(2, browser()->tab_strip_model()->count());
1624
1625  CheckDownload(browser(), file, file);
1626}
1627
1628// Open a web page in the current tab, then download a file via Javascript,
1629// which will do so in a temporary tab.
1630// Verify that we have 1 tab, and the download shelf is visible.
1631//
1632// The download_page3.html page contains an openNew() function that opens a
1633// tab with download-test1.lib in the URL.  When the URL is determined to be
1634// a download, the tab is closed automatically.
1635IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab2) {
1636  // Because it's an HTML link, it should open a web page rather than
1637  // downloading.
1638  base::FilePath file1(FILE_PATH_LITERAL("download_page3.html"));
1639  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
1640
1641  // Open a web page and wait.
1642  ui_test_utils::NavigateToURL(browser(), url);
1643
1644  // Download a file and wait.
1645  // The file to download is "download-test1.lib".
1646  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1647  DownloadAndWaitWithDisposition(browser(),
1648                                 GURL("javascript:openNew()"),
1649                                 CURRENT_TAB,
1650                                 ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
1651
1652  // When the download finishes, we should still have one tab.
1653  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1654  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1655
1656  CheckDownload(browser(), file, file);
1657}
1658
1659// Open a web page in the current tab, then call Javascript via a button to
1660// download a file in a new tab, which is closed automatically when the
1661// download begins.
1662// Verify that we have 1 tab, and the download shelf is visible.
1663//
1664// The download_page4.html page contains a form with download-test1.lib as the
1665// action.
1666IN_PROC_BROWSER_TEST_F(DownloadTest, CloseNewTab3) {
1667  // Because it's an HTML link, it should open a web page rather than
1668  // downloading.
1669  base::FilePath file1(FILE_PATH_LITERAL("download_page4.html"));
1670  GURL url(URLRequestMockHTTPJob::GetMockUrl(file1));
1671
1672  // Open a web page and wait.
1673  ui_test_utils::NavigateToURL(browser(), url);
1674
1675  // Download a file in a new tab and wait.  The tab will automatically close
1676  // when the download begins.
1677  // The file to download is "download-test1.lib".
1678  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1679  DownloadAndWaitWithDisposition(
1680      browser(),
1681      GURL("javascript:document.getElementById('form').submit()"),
1682      CURRENT_TAB,
1683      ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB);
1684
1685  // When the download finishes, we should still have one tab.
1686  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
1687  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1688
1689  CheckDownload(browser(), file, file);
1690}
1691
1692// Download a file in a new window.
1693// Verify that we have 2 windows, and the download shelf is not visible in the
1694// first window, but is visible in the second window.
1695// Close the new window.
1696// Verify that we have 1 window, and the download shelf is not visible.
1697//
1698// Regression test for http://crbug.com/44454
1699IN_PROC_BROWSER_TEST_F(DownloadTest, NewWindow) {
1700  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1701  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
1702#if !defined(OS_MACOSX)
1703  // See below.
1704  Browser* first_browser = browser();
1705#endif
1706
1707  // Download a file in a new window and wait.
1708  DownloadAndWaitWithDisposition(browser(),
1709                                 url,
1710                                 NEW_WINDOW,
1711                                 ui_test_utils::BROWSER_TEST_NONE);
1712
1713  // When the download finishes, the download shelf SHOULD NOT be visible in
1714  // the first window.
1715  ExpectWindowCountAfterDownload(2);
1716  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1717  // Download shelf should close. Download panel stays open on ChromeOS.
1718  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1719
1720  // The download shelf SHOULD be visible in the second window.
1721  std::set<Browser*> original_browsers;
1722  original_browsers.insert(browser());
1723  Browser* download_browser =
1724      ui_test_utils::GetBrowserNotInSet(original_browsers);
1725  ASSERT_TRUE(download_browser != NULL);
1726  EXPECT_NE(download_browser, browser());
1727  EXPECT_EQ(1, download_browser->tab_strip_model()->count());
1728  EXPECT_TRUE(download_browser->window()->IsDownloadShelfVisible());
1729
1730#if !defined(OS_MACOSX)
1731  // On Mac OS X, the UI window close is delayed until the outermost
1732  // message loop runs.  So it isn't possible to get a BROWSER_CLOSED
1733  // notification inside of a test.
1734  content::WindowedNotificationObserver signal(
1735      chrome::NOTIFICATION_BROWSER_CLOSED,
1736      content::Source<Browser>(download_browser));
1737#endif
1738
1739  // Close the new window.
1740  chrome::CloseWindow(download_browser);
1741
1742#if !defined(OS_MACOSX)
1743  signal.Wait();
1744  EXPECT_EQ(first_browser, browser());
1745  ExpectWindowCountAfterDownload(1);
1746#endif
1747
1748  EXPECT_EQ(1, browser()->tab_strip_model()->count());
1749  // Download shelf should close. Download panel stays open on ChromeOS.
1750  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1751
1752  CheckDownload(browser(), file, file);
1753}
1754
1755IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryCheck) {
1756  GURL download_url(URLRequestSlowDownloadJob::kKnownSizeUrl);
1757  base::FilePath file(net::GenerateFileName(download_url,
1758                                            std::string(),
1759                                            std::string(),
1760                                            std::string(),
1761                                            std::string(),
1762                                            std::string()));
1763
1764  // We use the server so that we can get a redirect and test url_chain
1765  // persistence.
1766  ASSERT_TRUE(test_server()->Start());
1767  GURL redirect_url = test_server()->GetURL(
1768      "server-redirect?" + download_url.spec());
1769
1770  // Download the url and wait until the object has been stored.
1771  base::Time start(base::Time::Now());
1772  HistoryObserver observer(browser()->profile());
1773  observer.SetFilterCallback(base::Bind(&HasDataAndName));
1774  ui_test_utils::NavigateToURL(browser(), redirect_url);
1775  observer.WaitForStored();
1776
1777  // Get the details on what was stored into the history.
1778  scoped_ptr<std::vector<history::DownloadRow> > downloads_in_database;
1779  ASSERT_TRUE(DownloadsHistoryDataCollector(
1780      browser()->profile()).WaitForDownloadInfo(&downloads_in_database));
1781  ASSERT_EQ(1u, downloads_in_database->size());
1782
1783  // Confirm history storage is what you expect for a partially completed
1784  // slow download job.
1785  history::DownloadRow& row(downloads_in_database->at(0));
1786  EXPECT_EQ(DestinationFile(browser(), file), row.target_path);
1787  EXPECT_EQ(DownloadTargetDeterminer::GetCrDownloadPath(
1788                DestinationFile(browser(), file)),
1789            row.current_path);
1790  ASSERT_EQ(2u, row.url_chain.size());
1791  EXPECT_EQ(redirect_url.spec(), row.url_chain[0].spec());
1792  EXPECT_EQ(download_url.spec(), row.url_chain[1].spec());
1793  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, row.danger_type);
1794  EXPECT_LE(start, row.start_time);
1795  EXPECT_EQ(URLRequestSlowDownloadJob::kFirstDownloadSize, row.received_bytes);
1796  EXPECT_EQ(URLRequestSlowDownloadJob::kFirstDownloadSize
1797            + URLRequestSlowDownloadJob::kSecondDownloadSize, row.total_bytes);
1798  EXPECT_EQ(content::DownloadItem::IN_PROGRESS, row.state);
1799  EXPECT_FALSE(row.opened);
1800
1801  // Finish the download.  We're ok relying on the history to be flushed
1802  // at this point as our queries will be behind the history updates
1803  // invoked by completion.
1804  scoped_ptr<content::DownloadTestObserver> download_observer(
1805      CreateWaiter(browser(), 1));
1806  ui_test_utils::NavigateToURL(browser(),
1807      GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl));
1808  download_observer->WaitForFinished();
1809  EXPECT_EQ(1u, download_observer->NumDownloadsSeenInState(
1810      DownloadItem::INTERRUPTED));
1811  base::Time end(base::Time::Now());
1812
1813  // Get what was stored in the history.
1814  ASSERT_TRUE(DownloadsHistoryDataCollector(
1815      browser()->profile()).WaitForDownloadInfo(&downloads_in_database));
1816  ASSERT_EQ(1u, downloads_in_database->size());
1817
1818  // Confirm history storage is what you expect for an interrupted slow download
1819  // job. The download isn't continuable, so there's no intermediate file.
1820  history::DownloadRow& row1(downloads_in_database->at(0));
1821  EXPECT_EQ(DestinationFile(browser(), file), row1.target_path);
1822  EXPECT_TRUE(row1.current_path.empty());
1823  ASSERT_EQ(2u, row1.url_chain.size());
1824  EXPECT_EQ(redirect_url.spec(), row1.url_chain[0].spec());
1825  EXPECT_EQ(download_url.spec(), row1.url_chain[1].spec());
1826  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, row1.danger_type);
1827  EXPECT_LE(start, row1.start_time);
1828  EXPECT_GE(end, row1.end_time);
1829  EXPECT_EQ(URLRequestSlowDownloadJob::kFirstDownloadSize,
1830            row1.received_bytes);
1831  EXPECT_EQ(URLRequestSlowDownloadJob::kFirstDownloadSize
1832            + URLRequestSlowDownloadJob::kSecondDownloadSize, row1.total_bytes);
1833  EXPECT_EQ(content::DownloadItem::INTERRUPTED, row1.state);
1834  EXPECT_EQ(content::DOWNLOAD_INTERRUPT_REASON_NETWORK_FAILED,
1835            row1.interrupt_reason);
1836  EXPECT_FALSE(row1.opened);
1837}
1838
1839// Make sure a dangerous file shows up properly in the history.
1840IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadHistoryDangerCheck) {
1841#if defined(OS_WIN) && defined(USE_ASH)
1842  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
1843  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
1844    return;
1845#endif
1846
1847  // .swf file so that it's dangerous on all platforms (including CrOS).
1848  base::FilePath file(FILE_PATH_LITERAL("downloads/dangerous/dangerous.swf"));
1849  GURL download_url(URLRequestMockHTTPJob::GetMockUrl(file));
1850
1851  // Download the url and wait until the object has been stored.
1852  scoped_ptr<content::DownloadTestObserver> download_observer(
1853      new content::DownloadTestObserverTerminal(
1854          DownloadManagerForBrowser(browser()), 1,
1855          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE));
1856  base::Time start(base::Time::Now());
1857  HistoryObserver observer(browser()->profile());
1858  observer.SetFilterCallback(base::Bind(&HasDataAndName));
1859  ui_test_utils::NavigateToURL(browser(), download_url);
1860  observer.WaitForStored();
1861
1862  // Get the details on what was stored into the history.
1863  scoped_ptr<std::vector<history::DownloadRow> > downloads_in_database;
1864  ASSERT_TRUE(DownloadsHistoryDataCollector(
1865      browser()->profile()).WaitForDownloadInfo(&downloads_in_database));
1866  ASSERT_EQ(1u, downloads_in_database->size());
1867
1868  // Confirm history storage is what you expect for an unvalidated
1869  // dangerous file.
1870  history::DownloadRow& row(downloads_in_database->at(0));
1871  EXPECT_EQ(DestinationFile(browser(), file), row.target_path);
1872  EXPECT_NE(DownloadTargetDeterminer::GetCrDownloadPath(
1873                DestinationFile(browser(), file)),
1874            row.current_path);
1875  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE, row.danger_type);
1876  EXPECT_LE(start, row.start_time);
1877  EXPECT_EQ(content::DownloadItem::IN_PROGRESS, row.state);
1878  EXPECT_FALSE(row.opened);
1879
1880  // Validate the download and wait for it to finish.
1881  std::vector<DownloadItem*> downloads;
1882  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
1883  ASSERT_EQ(1u, downloads.size());
1884  downloads[0]->ValidateDangerousDownload();
1885  download_observer->WaitForFinished();
1886
1887  // Get history details and confirm it's what you expect.
1888  downloads_in_database->clear();
1889  ASSERT_TRUE(DownloadsHistoryDataCollector(
1890      browser()->profile()).WaitForDownloadInfo(&downloads_in_database));
1891  ASSERT_EQ(1u, downloads_in_database->size());
1892  history::DownloadRow& row1(downloads_in_database->at(0));
1893  EXPECT_EQ(DestinationFile(browser(), file), row1.target_path);
1894  EXPECT_EQ(DestinationFile(browser(), file), row1.current_path);
1895  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED, row1.danger_type);
1896  EXPECT_LE(start, row1.start_time);
1897  EXPECT_EQ(content::DownloadItem::COMPLETE, row1.state);
1898  EXPECT_FALSE(row1.opened);
1899  // Not checking file size--not relevant to the point of the test, and
1900  // the file size is actually different on Windows and other platforms,
1901  // because for source control simplicity it's actually a text file, and
1902  // there are CRLF transformations for those files.
1903}
1904
1905IN_PROC_BROWSER_TEST_F(DownloadTest, PRE_DownloadTest_History) {
1906  // Download a file and wait for it to be stored.
1907  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1908  GURL download_url(URLRequestMockHTTPJob::GetMockUrl(file));
1909  HistoryObserver observer(browser()->profile());
1910  DownloadAndWait(browser(), download_url);
1911  observer.WaitForStored();
1912  HistoryServiceFactory::GetForProfile(
1913      browser()->profile(), Profile::IMPLICIT_ACCESS)->FlushForTest(
1914      base::Bind(&base::MessageLoop::Quit,
1915                 base::Unretained(base::MessageLoop::current()->current())));
1916  content::RunMessageLoop();
1917}
1918
1919#if defined(OS_CHROMEOS)
1920// Times out on ChromeOS: http://crbug.com/217810
1921#define MAYBE_DownloadTest_History DISABLED_DownloadTest_History
1922#else
1923#define MAYBE_DownloadTest_History DownloadTest_History
1924#endif
1925IN_PROC_BROWSER_TEST_F(DownloadTest, MAYBE_DownloadTest_History) {
1926  // This starts up right after PRE_DownloadTest_History and shares the same
1927  // profile directory.
1928  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1929  GURL download_url(URLRequestMockHTTPJob::GetMockUrl(file));
1930  std::vector<DownloadItem*> downloads;
1931  content::DownloadManager* manager = DownloadManagerForBrowser(browser());
1932
1933  // Wait for the history to be loaded with a single DownloadItem. Check that
1934  // it's the file that was downloaded in PRE_DownloadTest_History.
1935  CreatedObserver created_observer(manager);
1936  created_observer.Wait();
1937  manager->GetAllDownloads(&downloads);
1938  ASSERT_EQ(1UL, downloads.size());
1939  DownloadItem* item = downloads[0];
1940  EXPECT_EQ(file.value(), item->GetFullPath().BaseName().value());
1941  EXPECT_EQ(file.value(), item->GetTargetFilePath().BaseName().value());
1942  EXPECT_EQ(download_url, item->GetURL());
1943  // The following are set by download-test1.lib.mock-http-headers.
1944  std::string etag = item->GetETag();
1945  base::TrimWhitespaceASCII(etag, base::TRIM_ALL, &etag);
1946  EXPECT_EQ("abracadabra", etag);
1947
1948  std::string last_modified = item->GetLastModifiedTime();
1949  base::TrimWhitespaceASCII(last_modified, base::TRIM_ALL, &last_modified);
1950  EXPECT_EQ("Mon, 13 Nov 2006 20:31:09 GMT", last_modified);
1951
1952  // Downloads that were restored from history shouldn't cause the download
1953  // shelf to be displayed.
1954  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
1955}
1956
1957// Test for crbug.com/14505. This tests that chrome:// urls are still functional
1958// after download of a file while viewing another chrome://.
1959IN_PROC_BROWSER_TEST_F(DownloadTest, ChromeURLAfterDownload) {
1960  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1961  GURL download_url(URLRequestMockHTTPJob::GetMockUrl(file));
1962  GURL flags_url(chrome::kChromeUIFlagsURL);
1963  GURL extensions_url(chrome::kChromeUIExtensionsFrameURL);
1964
1965  ui_test_utils::NavigateToURL(browser(), flags_url);
1966  DownloadAndWait(browser(), download_url);
1967  ui_test_utils::NavigateToURL(browser(), extensions_url);
1968  WebContents* contents =
1969      browser()->tab_strip_model()->GetActiveWebContents();
1970  ASSERT_TRUE(contents);
1971  bool webui_responded = false;
1972  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1973      contents,
1974      "window.domAutomationController.send(window.webuiResponded);",
1975      &webui_responded));
1976  EXPECT_TRUE(webui_responded);
1977}
1978
1979// Test for crbug.com/12745. This tests that if a download is initiated from
1980// a chrome:// page that has registered and onunload handler, the browser
1981// will be able to close.
1982IN_PROC_BROWSER_TEST_F(DownloadTest, BrowserCloseAfterDownload) {
1983  GURL downloads_url(chrome::kChromeUIFlagsURL);
1984  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
1985  GURL download_url(URLRequestMockHTTPJob::GetMockUrl(file));
1986
1987  ui_test_utils::NavigateToURL(browser(), downloads_url);
1988  WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents();
1989  ASSERT_TRUE(contents);
1990  bool result = false;
1991  EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
1992      contents,
1993      "window.onunload = function() { var do_nothing = 0; }; "
1994      "window.domAutomationController.send(true);",
1995      &result));
1996  EXPECT_TRUE(result);
1997
1998  DownloadAndWait(browser(), download_url);
1999
2000  content::WindowedNotificationObserver signal(
2001      chrome::NOTIFICATION_BROWSER_CLOSED,
2002      content::Source<Browser>(browser()));
2003  chrome::CloseWindow(browser());
2004  signal.Wait();
2005}
2006
2007// Test to make sure the 'download' attribute in anchor tag is respected.
2008IN_PROC_BROWSER_TEST_F(DownloadTest, AnchorDownloadTag) {
2009  base::FilePath file(FILE_PATH_LITERAL("download-anchor-attrib.html"));
2010  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
2011
2012  // Create a download, wait until it's complete, and confirm
2013  // we're in the expected state.
2014  scoped_ptr<content::DownloadTestObserver> observer(
2015      CreateWaiter(browser(), 1));
2016  ui_test_utils::NavigateToURL(browser(), url);
2017  observer->WaitForFinished();
2018  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2019  CheckDownloadStates(1, DownloadItem::COMPLETE);
2020
2021  // Confirm the downloaded data exists.
2022  base::FilePath downloaded_file = GetDownloadDirectory(browser());
2023  downloaded_file = downloaded_file.Append(FILE_PATH_LITERAL("a_red_dot.png"));
2024  EXPECT_TRUE(base::PathExists(downloaded_file));
2025}
2026
2027// Test to make sure auto-open works.
2028IN_PROC_BROWSER_TEST_F(DownloadTest, AutoOpen) {
2029  base::FilePath file(FILE_PATH_LITERAL("download-autoopen.txt"));
2030  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
2031
2032  ASSERT_TRUE(
2033      GetDownloadPrefs(browser())->EnableAutoOpenBasedOnExtension(file));
2034
2035  DownloadAndWait(browser(), url);
2036
2037  // Find the download and confirm it was opened.
2038  std::vector<DownloadItem*> downloads;
2039  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
2040  ASSERT_EQ(1u, downloads.size());
2041  EXPECT_EQ(DownloadItem::COMPLETE, downloads[0]->GetState());
2042
2043  // Unfortunately, this will block forever, causing a timeout, if
2044  // the download is never opened.
2045  content::DownloadUpdatedObserver(
2046      downloads[0], base::Bind(&WasAutoOpened)).WaitForEvent();
2047  EXPECT_TRUE(downloads[0]->GetOpened());  // Confirm it anyway.
2048
2049  // As long as we're here, confirmed everything else is good.
2050  EXPECT_EQ(1, browser()->tab_strip_model()->count());
2051  CheckDownload(browser(), file, file);
2052  // Download shelf should close. Download panel stays open on ChromeOS.
2053  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2054}
2055
2056// Download an extension.  Expect a dangerous download warning.
2057// Deny the download.
2058IN_PROC_BROWSER_TEST_F(DownloadTest, CrxDenyInstall) {
2059  FeatureSwitch::ScopedOverride enable_easy_off_store_install(
2060      FeatureSwitch::easy_off_store_install(), true);
2061
2062  GURL extension_url(URLRequestMockHTTPJob::GetMockUrl(kGoodCrxPath));
2063
2064  scoped_ptr<content::DownloadTestObserver> observer(
2065      DangerousDownloadWaiter(
2066          browser(), 1,
2067          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_DENY));
2068  ui_test_utils::NavigateToURL(browser(), extension_url);
2069
2070  observer->WaitForFinished();
2071  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::CANCELLED));
2072  EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
2073
2074  // Download shelf should close.
2075  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2076
2077  // Check that the CRX is not installed.
2078  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
2079      browser()->profile())->extension_service();
2080  ASSERT_FALSE(extension_service->GetExtensionById(kGoodCrxId, false));
2081}
2082
2083// Download an extension.  Expect a dangerous download warning.
2084// Allow the download, deny the install.
2085IN_PROC_BROWSER_TEST_F(DownloadTest, CrxInstallDenysPermissions) {
2086  FeatureSwitch::ScopedOverride enable_easy_off_store_install(
2087      FeatureSwitch::easy_off_store_install(), true);
2088
2089  GURL extension_url(URLRequestMockHTTPJob::GetMockUrl(kGoodCrxPath));
2090
2091  // Install a mock install UI that simulates a user denying permission to
2092  // finish the install.
2093  download_crx_util::SetMockInstallPromptForTesting(
2094      scoped_ptr<ExtensionInstallPrompt>(
2095          new MockAbortExtensionInstallPrompt()));
2096
2097  scoped_ptr<content::DownloadTestObserver> observer(
2098      DangerousDownloadWaiter(
2099          browser(), 1,
2100          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
2101  ui_test_utils::NavigateToURL(browser(), extension_url);
2102
2103  observer->WaitForFinished();
2104  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2105  CheckDownloadStates(1, DownloadItem::COMPLETE);
2106  EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
2107
2108  // Download shelf should close from auto-open.
2109  content::DownloadManager::DownloadVector downloads;
2110  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
2111  ASSERT_EQ(1u, downloads.size());
2112  content::DownloadUpdatedObserver(
2113      downloads[0], base::Bind(&WasAutoOpened)).WaitForEvent();
2114  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2115
2116  // Check that the extension was not installed.
2117  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
2118      browser()->profile())->extension_service();
2119  ASSERT_FALSE(extension_service->GetExtensionById(kGoodCrxId, false));
2120}
2121
2122// Download an extension.  Expect a dangerous download warning.
2123// Allow the download, and the install.
2124IN_PROC_BROWSER_TEST_F(DownloadTest, CrxInstallAcceptPermissions) {
2125  FeatureSwitch::ScopedOverride enable_easy_off_store_install(
2126      FeatureSwitch::easy_off_store_install(), true);
2127
2128  GURL extension_url(URLRequestMockHTTPJob::GetMockUrl(kGoodCrxPath));
2129
2130  // Install a mock install UI that simulates a user allowing permission to
2131  // finish the install.
2132  SetAllowMockInstallPrompt();
2133
2134  scoped_ptr<content::DownloadTestObserver> observer(
2135      DangerousDownloadWaiter(
2136          browser(), 1,
2137          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
2138  ui_test_utils::NavigateToURL(browser(), extension_url);
2139
2140  observer->WaitForFinished();
2141  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2142  CheckDownloadStates(1, DownloadItem::COMPLETE);
2143  EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
2144
2145  // Download shelf should close from auto-open.
2146  content::DownloadManager::DownloadVector downloads;
2147  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
2148  ASSERT_EQ(1u, downloads.size());
2149  content::DownloadUpdatedObserver(
2150      downloads[0], base::Bind(&WasAutoOpened)).WaitForEvent();
2151  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2152
2153  // Check that the extension was installed.
2154  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
2155      browser()->profile())->extension_service();
2156  ASSERT_TRUE(extension_service->GetExtensionById(kGoodCrxId, false));
2157}
2158
2159// Test installing a CRX that fails integrity checks.
2160IN_PROC_BROWSER_TEST_F(DownloadTest, CrxInvalid) {
2161  base::FilePath file(FILE_PATH_LITERAL("extensions/bad_signature.crx"));
2162  GURL extension_url(URLRequestMockHTTPJob::GetMockUrl(file));
2163
2164  // Install a mock install UI that simulates a user allowing permission to
2165  // finish the install, and dismisses any error message.  We check that the
2166  // install failed below.
2167  SetAllowMockInstallPrompt();
2168
2169  scoped_ptr<content::DownloadTestObserver> observer(
2170      DangerousDownloadWaiter(
2171          browser(), 1,
2172          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
2173  ui_test_utils::NavigateToURL(browser(), extension_url);
2174
2175  observer->WaitForFinished();
2176  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2177  CheckDownloadStates(1, DownloadItem::COMPLETE);
2178
2179  // Check that the extension was not installed.
2180  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
2181      browser()->profile())->extension_service();
2182  ASSERT_FALSE(extension_service->GetExtensionById(kGoodCrxId, false));
2183}
2184
2185// Install a large (100kb) theme.
2186IN_PROC_BROWSER_TEST_F(DownloadTest, CrxLargeTheme) {
2187  FeatureSwitch::ScopedOverride enable_easy_off_store_install(
2188      FeatureSwitch::easy_off_store_install(), true);
2189
2190  GURL extension_url(URLRequestMockHTTPJob::GetMockUrl(kLargeThemePath));
2191
2192  // Install a mock install UI that simulates a user allowing permission to
2193  // finish the install.
2194  SetAllowMockInstallPrompt();
2195
2196  scoped_ptr<content::DownloadTestObserver> observer(
2197      DangerousDownloadWaiter(
2198          browser(), 1,
2199          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
2200  ui_test_utils::NavigateToURL(browser(), extension_url);
2201
2202  observer->WaitForFinished();
2203  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2204  CheckDownloadStates(1, DownloadItem::COMPLETE);
2205  EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
2206
2207  // Download shelf should close from auto-open.
2208  content::DownloadManager::DownloadVector downloads;
2209  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
2210  ASSERT_EQ(1u, downloads.size());
2211  content::DownloadUpdatedObserver(
2212      downloads[0], base::Bind(&WasAutoOpened)).WaitForEvent();
2213  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2214
2215  // Check that the extension was installed.
2216  ExtensionService* extension_service = extensions::ExtensionSystem::Get(
2217      browser()->profile())->extension_service();
2218  ASSERT_TRUE(extension_service->GetExtensionById(kLargeThemeCrxId, false));
2219}
2220
2221// Tests for download initiation functions.
2222IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadUrl) {
2223  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
2224  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
2225
2226  // DownloadUrl always prompts; return acceptance of whatever it prompts.
2227  EnableFileChooser(true);
2228
2229  WebContents* web_contents =
2230      browser()->tab_strip_model()->GetActiveWebContents();
2231  ASSERT_TRUE(web_contents);
2232
2233  content::DownloadTestObserver* observer(
2234      new content::DownloadTestObserverTerminal(
2235          DownloadManagerForBrowser(browser()), 1,
2236          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2237  scoped_ptr<DownloadUrlParameters> params(
2238      DownloadUrlParameters::FromWebContents(web_contents, url));
2239  params->set_prompt(true);
2240  DownloadManagerForBrowser(browser())->DownloadUrl(params.Pass());
2241  observer->WaitForFinished();
2242  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2243  CheckDownloadStates(1, DownloadItem::COMPLETE);
2244  EXPECT_TRUE(DidShowFileChooser());
2245
2246  // Check state.
2247  EXPECT_EQ(1, browser()->tab_strip_model()->count());
2248  ASSERT_TRUE(CheckDownload(browser(), file, file));
2249  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
2250}
2251
2252IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadUrlToPath) {
2253  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
2254  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
2255
2256  WebContents* web_contents =
2257      browser()->tab_strip_model()->GetActiveWebContents();
2258  ASSERT_TRUE(web_contents);
2259
2260  base::ScopedTempDir other_directory;
2261  ASSERT_TRUE(other_directory.CreateUniqueTempDir());
2262  base::FilePath target_file_full_path
2263      = other_directory.path().Append(file.BaseName());
2264  content::DownloadTestObserver* observer(CreateWaiter(browser(), 1));
2265  scoped_ptr<DownloadUrlParameters> params(
2266      DownloadUrlParameters::FromWebContents(web_contents, url));
2267  params->set_file_path(target_file_full_path);
2268  DownloadManagerForBrowser(browser())->DownloadUrl(params.Pass());
2269  observer->WaitForFinished();
2270  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2271
2272  // Check state.
2273  EXPECT_EQ(1, browser()->tab_strip_model()->count());
2274  ASSERT_TRUE(CheckDownloadFullPaths(browser(),
2275                                     target_file_full_path,
2276                                     OriginFile(file)));
2277
2278  // Temporary are treated as auto-opened, and after that open won't be
2279  // visible; wait for auto-open and confirm not visible.
2280  std::vector<DownloadItem*> downloads;
2281  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
2282  ASSERT_EQ(1u, downloads.size());
2283  content::DownloadUpdatedObserver(
2284      downloads[0], base::Bind(&WasAutoOpened)).WaitForEvent();
2285  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2286}
2287
2288IN_PROC_BROWSER_TEST_F(DownloadTest, SavePageNonHTMLViaGet) {
2289  // Do initial setup.
2290  ASSERT_TRUE(test_server()->Start());
2291  EnableFileChooser(true);
2292  std::vector<DownloadItem*> download_items;
2293  GetDownloads(browser(), &download_items);
2294  ASSERT_TRUE(download_items.empty());
2295
2296  // Navigate to a non-HTML resource. The resource also has
2297  // Cache-Control: no-cache set, which normally requires revalidation
2298  // each time.
2299  GURL url = test_server()->GetURL("files/downloads/image.jpg");
2300  ASSERT_TRUE(url.is_valid());
2301  ui_test_utils::NavigateToURL(browser(), url);
2302
2303  // Stop the test server, and then try to save the page. If cache validation
2304  // is not bypassed then this will fail since the server is no longer
2305  // reachable.
2306  ASSERT_TRUE(test_server()->Stop());
2307  scoped_ptr<content::DownloadTestObserver> waiter(
2308      new content::DownloadTestObserverTerminal(
2309          DownloadManagerForBrowser(browser()), 1,
2310          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2311  chrome::SavePage(browser());
2312  waiter->WaitForFinished();
2313  EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2314  CheckDownloadStates(1, DownloadItem::COMPLETE);
2315
2316  // Validate that the correct file was downloaded.
2317  GetDownloads(browser(), &download_items);
2318  EXPECT_TRUE(DidShowFileChooser());
2319  ASSERT_EQ(1u, download_items.size());
2320  ASSERT_EQ(url, download_items[0]->GetOriginalUrl());
2321
2322  // Try to download it via a context menu.
2323  scoped_ptr<content::DownloadTestObserver> waiter_context_menu(
2324      new content::DownloadTestObserverTerminal(
2325          DownloadManagerForBrowser(browser()), 1,
2326          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2327  content::ContextMenuParams context_menu_params;
2328  context_menu_params.media_type = blink::WebContextMenuData::MediaTypeImage;
2329  context_menu_params.src_url = url;
2330  context_menu_params.page_url = url;
2331  TestRenderViewContextMenu menu(
2332      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
2333      context_menu_params);
2334  menu.Init();
2335  menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
2336  waiter_context_menu->WaitForFinished();
2337  EXPECT_EQ(
2338      1u, waiter_context_menu->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2339  CheckDownloadStates(2, DownloadItem::COMPLETE);
2340
2341  // Validate that the correct file was downloaded via the context menu.
2342  download_items.clear();
2343  GetDownloads(browser(), &download_items);
2344  EXPECT_TRUE(DidShowFileChooser());
2345  ASSERT_EQ(2u, download_items.size());
2346  ASSERT_EQ(url, download_items[0]->GetOriginalUrl());
2347  ASSERT_EQ(url, download_items[1]->GetOriginalUrl());
2348}
2349
2350IN_PROC_BROWSER_TEST_F(DownloadTest, SavePageNonHTMLViaPost) {
2351  // Do initial setup.
2352  ASSERT_TRUE(test_server()->Start());
2353  EnableFileChooser(true);
2354  std::vector<DownloadItem*> download_items;
2355  GetDownloads(browser(), &download_items);
2356  ASSERT_TRUE(download_items.empty());
2357
2358  // Navigate to a form page.
2359  GURL form_url = test_server()->GetURL(
2360      "files/downloads/form_page_to_post.html");
2361  ASSERT_TRUE(form_url.is_valid());
2362  ui_test_utils::NavigateToURL(browser(), form_url);
2363
2364  // Submit the form. This will send a POST reqeuest, and the response is a
2365  // JPEG image. The resource also has Cache-Control: no-cache set,
2366  // which normally requires revalidation each time.
2367  GURL jpeg_url = test_server()->GetURL("files/post/downloads/image.jpg");
2368  ASSERT_TRUE(jpeg_url.is_valid());
2369  WebContents* web_contents =
2370      browser()->tab_strip_model()->GetActiveWebContents();
2371  ASSERT_TRUE(web_contents != NULL);
2372  content::WindowedNotificationObserver observer(
2373      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
2374      content::Source<content::NavigationController>(
2375          &web_contents->GetController()));
2376  content::RenderFrameHost* render_frame_host = web_contents->GetMainFrame();
2377  ASSERT_TRUE(render_frame_host != NULL);
2378  render_frame_host->ExecuteJavaScript(base::ASCIIToUTF16("SubmitForm()"));
2379  observer.Wait();
2380  EXPECT_EQ(jpeg_url, web_contents->GetURL());
2381
2382  // Stop the test server, and then try to save the page. If cache validation
2383  // is not bypassed then this will fail since the server is no longer
2384  // reachable. This will also fail if it tries to be retrieved via "GET"
2385  // rather than "POST".
2386  ASSERT_TRUE(test_server()->Stop());
2387  scoped_ptr<content::DownloadTestObserver> waiter(
2388      new content::DownloadTestObserverTerminal(
2389          DownloadManagerForBrowser(browser()), 1,
2390          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2391  chrome::SavePage(browser());
2392  waiter->WaitForFinished();
2393  EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2394  CheckDownloadStates(1, DownloadItem::COMPLETE);
2395
2396  // Validate that the correct file was downloaded.
2397  GetDownloads(browser(), &download_items);
2398  EXPECT_TRUE(DidShowFileChooser());
2399  ASSERT_EQ(1u, download_items.size());
2400  ASSERT_EQ(jpeg_url, download_items[0]->GetOriginalUrl());
2401
2402  // Try to download it via a context menu.
2403  scoped_ptr<content::DownloadTestObserver> waiter_context_menu(
2404      new content::DownloadTestObserverTerminal(
2405          DownloadManagerForBrowser(browser()), 1,
2406          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2407  content::ContextMenuParams context_menu_params;
2408  context_menu_params.media_type = blink::WebContextMenuData::MediaTypeImage;
2409  context_menu_params.src_url = jpeg_url;
2410  context_menu_params.page_url = jpeg_url;
2411  TestRenderViewContextMenu menu(web_contents->GetMainFrame(),
2412                                 context_menu_params);
2413  menu.Init();
2414  menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
2415  waiter_context_menu->WaitForFinished();
2416  EXPECT_EQ(
2417      1u, waiter_context_menu->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2418  CheckDownloadStates(2, DownloadItem::COMPLETE);
2419
2420  // Validate that the correct file was downloaded via the context menu.
2421  download_items.clear();
2422  GetDownloads(browser(), &download_items);
2423  EXPECT_TRUE(DidShowFileChooser());
2424  ASSERT_EQ(2u, download_items.size());
2425  ASSERT_EQ(jpeg_url, download_items[0]->GetOriginalUrl());
2426  ASSERT_EQ(jpeg_url, download_items[1]->GetOriginalUrl());
2427}
2428
2429IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadErrorsServer) {
2430  DownloadInfo download_info[] = {
2431    {  // Normal navigated download.
2432      "a_zip_file.zip",
2433      DOWNLOAD_NAVIGATE,
2434      content::DOWNLOAD_INTERRUPT_REASON_NONE,
2435      true,
2436      false
2437    },
2438    {  // Normal direct download.
2439      "a_zip_file.zip",
2440      DOWNLOAD_DIRECT,
2441      content::DOWNLOAD_INTERRUPT_REASON_NONE,
2442      true,
2443      false
2444    },
2445    {  // Direct download with 404 error.
2446      "there_IS_no_spoon.zip",
2447      DOWNLOAD_DIRECT,
2448      content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2449      true,
2450      false
2451    },
2452    {  // Navigated download with 404 error.
2453      "there_IS_no_spoon.zip",
2454      DOWNLOAD_NAVIGATE,
2455      content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
2456      false,
2457      false
2458    },
2459    {  // Direct download with 400 error.
2460      "zip_file_not_found.zip",
2461      DOWNLOAD_DIRECT,
2462      content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
2463      true,
2464      false
2465    },
2466    {  // Navigated download with 400 error.
2467      "zip_file_not_found.zip",
2468      DOWNLOAD_NAVIGATE,
2469      content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
2470      false,
2471      false
2472    }
2473  };
2474
2475  DownloadFilesCheckErrors(ARRAYSIZE_UNSAFE(download_info), download_info);
2476}
2477
2478IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadErrorsFile) {
2479  FileErrorInjectInfo error_info[] = {
2480    {  // Navigated download with injected "Disk full" error in Initialize().
2481      { "a_zip_file.zip",
2482        DOWNLOAD_NAVIGATE,
2483        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2484        1
2485      },
2486      {
2487        "",
2488        content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
2489        0,
2490        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2491      }
2492    },
2493    {  // Direct download with injected "Disk full" error in Initialize().
2494      { "a_zip_file.zip",
2495        DOWNLOAD_DIRECT,
2496        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2497        1
2498      },
2499      {
2500        "",
2501        content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
2502        0,
2503        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2504      }
2505    },
2506    {  // Navigated download with injected "Disk full" error in Write().
2507      { "a_zip_file.zip",
2508        DOWNLOAD_NAVIGATE,
2509        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2510        1
2511      },
2512      {
2513        "",
2514        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2515        0,
2516        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2517      }
2518    },
2519    {  // Direct download with injected "Disk full" error in Write().
2520      { "a_zip_file.zip",
2521        DOWNLOAD_DIRECT,
2522        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2523        1
2524      },
2525      {
2526        "",
2527        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2528        0,
2529        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2530      }
2531    },
2532    {  // Navigated download with injected "Failed" error in Initialize().
2533      { "a_zip_file.zip",
2534        DOWNLOAD_NAVIGATE,
2535        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2536        1
2537      },
2538      {
2539        "",
2540        content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
2541        0,
2542        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2543      }
2544    },
2545    {  // Direct download with injected "Failed" error in Initialize().
2546      { "a_zip_file.zip",
2547        DOWNLOAD_DIRECT,
2548        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2549        1
2550      },
2551      {
2552        "",
2553        content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
2554        0,
2555        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2556      }
2557    },
2558    {  // Navigated download with injected "Failed" error in Write().
2559      { "a_zip_file.zip",
2560        DOWNLOAD_NAVIGATE,
2561        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2562        1
2563      },
2564      {
2565        "",
2566        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2567        0,
2568        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2569      }
2570    },
2571    {  // Direct download with injected "Failed" error in Write().
2572      { "a_zip_file.zip",
2573        DOWNLOAD_DIRECT,
2574        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2575        1
2576      },
2577      {
2578        "",
2579        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2580        0,
2581        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2582      }
2583    },
2584    {  // Navigated download with injected "Name too long" error in
2585       // Initialize().
2586      { "a_zip_file.zip",
2587        DOWNLOAD_NAVIGATE,
2588        content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG,
2589        1
2590      },
2591      {
2592        "",
2593        content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
2594        0,
2595        content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG,
2596      }
2597    },
2598    {  // Direct download with injected "Name too long" error in Initialize().
2599      { "a_zip_file.zip",
2600        DOWNLOAD_DIRECT,
2601        content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG,
2602        1
2603      },
2604      {
2605        "",
2606        content::TestFileErrorInjector::FILE_OPERATION_INITIALIZE,
2607        0,
2608        content::DOWNLOAD_INTERRUPT_REASON_FILE_NAME_TOO_LONG,
2609      }
2610    },
2611    {  // Navigated download with injected "Name too long" error in Write().
2612      { "a_zip_file.zip",
2613        DOWNLOAD_NAVIGATE,
2614        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2615        1
2616      },
2617      {
2618        "",
2619        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2620        0,
2621        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2622      }
2623    },
2624    {  // Direct download with injected "Name too long" error in Write().
2625      { "a_zip_file.zip",
2626        DOWNLOAD_DIRECT,
2627        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2628        1
2629      },
2630      {
2631        "",
2632        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2633        0,
2634        content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
2635      }
2636    },
2637    {  // Direct download with injected "Disk full" error in 2nd Write().
2638      { "06bESSE21Evolution.ppt",
2639        DOWNLOAD_DIRECT,
2640        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2641        1
2642      },
2643      {
2644        "",
2645        content::TestFileErrorInjector::FILE_OPERATION_WRITE,
2646        1,
2647        content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE,
2648      }
2649    }
2650  };
2651
2652  DownloadInsertFilesErrorCheckErrors(ARRAYSIZE_UNSAFE(error_info), error_info);
2653}
2654
2655IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadErrorReadonlyFolder) {
2656  DownloadInfo download_info[] = {
2657    {
2658      "a_zip_file.zip",
2659      DOWNLOAD_DIRECT,
2660      // This passes because we switch to the My Documents folder.
2661      content::DOWNLOAD_INTERRUPT_REASON_NONE,
2662      true,
2663      true
2664    },
2665    {
2666      "a_zip_file.zip",
2667      DOWNLOAD_NAVIGATE,
2668      // This passes because we switch to the My Documents folder.
2669      content::DOWNLOAD_INTERRUPT_REASON_NONE,
2670      true,
2671      true
2672    }
2673  };
2674
2675  DownloadFilesToReadonlyFolder(ARRAYSIZE_UNSAFE(download_info), download_info);
2676}
2677
2678// Test that we show a dangerous downloads warning for a dangerous file
2679// downloaded through a blob: URL.
2680IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadDangerousBlobData) {
2681#if defined(OS_WIN)
2682  // On Windows, if SafeBrowsing is enabled, certain file types (.exe, .cab,
2683  // .msi) will be handled by the DownloadProtectionService. However, if the URL
2684  // is non-standard (e.g. blob:) then those files won't be handled by the
2685  // DPS. We should be showing the dangerous download warning for any file
2686  // considered dangerous and isn't handled by the DPS.
2687  const char kFilename[] = "foo.exe";
2688#else
2689  const char kFilename[] = "foo.swf";
2690#endif
2691
2692  std::string path("files/downloads/download-dangerous-blob.html?filename=");
2693  path += kFilename;
2694
2695  // Need to use http urls because the blob js doesn't work on file urls for
2696  // security reasons.
2697  ASSERT_TRUE(test_server()->Start());
2698  GURL url(test_server()->GetURL(path));
2699
2700  content::DownloadTestObserver* observer(DangerousDownloadWaiter(
2701      browser(), 1,
2702      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
2703  ui_test_utils::NavigateToURL(browser(), url);
2704  observer->WaitForFinished();
2705
2706  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2707  EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
2708}
2709
2710IN_PROC_BROWSER_TEST_F(DownloadTest, LoadURLExternallyReferrerPolicy) {
2711  // Do initial setup.
2712  ASSERT_TRUE(test_server()->Start());
2713  EnableFileChooser(true);
2714  std::vector<DownloadItem*> download_items;
2715  GetDownloads(browser(), &download_items);
2716  ASSERT_TRUE(download_items.empty());
2717
2718  // Navigate to a page with a referrer policy and a link on it. The link points
2719  // to testserver's /echoheader.
2720  GURL url = test_server()->GetURL("files/downloads/referrer_policy.html");
2721  ASSERT_TRUE(url.is_valid());
2722  ui_test_utils::NavigateToURL(browser(), url);
2723
2724  scoped_ptr<content::DownloadTestObserver> waiter(
2725      new content::DownloadTestObserverTerminal(
2726          DownloadManagerForBrowser(browser()), 1,
2727          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2728
2729  // Click on the link with the alt key pressed. This will download the link
2730  // target.
2731  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2732  blink::WebMouseEvent mouse_event;
2733  mouse_event.type = blink::WebInputEvent::MouseDown;
2734  mouse_event.button = blink::WebMouseEvent::ButtonLeft;
2735  mouse_event.x = 15;
2736  mouse_event.y = 15;
2737  mouse_event.clickCount = 1;
2738  mouse_event.modifiers = blink::WebInputEvent::AltKey;
2739  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
2740  mouse_event.type = blink::WebInputEvent::MouseUp;
2741  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
2742
2743  waiter->WaitForFinished();
2744  EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2745  CheckDownloadStates(1, DownloadItem::COMPLETE);
2746
2747  // Validate that the correct file was downloaded.
2748  GetDownloads(browser(), &download_items);
2749  ASSERT_EQ(1u, download_items.size());
2750  ASSERT_EQ(test_server()->GetURL("echoheader?Referer"),
2751            download_items[0]->GetOriginalUrl());
2752
2753  // Check that the file contains the expected referrer.
2754  base::FilePath file(download_items[0]->GetTargetFilePath());
2755  std::string expected_contents = test_server()->GetURL(std::string()).spec();
2756  ASSERT_TRUE(VerifyFile(file, expected_contents, expected_contents.length()));
2757}
2758
2759// This test ensures that the Referer header is properly sanitized when
2760// Save Link As is chosen from the context menu.
2761IN_PROC_BROWSER_TEST_F(DownloadTest, SaveLinkAsReferrerPolicyOrigin) {
2762  // Do initial setup.
2763  ASSERT_TRUE(test_server()->Start());
2764  net::SpawnedTestServer ssl_test_server(
2765      net::SpawnedTestServer::TYPE_HTTPS,
2766      net::SpawnedTestServer::kLocalhost,
2767      base::FilePath(FILE_PATH_LITERAL("chrome/test/data/referrer_policy")));
2768  ASSERT_TRUE(ssl_test_server.Start());
2769  EnableFileChooser(true);
2770  std::vector<DownloadItem*> download_items;
2771  GetDownloads(browser(), &download_items);
2772  ASSERT_TRUE(download_items.empty());
2773
2774  // Navigate to the initial page, where Save Link As will be executed.
2775  GURL url = ssl_test_server.GetURL(
2776      std::string("files/referrer-policy-start.html?policy=origin") +
2777      "&port=" + base::IntToString(test_server()->host_port_pair().port()) +
2778      "&ssl_port=" +
2779      base::IntToString(ssl_test_server.host_port_pair().port()) +
2780      "&redirect=echoheader&link=true&target=");
2781  ASSERT_TRUE(url.is_valid());
2782  ui_test_utils::NavigateToURL(browser(), url);
2783
2784  scoped_ptr<content::DownloadTestObserver> waiter(
2785      new content::DownloadTestObserverTerminal(
2786          DownloadManagerForBrowser(browser()), 1,
2787          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2788
2789  // Right-click on the link and choose Save Link As. This will download the
2790  // link target.
2791  ContextMenuNotificationObserver context_menu_observer(
2792      IDC_CONTENT_CONTEXT_SAVELINKAS);
2793
2794  WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents();
2795  blink::WebMouseEvent mouse_event;
2796  mouse_event.type = blink::WebInputEvent::MouseDown;
2797  mouse_event.button = blink::WebMouseEvent::ButtonRight;
2798  mouse_event.x = 15;
2799  mouse_event.y = 15;
2800  mouse_event.clickCount = 1;
2801  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
2802  mouse_event.type = blink::WebInputEvent::MouseUp;
2803  tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event);
2804
2805  waiter->WaitForFinished();
2806  EXPECT_EQ(1u, waiter->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2807  CheckDownloadStates(1, DownloadItem::COMPLETE);
2808
2809  // Validate that the correct file was downloaded.
2810  GetDownloads(browser(), &download_items);
2811  EXPECT_EQ(1u, download_items.size());
2812  EXPECT_EQ(test_server()->GetURL("echoheader?Referer"),
2813            download_items[0]->GetOriginalUrl());
2814
2815  // Check that the file contains the expected referrer.
2816  base::FilePath file(download_items[0]->GetTargetFilePath());
2817  std::string expected_contents = ssl_test_server.GetURL(std::string()).spec();
2818  EXPECT_TRUE(VerifyFile(file, expected_contents, expected_contents.length()));
2819}
2820
2821// This test ensures that the Referer header is properly sanitized when
2822// Save Image As is chosen from the context menu. The test succeeds if
2823// it doesn't crash.
2824IN_PROC_BROWSER_TEST_F(DownloadTest, SaveImageAsReferrerPolicyDefault) {
2825  // Do initial setup.
2826  ASSERT_TRUE(test_server()->Start());
2827  net::SpawnedTestServer ssl_test_server(
2828      net::SpawnedTestServer::TYPE_HTTPS,
2829      net::SpawnedTestServer::kLocalhost,
2830      base::FilePath(FILE_PATH_LITERAL("chrome/test/data/")));
2831  ASSERT_TRUE(ssl_test_server.Start());
2832  EnableFileChooser(true);
2833  std::vector<DownloadItem*> download_items;
2834  GetDownloads(browser(), &download_items);
2835  ASSERT_TRUE(download_items.empty());
2836
2837  GURL url = ssl_test_server.GetURL("files/title1.html");
2838  GURL img_url = test_server()->GetURL("files/downloads/image.jpg");
2839  ASSERT_TRUE(url.is_valid());
2840  ui_test_utils::NavigateToURL(browser(), url);
2841
2842  // Try to download an image via a context menu.
2843  scoped_ptr<content::DownloadTestObserver> waiter_context_menu(
2844      new content::DownloadTestObserverTerminal(
2845          DownloadManagerForBrowser(browser()), 1,
2846          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2847  content::ContextMenuParams context_menu_params;
2848  context_menu_params.media_type = blink::WebContextMenuData::MediaTypeImage;
2849  context_menu_params.page_url = url;
2850  context_menu_params.src_url = img_url;
2851  TestRenderViewContextMenu menu(
2852      browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(),
2853      context_menu_params);
2854  menu.Init();
2855  menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0);
2856  waiter_context_menu->WaitForFinished();
2857  EXPECT_EQ(
2858      1u, waiter_context_menu->NumDownloadsSeenInState(DownloadItem::COMPLETE));
2859  CheckDownloadStates(1, DownloadItem::COMPLETE);
2860
2861  // Validate that the correct file was downloaded via the context menu.
2862  download_items.clear();
2863  GetDownloads(browser(), &download_items);
2864  EXPECT_TRUE(DidShowFileChooser());
2865  ASSERT_EQ(1u, download_items.size());
2866  ASSERT_EQ(img_url, download_items[0]->GetOriginalUrl());
2867}
2868
2869IN_PROC_BROWSER_TEST_F(DownloadTest, HiddenDownload) {
2870  base::FilePath file(FILE_PATH_LITERAL("download-test1.lib"));
2871  GURL url(URLRequestMockHTTPJob::GetMockUrl(file));
2872
2873  DownloadManager* download_manager = DownloadManagerForBrowser(browser());
2874  scoped_ptr<content::DownloadTestObserver> observer(
2875      new content::DownloadTestObserverTerminal(
2876          download_manager,
2877          1,
2878          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL));
2879
2880  // Download and set IsHiddenDownload to true.
2881  WebContents* web_contents =
2882      browser()->tab_strip_model()->GetActiveWebContents();
2883  scoped_ptr<DownloadUrlParameters> params(
2884      DownloadUrlParameters::FromWebContents(web_contents, url));
2885  params->set_callback(base::Bind(&SetHiddenDownloadCallback));
2886  download_manager->DownloadUrl(params.Pass());
2887  observer->WaitForFinished();
2888
2889  // Verify that download shelf is not shown.
2890  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
2891}
2892
2893// Verify the multiple downloads infobar.
2894IN_PROC_BROWSER_TEST_F(DownloadTest, TestMultipleDownloadsInfobar) {
2895#if defined(OS_WIN) && defined(USE_ASH)
2896  // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2897  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
2898    return;
2899#endif
2900
2901  ASSERT_TRUE(test_server()->Start());
2902
2903  // Create a downloads observer.
2904  scoped_ptr<content::DownloadTestObserver> downloads_observer(
2905        CreateWaiter(browser(), 2));
2906
2907  // Create an infobar observer.
2908  content::WindowedNotificationObserver infobar_added_1(
2909        chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
2910        content::NotificationService::AllSources());
2911  ui_test_utils::NavigateToURL(
2912     browser(),
2913     test_server()->GetURL("files/downloads/download-a_zip_file.html"));
2914  infobar_added_1.Wait();
2915
2916  InfoBarService* infobar_service = InfoBarService::FromWebContents(
2917       browser()->tab_strip_model()->GetActiveWebContents());
2918  // Verify that there is only one infobar.
2919  ASSERT_EQ(1u, infobar_service->infobar_count());
2920
2921  // Get the infobar at index 0.
2922  infobars::InfoBar* infobar = infobar_service->infobar_at(0);
2923  ConfirmInfoBarDelegate* confirm_infobar =
2924      infobar->delegate()->AsConfirmInfoBarDelegate();
2925  ASSERT_TRUE(confirm_infobar != NULL);
2926
2927  // Verify multi download warning infobar message.
2928  EXPECT_EQ(confirm_infobar->GetMessageText(),
2929            l10n_util::GetStringUTF16(IDS_MULTI_DOWNLOAD_WARNING));
2930
2931  // Click on the "Allow" button to allow multiple downloads.
2932  if (confirm_infobar->Accept())
2933    infobar_service->RemoveInfoBar(infobar);
2934  // Verify that there are no more infobars.
2935  EXPECT_EQ(0u, infobar_service->infobar_count());
2936
2937  // Waits for the download to complete.
2938  downloads_observer->WaitForFinished();
2939  EXPECT_EQ(2u, downloads_observer->NumDownloadsSeenInState(
2940      DownloadItem::COMPLETE));
2941}
2942
2943IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_Renaming) {
2944  ASSERT_TRUE(test_server()->Start());
2945  GURL url(test_server()->GetURL("files/downloads/a_zip_file.zip"));
2946  content::DownloadManager* manager = DownloadManagerForBrowser(browser());
2947  base::FilePath origin_file(OriginFile(base::FilePath(FILE_PATH_LITERAL(
2948      "downloads/a_zip_file.zip"))));
2949  ASSERT_TRUE(base::PathExists(origin_file));
2950  std::string origin_contents;
2951  ASSERT_TRUE(base::ReadFileToString(origin_file, &origin_contents));
2952
2953  // Download the same url several times and expect that all downloaded files
2954  // after the zero-th contain a deduplication counter.
2955  for (int index = 0; index < 5; ++index) {
2956    DownloadAndWait(browser(), url);
2957    EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
2958    content::DownloadItem* item = manager->GetDownload(
2959        content::DownloadItem::kInvalidId + 1 + index);
2960    ASSERT_TRUE(item);
2961    ASSERT_EQ(DownloadItem::COMPLETE, item->GetState());
2962    base::FilePath target_path(item->GetTargetFilePath());
2963    EXPECT_EQ(std::string("a_zip_file") +
2964        (index == 0 ? std::string(".zip") :
2965                      base::StringPrintf(" (%d).zip", index)),
2966              target_path.BaseName().AsUTF8Unsafe());
2967    ASSERT_TRUE(base::PathExists(target_path));
2968    ASSERT_TRUE(VerifyFile(target_path, origin_contents,
2969                           origin_contents.size()));
2970  }
2971}
2972
2973// Test that the entire download pipeline handles unicode correctly.
2974IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_CrazyFilenames) {
2975  const wchar_t* kCrazyFilenames[] = {
2976    L"a_file_name.zip",
2977    L"\u89c6\u9891\u76f4\u64ad\u56fe\u7247.zip",  // chinese chars
2978    L"\u0412\u043e \u0424\u043b\u043e\u0440\u0438\u0434\u0435\u043e\u0431\u044a"
2979      L"\u044f\u0432\u043b\u0435\u043d\u0440\u0435\u0436\u0438\u043c \u0427"
2980      L"\u041f \u0438\u0437-\u0437\u0430 \u0443\u0442\u0435\u0447\u043a\u0438 "
2981      L"\u043d\u0435\u0444\u0442\u0438.zip",  // russian
2982    L"Desocupa\xe7\xe3o est\xe1vel.zip",
2983    // arabic:
2984    L"\u0638\u2026\u0638\u02c6\u0637\xa7\u0638\u201a\u0637\xb9 \u0638\u201e"
2985      L"\u0638\u201e\u0637\xb2\u0638\u0679\u0637\xa7\u0637\xb1\u0637\xa9.zip",
2986    L"\u05d4\u05e2\u05d3\u05e4\u05d5\u05ea.zip",  // hebrew
2987    L"\u092d\u093e\u0930\u0924.zip",  // hindi
2988    L"d\xe9stabilis\xe9.zip",  // french
2989    // korean
2990    L"\u97d3-\u4e2d \uc815\uc0c1, \ucc9c\uc548\ud568 \uc758\uacac.zip",
2991    L"jiho....tiho...miho.zip",
2992    L"jiho!@#$tiho$%^&-()_+=miho copy.zip",  // special chars
2993    L"Wohoo-to hoo+I.zip",
2994    L"Picture 1.zip",
2995    L"This is a very very long english sentence with spaces and , and +.zip",
2996  };
2997
2998  std::vector<DownloadItem*> download_items;
2999  base::FilePath origin(FILE_PATH_LITERAL("origin"));
3000  ASSERT_TRUE(base::CreateDirectory(DestinationFile(browser(), origin)));
3001
3002  for (size_t index = 0; index < arraysize(kCrazyFilenames); ++index) {
3003    base::string16 crazy16;
3004    std::string crazy8;
3005    const wchar_t* crazy_w = kCrazyFilenames[index];
3006    ASSERT_TRUE(base::WideToUTF8(crazy_w, wcslen(crazy_w), &crazy8));
3007    ASSERT_TRUE(base::WideToUTF16(crazy_w, wcslen(crazy_w), &crazy16));
3008    base::FilePath file_path(DestinationFile(browser(), origin.Append(
3009#if defined(OS_WIN)
3010            crazy16
3011#elif defined(OS_POSIX)
3012            crazy8
3013#endif
3014        )));
3015
3016    // Create the file.
3017    EXPECT_EQ(static_cast<int>(crazy8.size()),
3018              base::WriteFile(file_path, crazy8.c_str(), crazy8.size()));
3019    GURL file_url(net::FilePathToFileURL(file_path));
3020
3021    // Download the file and check that the filename is correct.
3022    DownloadAndWait(browser(), file_url);
3023    EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
3024    GetDownloads(browser(), &download_items);
3025    ASSERT_EQ(1UL, download_items.size());
3026    base::FilePath downloaded(download_items[0]->GetTargetFilePath());
3027    download_items[0]->Remove();
3028    download_items.clear();
3029    ASSERT_TRUE(CheckDownloadFullPaths(
3030        browser(),
3031        downloaded,
3032        file_path));
3033  }
3034}
3035
3036IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_Remove) {
3037  ASSERT_TRUE(test_server()->Start());
3038  GURL url(test_server()->GetURL("files/downloads/a_zip_file.zip"));
3039  std::vector<DownloadItem*> download_items;
3040  GetDownloads(browser(), &download_items);
3041  ASSERT_TRUE(download_items.empty());
3042
3043  // Download a file.
3044  DownloadAndWaitWithDisposition(browser(),
3045                                 url,
3046                                 CURRENT_TAB,
3047                                 ui_test_utils::BROWSER_TEST_NONE);
3048  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
3049  GetDownloads(browser(), &download_items);
3050  ASSERT_EQ(1UL, download_items.size());
3051  base::FilePath downloaded(download_items[0]->GetTargetFilePath());
3052
3053  // Remove the DownloadItem but not the file, then check that the file still
3054  // exists.
3055  download_items[0]->Remove();
3056  download_items.clear();
3057  GetDownloads(browser(), &download_items);
3058  ASSERT_EQ(0UL, download_items.size());
3059  ASSERT_TRUE(CheckDownloadFullPaths(
3060      browser(), downloaded, OriginFile(base::FilePath(
3061          FILE_PATH_LITERAL("downloads/a_zip_file.zip")))));
3062
3063}
3064
3065IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_PauseResumeCancel) {
3066  DownloadItem* download_item = CreateSlowTestDownload();
3067  ASSERT_TRUE(download_item);
3068  ASSERT_FALSE(download_item->GetTargetFilePath().empty());
3069  EXPECT_FALSE(download_item->IsPaused());
3070  EXPECT_NE(DownloadItem::CANCELLED, download_item->GetState());
3071  download_item->Pause();
3072  EXPECT_TRUE(download_item->IsPaused());
3073  download_item->Resume();
3074  EXPECT_FALSE(download_item->IsPaused());
3075  EXPECT_NE(DownloadItem::CANCELLED, download_item->GetState());
3076  download_item->Cancel(true);
3077  EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());
3078}
3079
3080// The Mac downloaded files quarantine feature is implemented by the
3081// Contents/Info.plist file in cocoa apps. browser_tests cannot test
3082// quarantining files on Mac because it is not a cocoa app.
3083// TODO(benjhayden) test the equivalents on other platforms.
3084
3085#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
3086// Timing out on ARM linux: http://crbug.com/238459
3087#define MAYBE_DownloadTest_PercentComplete DISABLED_DownloadTest_PercentComplete
3088#elif defined(OS_MACOSX)
3089// Disable on mac: http://crbug.com/238831
3090#define MAYBE_DownloadTest_PercentComplete DISABLED_DownloadTest_PercentComplete
3091#else
3092#define MAYBE_DownloadTest_PercentComplete DownloadTest_PercentComplete
3093#endif
3094IN_PROC_BROWSER_TEST_F(DownloadTest, MAYBE_DownloadTest_PercentComplete) {
3095  // Write a huge file.
3096  base::FilePath file_path(DestinationFile(
3097      browser(), base::FilePath(FILE_PATH_LITERAL("DownloadTest_BigZip.zip"))));
3098  base::File file(file_path, base::File::FLAG_CREATE | base::File::FLAG_WRITE);
3099  ASSERT_TRUE(file.IsValid());
3100  int64 size = 1 << 25;
3101  EXPECT_EQ(1, file.Write(size, "a", 1));
3102  file.Close();
3103
3104#if defined(OS_POSIX)
3105  // Make it readable by chronos on chromeos
3106  base::SetPosixFilePermissions(file_path, 0755);
3107#endif
3108
3109  // Ensure that we have enough disk space.
3110  int64 free_space = base::SysInfo::AmountOfFreeDiskSpace(
3111      GetDownloadDirectory(browser()));
3112  ASSERT_LE(size, free_space) << "Not enough disk space to download. Got "
3113                              << free_space;
3114  GURL file_url(net::FilePathToFileURL(file_path));
3115  scoped_ptr<content::DownloadTestObserver> progress_waiter(
3116      CreateInProgressWaiter(browser(), 1));
3117
3118  // Start downloading a file, wait for it to be created.
3119  ui_test_utils::NavigateToURLWithDisposition(
3120      browser(), file_url, CURRENT_TAB, ui_test_utils::BROWSER_TEST_NONE);
3121  progress_waiter->WaitForFinished();
3122  EXPECT_EQ(1u, progress_waiter->NumDownloadsSeenInState(
3123      DownloadItem::IN_PROGRESS));
3124  std::vector<DownloadItem*> download_items;
3125  GetDownloads(browser(), &download_items);
3126  ASSERT_EQ(1UL, download_items.size());
3127
3128  // Wait for the download to complete, checking along the way that the
3129  // PercentComplete() never regresses.
3130  PercentWaiter waiter(download_items[0]);
3131  EXPECT_TRUE(waiter.WaitForFinished());
3132  EXPECT_EQ(DownloadItem::COMPLETE, download_items[0]->GetState());
3133  ASSERT_EQ(100, download_items[0]->PercentComplete());
3134  EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
3135
3136  // Check that the file downloaded correctly.
3137  ASSERT_TRUE(base::PathExists(download_items[0]->GetTargetFilePath()));
3138  int64 downloaded_size = 0;
3139  ASSERT_TRUE(base::GetFileSize(
3140      download_items[0]->GetTargetFilePath(), &downloaded_size));
3141  ASSERT_EQ(size + 1, downloaded_size);
3142  ASSERT_TRUE(base::DieFileDie(file_path, false));
3143  ASSERT_TRUE(base::DieFileDie(download_items[0]->GetTargetFilePath(), false));
3144}
3145
3146IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_DenyDanger) {
3147  ASSERT_TRUE(test_server()->Start());
3148  GURL url(test_server()->GetURL("files/downloads/dangerous/dangerous.crx"));
3149  scoped_ptr<content::DownloadTestObserver> observer(
3150      DangerousDownloadWaiter(
3151          browser(), 1,
3152          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_DENY));
3153  ui_test_utils::NavigateToURL(browser(), url);
3154  observer->WaitForFinished();
3155  EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::CANCELLED));
3156  EXPECT_EQ(1u, observer->NumDangerousDownloadsSeen());
3157  EXPECT_FALSE(browser()->window()->IsDownloadShelfVisible());
3158}
3159
3160IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadPrefs_SaveFilePath) {
3161  DownloadPrefs* on_prefs = DownloadServiceFactory::GetForBrowserContext(
3162      browser()->profile())->GetDownloadManagerDelegate()->download_prefs();
3163  DownloadPrefs* off_prefs = DownloadServiceFactory::GetForBrowserContext(
3164      browser()->profile()->GetOffTheRecordProfile())
3165    ->GetDownloadManagerDelegate()->download_prefs();
3166  base::FilePath dir(on_prefs->SaveFilePath());
3167  EXPECT_EQ(dir.value(), off_prefs->SaveFilePath().value());
3168
3169  on_prefs->SetSaveFilePath(dir.AppendASCII("on"));
3170  EXPECT_EQ(dir.AppendASCII("on").value(), on_prefs->SaveFilePath().value());
3171  EXPECT_EQ(dir.AppendASCII("on").value(), off_prefs->SaveFilePath().value());
3172
3173  on_prefs->SetSaveFilePath(dir);
3174  EXPECT_EQ(dir.value(), on_prefs->SaveFilePath().value());
3175  EXPECT_EQ(dir.value(), off_prefs->SaveFilePath().value());
3176
3177  off_prefs->SetSaveFilePath(dir.AppendASCII("off"));
3178  EXPECT_EQ(dir.value(), on_prefs->SaveFilePath().value());
3179  EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value());
3180
3181  on_prefs->SetSaveFilePath(dir.AppendASCII("on"));
3182  EXPECT_EQ(dir.AppendASCII("on").value(), on_prefs->SaveFilePath().value());
3183  EXPECT_EQ(dir.AppendASCII("off").value(), off_prefs->SaveFilePath().value());
3184}
3185
3186// A download that is interrupted due to a file error should be able to be
3187// resumed.
3188IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_NoPrompt) {
3189  CommandLine::ForCurrentProcess()->AppendSwitch(
3190      switches::kEnableDownloadResumption);
3191  scoped_refptr<content::TestFileErrorInjector> error_injector(
3192      content::TestFileErrorInjector::Create(
3193          DownloadManagerForBrowser(browser())));
3194  scoped_ptr<content::DownloadTestObserver> completion_observer(
3195      CreateWaiter(browser(), 1));
3196  EnableFileChooser(true);
3197
3198  DownloadItem* download = StartMockDownloadAndInjectError(
3199      error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
3200  ASSERT_TRUE(download);
3201
3202  download->Resume();
3203  completion_observer->WaitForFinished();
3204
3205  EXPECT_EQ(
3206      1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
3207  EXPECT_FALSE(DidShowFileChooser());
3208}
3209
3210// A download that's interrupted due to a reason that indicates that the target
3211// path is invalid or unusable should cause a prompt to be displayed on
3212// resumption.
3213IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPrompt) {
3214  CommandLine::ForCurrentProcess()->AppendSwitch(
3215      switches::kEnableDownloadResumption);
3216  scoped_refptr<content::TestFileErrorInjector> error_injector(
3217      content::TestFileErrorInjector::Create(
3218          DownloadManagerForBrowser(browser())));
3219  scoped_ptr<content::DownloadTestObserver> completion_observer(
3220      CreateWaiter(browser(), 1));
3221  EnableFileChooser(true);
3222
3223  DownloadItem* download = StartMockDownloadAndInjectError(
3224      error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_NO_SPACE);
3225  ASSERT_TRUE(download);
3226
3227  download->Resume();
3228  completion_observer->WaitForFinished();
3229
3230  EXPECT_EQ(
3231      1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
3232  EXPECT_TRUE(DidShowFileChooser());
3233}
3234
3235// The user shouldn't be prompted on a resumed download unless a prompt is
3236// necessary due to the interrupt reason.
3237IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_WithPromptAlways) {
3238  CommandLine::ForCurrentProcess()->AppendSwitch(
3239      switches::kEnableDownloadResumption);
3240  browser()->profile()->GetPrefs()->SetBoolean(
3241      prefs::kPromptForDownload, true);
3242  scoped_refptr<content::TestFileErrorInjector> error_injector(
3243      content::TestFileErrorInjector::Create(
3244          DownloadManagerForBrowser(browser())));
3245  scoped_ptr<content::DownloadTestObserver> completion_observer(
3246      CreateWaiter(browser(), 1));
3247  EnableFileChooser(true);
3248
3249  DownloadItem* download = StartMockDownloadAndInjectError(
3250      error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
3251  ASSERT_TRUE(download);
3252
3253  // Prompts the user initially because of the kPromptForDownload preference.
3254  EXPECT_TRUE(DidShowFileChooser());
3255
3256  download->Resume();
3257  completion_observer->WaitForFinished();
3258
3259  EXPECT_EQ(
3260      1u, completion_observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
3261  // Shouldn't prompt for resumption.
3262  EXPECT_FALSE(DidShowFileChooser());
3263}
3264
3265// A download that is interrupted due to a transient error should be resumed
3266// automatically.
3267IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_Automatic) {
3268  CommandLine::ForCurrentProcess()->AppendSwitch(
3269      switches::kEnableDownloadResumption);
3270  scoped_refptr<content::TestFileErrorInjector> error_injector(
3271      content::TestFileErrorInjector::Create(
3272          DownloadManagerForBrowser(browser())));
3273
3274  DownloadItem* download = StartMockDownloadAndInjectError(
3275      error_injector.get(),
3276      content::DOWNLOAD_INTERRUPT_REASON_FILE_TRANSIENT_ERROR);
3277  ASSERT_TRUE(download);
3278
3279  // The number of times this the download is resumed automatically is defined
3280  // in DownloadItemImpl::kMaxAutoResumeAttempts. The number of DownloadFiles
3281  // created should be that number + 1 (for the original download request). We
3282  // only care that it is greater than 1.
3283  EXPECT_GT(1u, error_injector->TotalFileCount());
3284}
3285
3286// An interrupting download should be resumable multiple times.
3287IN_PROC_BROWSER_TEST_F(DownloadTest, Resumption_MultipleAttempts) {
3288  CommandLine::ForCurrentProcess()->AppendSwitch(
3289      switches::kEnableDownloadResumption);
3290  scoped_refptr<content::TestFileErrorInjector> error_injector(
3291      content::TestFileErrorInjector::Create(
3292          DownloadManagerForBrowser(browser())));
3293  scoped_ptr<DownloadTestObserverNotInProgress> completion_observer(
3294      new DownloadTestObserverNotInProgress(
3295          DownloadManagerForBrowser(browser()), 1));
3296  // Wait for two transitions to a resumable state
3297  scoped_ptr<content::DownloadTestObserver> resumable_observer(
3298      new DownloadTestObserverResumable(
3299          DownloadManagerForBrowser(browser()), 2));
3300
3301  EnableFileChooser(true);
3302  DownloadItem* download = StartMockDownloadAndInjectError(
3303      error_injector.get(), content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED);
3304  ASSERT_TRUE(download);
3305
3306  content::TestFileErrorInjector::FileErrorInfo error_info;
3307  error_info.url = download->GetOriginalUrl().spec();
3308  error_info.code = content::TestFileErrorInjector::FILE_OPERATION_WRITE;
3309  error_info.operation_instance = 0;
3310  error_info.error = content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED;
3311  error_injector->AddError(error_info);
3312  error_injector->InjectErrors();
3313
3314  // Resuming should cause the download to be interrupted again due to the
3315  // errors we are injecting.
3316  download->Resume();
3317  resumable_observer->WaitForFinished();
3318  ASSERT_EQ(DownloadItem::INTERRUPTED, download->GetState());
3319  ASSERT_EQ(content::DOWNLOAD_INTERRUPT_REASON_FILE_FAILED,
3320            download->GetLastReason());
3321
3322  error_injector->ClearErrors();
3323  error_injector->InjectErrors();
3324
3325  // No errors this time. The download should complete successfully.
3326  EXPECT_FALSE(completion_observer->IsFinished());
3327  completion_observer->StartObserving();
3328  download->Resume();
3329  completion_observer->WaitForFinished();
3330  EXPECT_EQ(DownloadItem::COMPLETE, download->GetState());
3331
3332  EXPECT_FALSE(DidShowFileChooser());
3333}
3334
3335// The file empty.bin is served with a MIME type of application/octet-stream.
3336// The content body is empty. Make sure this case is handled properly and we
3337// don't regress on http://crbug.com/320394.
3338IN_PROC_BROWSER_TEST_F(DownloadTest, DownloadTest_GZipWithNoContent) {
3339  ASSERT_TRUE(test_server()->Start());
3340  GURL url(test_server()->GetURL("files/downloads/empty.bin"));
3341  // Downloading the same URL twice causes the second request to be served from
3342  // cached (with a high probability). This test verifies that that doesn't
3343  // happen regardless of whether the request is served via the cache or from
3344  // the network.
3345  DownloadAndWait(browser(), url);
3346  DownloadAndWait(browser(), url);
3347}
3348
3349#if defined(FULL_SAFE_BROWSING)
3350
3351// The following two tests are only meaningful on OS_WIN since that's the only
3352// platform where client download checks are currently performed.
3353// TODO(asanka): Relax this restriction as other platforms are added.
3354#if defined(OS_WIN)
3355namespace {
3356
3357// This is a custom DownloadTestObserver for
3358// DangerousFileWithSBDisabledBeforeCompletion test that disables the
3359// SafeBrowsing service when a single download is IN_PROGRESS and has a target
3360// path assigned.  DownloadItemImpl is expected to call MaybeCompleteDownload
3361// soon afterwards and we want to disable the service before then.
3362class DisableSafeBrowsingOnInProgressDownload
3363    : public content::DownloadTestObserver {
3364 public:
3365  explicit DisableSafeBrowsingOnInProgressDownload(Browser* browser)
3366      : DownloadTestObserver(DownloadManagerForBrowser(browser),
3367                             1,
3368                             ON_DANGEROUS_DOWNLOAD_QUIT),
3369        browser_(browser),
3370        final_state_seen_(false) {
3371    Init();
3372  }
3373  virtual ~DisableSafeBrowsingOnInProgressDownload() {}
3374
3375  virtual bool IsDownloadInFinalState(DownloadItem* download) OVERRIDE {
3376    if (download->GetState() != DownloadItem::IN_PROGRESS ||
3377        download->GetTargetFilePath().empty())
3378      return false;
3379
3380    if (final_state_seen_)
3381      return true;
3382
3383    final_state_seen_ = true;
3384    browser_->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled,
3385                                                false);
3386    EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
3387              download->GetDangerType());
3388    EXPECT_FALSE(download->IsDangerous());
3389    EXPECT_TRUE(DownloadItemModel(download).IsDangerousFileBasedOnType());
3390    return true;
3391  }
3392
3393 private:
3394  Browser* browser_;
3395  bool final_state_seen_;
3396};
3397
3398}  // namespace
3399
3400IN_PROC_BROWSER_TEST_F(DownloadTest,
3401                       DangerousFileWithSBDisabledBeforeCompletion) {
3402  browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled,
3403                                               true);
3404  ASSERT_TRUE(test_server()->Start());
3405  GURL download_url(
3406      test_server()->GetURL("files/downloads/dangerous/dangerous.exe"));
3407  scoped_ptr<content::DownloadTestObserver> dangerous_observer(
3408      DangerousDownloadWaiter(
3409          browser(),
3410          1,
3411          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_QUIT));
3412  scoped_ptr<content::DownloadTestObserver> in_progress_observer(
3413      new DisableSafeBrowsingOnInProgressDownload(browser()));
3414  ui_test_utils::NavigateToURLWithDisposition(browser(),
3415                                              download_url,
3416                                              NEW_BACKGROUND_TAB,
3417                                              ui_test_utils::BROWSER_TEST_NONE);
3418  in_progress_observer->WaitForFinished();
3419
3420  // SafeBrowsing should have been disabled by our observer.
3421  ASSERT_FALSE(browser()->profile()->GetPrefs()->GetBoolean(
3422      prefs::kSafeBrowsingEnabled));
3423
3424  std::vector<DownloadItem*> downloads;
3425  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
3426  ASSERT_EQ(1u, downloads.size());
3427  DownloadItem* download = downloads[0];
3428
3429  dangerous_observer->WaitForFinished();
3430
3431  EXPECT_TRUE(download->IsDangerous());
3432  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
3433            download->GetDangerType());
3434  download->Cancel(true);
3435}
3436
3437IN_PROC_BROWSER_TEST_F(DownloadTest, DangerousFileWithSBDisabledBeforeStart) {
3438  // Disable SafeBrowsing
3439  browser()->profile()->GetPrefs()->SetBoolean(prefs::kSafeBrowsingEnabled,
3440                                               false);
3441
3442  ASSERT_TRUE(test_server()->Start());
3443  GURL download_url(
3444      test_server()->GetURL("files/downloads/dangerous/dangerous.exe"));
3445  scoped_ptr<content::DownloadTestObserver> dangerous_observer(
3446      DangerousDownloadWaiter(
3447          browser(),
3448          1,
3449          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_QUIT));
3450  ui_test_utils::NavigateToURLWithDisposition(browser(),
3451                                              download_url,
3452                                              NEW_BACKGROUND_TAB,
3453                                              ui_test_utils::BROWSER_TEST_NONE);
3454  dangerous_observer->WaitForFinished();
3455
3456  std::vector<DownloadItem*> downloads;
3457  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
3458  ASSERT_EQ(1u, downloads.size());
3459
3460  DownloadItem* download = downloads[0];
3461  EXPECT_TRUE(download->IsDangerous());
3462  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
3463            download->GetDangerType());
3464
3465  download->Cancel(true);
3466}
3467
3468IN_PROC_BROWSER_TEST_F(DownloadTest, SafeSupportedFile) {
3469  ASSERT_TRUE(test_server()->Start());
3470  GURL download_url(test_server()->GetURL("files/downloads/a_zip_file.zip"));
3471  DownloadAndWait(browser(), download_url);
3472
3473  std::vector<DownloadItem*> downloads;
3474  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
3475  ASSERT_EQ(1u, downloads.size());
3476
3477  DownloadItem* download = downloads[0];
3478  EXPECT_FALSE(download->IsDangerous());
3479  EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT,
3480            download->GetDangerType());
3481
3482  download->Cancel(true);
3483}
3484
3485#endif // OS_WIN
3486
3487IN_PROC_BROWSER_TEST_F(DownloadTest, FeedbackService) {
3488  // Make a dangerous file.
3489  base::FilePath file(FILE_PATH_LITERAL("downloads/dangerous/dangerous.swf"));
3490  GURL download_url(net::URLRequestMockHTTPJob::GetMockUrl(file));
3491  scoped_ptr<content::DownloadTestObserverInterrupted> observer(
3492      new content::DownloadTestObserverInterrupted(
3493          DownloadManagerForBrowser(browser()), 1,
3494          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_QUIT));
3495  ui_test_utils::NavigateToURLWithDisposition(
3496      browser(),
3497      GURL(download_url),
3498      NEW_BACKGROUND_TAB,
3499      ui_test_utils::BROWSER_TEST_NONE);
3500  observer->WaitForFinished();
3501
3502  // Get the download from the DownloadManager.
3503  std::vector<DownloadItem*> downloads;
3504  DownloadManagerForBrowser(browser())->GetAllDownloads(&downloads);
3505  ASSERT_EQ(1u, downloads.size());
3506  EXPECT_TRUE(downloads[0]->IsDangerous());
3507
3508  // Save fake pings for the download.
3509  safe_browsing::ClientDownloadReport fake_metadata;
3510  fake_metadata.mutable_download_request()->set_url("http://test");
3511  fake_metadata.mutable_download_request()->set_length(1);
3512  fake_metadata.mutable_download_request()->mutable_digests()->set_sha1("hi");
3513  fake_metadata.mutable_download_response()->set_verdict(
3514      safe_browsing::ClientDownloadResponse::UNCOMMON);
3515  std::string ping_request(
3516      fake_metadata.download_request().SerializeAsString());
3517  std::string ping_response(
3518      fake_metadata.download_response().SerializeAsString());
3519  SafeBrowsingService* sb_service = g_browser_process->safe_browsing_service();
3520  safe_browsing::DownloadProtectionService* download_protection_service =
3521      sb_service->download_protection_service();
3522  download_protection_service->feedback_service()->MaybeStorePingsForDownload(
3523      safe_browsing::DownloadProtectionService::UNCOMMON,
3524      downloads[0],
3525      ping_request,
3526      ping_response);
3527  ASSERT_TRUE(safe_browsing::DownloadFeedbackService::IsEnabledForDownload(
3528      *(downloads[0])));
3529
3530  // Begin feedback and check that the file is "stolen".
3531  download_protection_service->feedback_service()->BeginFeedbackForDownload(
3532      downloads[0]);
3533  std::vector<DownloadItem*> updated_downloads;
3534  GetDownloads(browser(), &updated_downloads);
3535  ASSERT_TRUE(updated_downloads.empty());
3536}
3537#endif
3538