// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <algorithm>

#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/json/json_reader.h"
#include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/download/download_file_icon_extractor.h"
#include "chrome/browser/download/download_service.h"
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/download/download_test_file_activity_observer.h"
#include "chrome/browser/extensions/api/downloads/downloads_api.h"
#include "chrome/browser/extensions/event_names.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/extensions/extension_function_test_utils.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/history/download_row.h"
#include "chrome/browser/net/url_request_mock_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/page_transition_types.h"
#include "content/public/test/download_test_observer.h"
#include "content/test/net/url_request_slow_download_job.h"
#include "net/base/data_url.h"
#include "net/base/net_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_operation_runner.h"
#include "webkit/browser/fileapi/file_system_url.h"

using content::BrowserContext;
using content::BrowserThread;
using content::DownloadItem;
using content::DownloadManager;
using content::URLRequestSlowDownloadJob;

namespace events = extensions::event_names;

namespace errors = download_extension_errors;

namespace api = extensions::api::downloads;

namespace {

// Comparator that orders download items by their ID. Can be used with
// std::sort.
struct DownloadIdComparator {
  bool operator() (DownloadItem* first, DownloadItem* second) {
    return first->GetId() < second->GetId();
  }
};

class DownloadsEventsListener : public content::NotificationObserver {
 public:
  DownloadsEventsListener()
    : waiting_(false) {
    registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
                   content::NotificationService::AllSources());
  }

  virtual ~DownloadsEventsListener() {
    registrar_.Remove(this, chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT,
                      content::NotificationService::AllSources());
    STLDeleteElements(&events_);
  }

  void ClearEvents() {
    STLDeleteElements(&events_);
    events_.clear();
  }

  class Event {
   public:
    Event(Profile* profile,
          const std::string& event_name,
          const std::string& json_args,
          base::Time caught)
      : profile_(profile),
        event_name_(event_name),
        json_args_(json_args),
        args_(base::JSONReader::Read(json_args)),
        caught_(caught) {
    }

    const base::Time& caught() { return caught_; }

    bool Satisfies(const Event& other) const {
      return other.SatisfiedBy(*this);
    }

    bool SatisfiedBy(const Event& other) const {
      if ((profile_ != other.profile_) ||
          (event_name_ != other.event_name_))
        return false;
      if (((event_name_ == events::kOnDownloadDeterminingFilename) ||
           (event_name_ == events::kOnDownloadCreated) ||
           (event_name_ == events::kOnDownloadChanged)) &&
          args_.get() &&
          other.args_.get()) {
        base::ListValue* left_list = NULL;
        base::DictionaryValue* left_dict = NULL;
        base::ListValue* right_list = NULL;
        base::DictionaryValue* right_dict = NULL;
        if (!args_->GetAsList(&left_list) ||
            !other.args_->GetAsList(&right_list) ||
            !left_list->GetDictionary(0, &left_dict) ||
            !right_list->GetDictionary(0, &right_dict))
          return false;
        for (base::DictionaryValue::Iterator iter(*left_dict);
             !iter.IsAtEnd(); iter.Advance()) {
          base::Value* right_value = NULL;
          if (!right_dict->HasKey(iter.key()) ||
              (right_dict->Get(iter.key(), &right_value) &&
               !iter.value().Equals(right_value))) {
            return false;
          }
        }
        return true;
      } else if ((event_name_ == events::kOnDownloadErased) &&
                 args_.get() &&
                 other.args_.get()) {
        int my_id = -1, other_id = -1;
        return (args_->GetAsInteger(&my_id) &&
                other.args_->GetAsInteger(&other_id) &&
                my_id == other_id);
      }
      return json_args_ == other.json_args_;
    }

    std::string Debug() {
      return base::StringPrintf("Event(%p, %s, %s, %f)",
                                profile_,
                                event_name_.c_str(),
                                json_args_.c_str(),
                                caught_.ToJsTime());
    }

   private:
    Profile* profile_;
    std::string event_name_;
    std::string json_args_;
    scoped_ptr<base::Value> args_;
    base::Time caught_;

    DISALLOW_COPY_AND_ASSIGN(Event);
  };

  typedef ExtensionDownloadsEventRouter::DownloadsNotificationSource
    DownloadsNotificationSource;

  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE {
    switch (type) {
      case chrome::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT:
        {
          DownloadsNotificationSource* dns =
              content::Source<DownloadsNotificationSource>(source).ptr();
          Event* new_event = new Event(
              dns->profile,
              dns->event_name,
              *content::Details<std::string>(details).ptr(), base::Time::Now());
          events_.push_back(new_event);
          if (waiting_ &&
              waiting_for_.get() &&
              new_event->Satisfies(*waiting_for_)) {
            waiting_ = false;
            base::MessageLoopForUI::current()->Quit();
          }
          break;
        }
      default:
        NOTREACHED();
    }
  }

  bool WaitFor(Profile* profile,
               const std::string& event_name,
               const std::string& json_args) {
    waiting_for_.reset(new Event(profile, event_name, json_args, base::Time()));
    for (std::deque<Event*>::const_iterator iter = events_.begin();
         iter != events_.end(); ++iter) {
      if ((*iter)->Satisfies(*waiting_for_.get())) {
        return true;
      }
    }
    waiting_ = true;
    content::RunMessageLoop();
    bool success = !waiting_;
    if (waiting_) {
      // Print the events that were caught since the last WaitFor() call to help
      // find the erroneous event.
      // TODO(benjhayden) Fuzzy-match and highlight the erroneous event.
      for (std::deque<Event*>::const_iterator iter = events_.begin();
          iter != events_.end(); ++iter) {
        if ((*iter)->caught() > last_wait_) {
          LOG(INFO) << "Caught " << (*iter)->Debug();
        }
      }
      if (waiting_for_.get()) {
        LOG(INFO) << "Timed out waiting for " << waiting_for_->Debug();
      }
      waiting_ = false;
    }
    waiting_for_.reset();
    last_wait_ = base::Time::Now();
    return success;
  }

 private:
  bool waiting_;
  base::Time last_wait_;
  scoped_ptr<Event> waiting_for_;
  content::NotificationRegistrar registrar_;
  std::deque<Event*> events_;

  DISALLOW_COPY_AND_ASSIGN(DownloadsEventsListener);
};

class DownloadExtensionTest : public ExtensionApiTest {
 public:
  DownloadExtensionTest()
    : extension_(NULL),
      incognito_browser_(NULL),
      current_browser_(NULL) {
  }

 protected:
  // Used with CreateHistoryDownloads
  struct HistoryDownloadInfo {
    // Filename to use. CreateHistoryDownloads will append this filename to the
    // temporary downloads directory specified by downloads_directory().
    const base::FilePath::CharType*   filename;

    // State for the download. Note that IN_PROGRESS downloads will be created
    // as CANCELLED.
    DownloadItem::DownloadState state;

    // Danger type for the download. Only use DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS
    // and DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT.
    content::DownloadDangerType danger_type;
  };

  void LoadExtension(const char* name) {
    // Store the created Extension object so that we can attach it to
    // ExtensionFunctions.  Also load the extension in incognito profiles for
    // testing incognito.
    extension_ = LoadExtensionIncognito(test_data_dir_.AppendASCII(name));
    CHECK(extension_);
    content::WebContents* tab = chrome::AddSelectedTabWithURL(
        current_browser(),
        extension_->GetResourceURL("empty.html"),
        content::PAGE_TRANSITION_LINK);
    extensions::ExtensionSystem::Get(current_browser()->profile())->
      event_router()->AddEventListener(
          extensions::event_names::kOnDownloadCreated,
          tab->GetRenderProcessHost(),
          GetExtensionId());
    extensions::ExtensionSystem::Get(current_browser()->profile())->
      event_router()->AddEventListener(
          extensions::event_names::kOnDownloadChanged,
          tab->GetRenderProcessHost(),
          GetExtensionId());
    extensions::ExtensionSystem::Get(current_browser()->profile())->
      event_router()->AddEventListener(
          extensions::event_names::kOnDownloadErased,
          tab->GetRenderProcessHost(),
          GetExtensionId());
  }

  content::RenderProcessHost* AddFilenameDeterminer() {
    content::WebContents* tab = chrome::AddSelectedTabWithURL(
        current_browser(),
        extension_->GetResourceURL("empty.html"),
        content::PAGE_TRANSITION_LINK);
    extensions::ExtensionSystem::Get(current_browser()->profile())->
      event_router()->AddEventListener(
          extensions::event_names::kOnDownloadDeterminingFilename,
          tab->GetRenderProcessHost(),
          GetExtensionId());
    return tab->GetRenderProcessHost();
  }

  void RemoveFilenameDeterminer(content::RenderProcessHost* host) {
    extensions::ExtensionSystem::Get(current_browser()->profile())->
      event_router()->RemoveEventListener(
          extensions::event_names::kOnDownloadDeterminingFilename,
          host,
          GetExtensionId());
  }

  Browser* current_browser() { return current_browser_; }

  // InProcessBrowserTest
  virtual void SetUpOnMainThread() OVERRIDE {
    ExtensionApiTest::SetUpOnMainThread();
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
    InProcessBrowserTest::SetUpOnMainThread();
    GoOnTheRecord();
    CreateAndSetDownloadsDirectory();
    current_browser()->profile()->GetPrefs()->SetBoolean(
        prefs::kPromptForDownload, false);
    GetOnRecordManager()->RemoveAllDownloads();
    events_listener_.reset(new DownloadsEventsListener());
    // Disable file chooser for current profile.
    DownloadTestFileActivityObserver observer(current_browser()->profile());
    observer.EnableFileChooser(false);
  }

  void GoOnTheRecord() { current_browser_ = browser(); }

  void GoOffTheRecord() {
    if (!incognito_browser_) {
      incognito_browser_ = CreateIncognitoBrowser();
      GetOffRecordManager()->RemoveAllDownloads();
      // Disable file chooser for incognito profile.
      DownloadTestFileActivityObserver observer(incognito_browser_->profile());
      observer.EnableFileChooser(false);
    }
    current_browser_ = incognito_browser_;
  }

  bool WaitFor(const std::string& event_name, const std::string& json_args) {
    return events_listener_->WaitFor(
        current_browser()->profile(), event_name, json_args);
  }

  bool WaitForInterruption(
      DownloadItem* item,
      content::DownloadInterruptReason expected_error,
      const std::string& on_created_event) {
    if (!WaitFor(events::kOnDownloadCreated, on_created_event))
      return false;
    // Now, onCreated is always fired before interruption.
    return WaitFor(events::kOnDownloadChanged,
        base::StringPrintf("[{\"id\": %d,"
                           "  \"error\": {\"current\": \"%s\"},"
                           "  \"state\": {"
                           "    \"previous\": \"in_progress\","
                           "    \"current\": \"interrupted\"}}]",
                           item->GetId(),
                           content::InterruptReasonDebugString(
                             expected_error).c_str()));
  }

  void ClearEvents() {
    events_listener_->ClearEvents();
  }

  std::string GetExtensionURL() {
    return extension_->url().spec();
  }
  std::string GetExtensionId() {
    return extension_->id();
  }

  std::string GetFilename(const char* path) {
    std::string result =
      downloads_directory_.path().AppendASCII(path).AsUTF8Unsafe();
#if defined(OS_WIN)
    for (std::string::size_type next = result.find("\\");
         next != std::string::npos;
         next = result.find("\\", next)) {
      result.replace(next, 1, "\\\\");
      next += 2;
    }
#endif
    return result;
  }

  DownloadManager* GetOnRecordManager() {
    return BrowserContext::GetDownloadManager(browser()->profile());
  }
  DownloadManager* GetOffRecordManager() {
    return BrowserContext::GetDownloadManager(
        browser()->profile()->GetOffTheRecordProfile());
  }
  DownloadManager* GetCurrentManager() {
    return (current_browser_ == incognito_browser_) ?
      GetOffRecordManager() : GetOnRecordManager();
  }

  // Creates a set of history downloads based on the provided |history_info|
  // array. |count| is the number of elements in |history_info|. On success,
  // |items| will contain |count| DownloadItems in the order that they were
  // specified in |history_info|. Returns true on success and false otherwise.
  bool CreateHistoryDownloads(const HistoryDownloadInfo* history_info,
                              size_t count,
                              DownloadManager::DownloadVector* items) {
    DownloadIdComparator download_id_comparator;
    base::Time current = base::Time::Now();
    items->clear();
    GetOnRecordManager()->GetAllDownloads(items);
    CHECK_EQ(0, static_cast<int>(items->size()));
    std::vector<GURL> url_chain;
    url_chain.push_back(GURL());
    for (size_t i = 0; i < count; ++i) {
      DownloadItem* item = GetOnRecordManager()->CreateDownloadItem(
          content::DownloadItem::kInvalidId + 1 + i,
          downloads_directory().Append(history_info[i].filename),
          downloads_directory().Append(history_info[i].filename),
          url_chain, GURL(),    // URL Chain, referrer
          current, current,  // start_time, end_time
          std::string(), std::string(), // etag, last_modified
          1, 1,              // received_bytes, total_bytes
          history_info[i].state,  // state
          content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
          content::DOWNLOAD_INTERRUPT_REASON_NONE,
          false);                 // opened
      items->push_back(item);
    }

    // Order by ID so that they are in the order that we created them.
    std::sort(items->begin(), items->end(), download_id_comparator);
    // Set the danger type if necessary.
    for (size_t i = 0; i < count; ++i) {
      if (history_info[i].danger_type !=
          content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
        EXPECT_EQ(content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT,
                  history_info[i].danger_type);
        items->at(i)->OnContentCheckCompleted(history_info[i].danger_type);
      }
    }
    return true;
  }

  void CreateSlowTestDownloads(
      size_t count, DownloadManager::DownloadVector* items) {
    for (size_t i = 0; i < count; ++i) {
      scoped_ptr<content::DownloadTestObserver> observer(
          CreateInProgressDownloadObserver(1));
      GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
      ui_test_utils::NavigateToURLWithDisposition(
          current_browser(), slow_download_url, CURRENT_TAB,
          ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
      observer->WaitForFinished();
      EXPECT_EQ(
          1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
    }
    GetCurrentManager()->GetAllDownloads(items);
    ASSERT_EQ(count, items->size());
  }

  DownloadItem* CreateSlowTestDownload() {
    scoped_ptr<content::DownloadTestObserver> observer(
        CreateInProgressDownloadObserver(1));
    GURL slow_download_url(URLRequestSlowDownloadJob::kUnknownSizeUrl);
    DownloadManager* manager = GetCurrentManager();

    EXPECT_EQ(0, manager->InProgressCount());
    if (manager->InProgressCount() != 0)
      return NULL;

    ui_test_utils::NavigateToURLWithDisposition(
        current_browser(), slow_download_url, CURRENT_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

    observer->WaitForFinished();
    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));

    DownloadManager::DownloadVector items;
    manager->GetAllDownloads(&items);

    DownloadItem* new_item = NULL;
    for (DownloadManager::DownloadVector::iterator iter = items.begin();
         iter != items.end(); ++iter) {
      if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
        // There should be only one IN_PROGRESS item.
        EXPECT_EQ(NULL, new_item);
        new_item = *iter;
      }
    }
    return new_item;
  }

  void FinishPendingSlowDownloads() {
    scoped_ptr<content::DownloadTestObserver> observer(
        CreateDownloadObserver(1));
    GURL finish_url(URLRequestSlowDownloadJob::kFinishDownloadUrl);
    ui_test_utils::NavigateToURLWithDisposition(
        current_browser(), finish_url, NEW_FOREGROUND_TAB,
        ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
    observer->WaitForFinished();
    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::COMPLETE));
  }

  content::DownloadTestObserver* CreateDownloadObserver(size_t download_count) {
    return new content::DownloadTestObserverTerminal(
        GetCurrentManager(), download_count,
        content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
  }

  content::DownloadTestObserver* CreateInProgressDownloadObserver(
      size_t download_count) {
    return new content::DownloadTestObserverInProgress(
        GetCurrentManager(), download_count);
  }

  bool RunFunction(UIThreadExtensionFunction* function,
                   const std::string& args) {
    scoped_refptr<UIThreadExtensionFunction> delete_function(function);
    SetUpExtensionFunction(function);
    bool result = extension_function_test_utils::RunFunction(
        function, args, browser(), GetFlags());
    if (!result) {
      LOG(ERROR) << function->GetError();
    }
    return result;
  }

  extension_function_test_utils::RunFunctionFlags GetFlags() {
    return current_browser()->profile()->IsOffTheRecord() ?
           extension_function_test_utils::INCLUDE_INCOGNITO :
           extension_function_test_utils::NONE;
  }

  // extension_function_test_utils::RunFunction*() only uses browser for its
  // profile(), so pass it the on-record browser so that it always uses the
  // on-record profile to match real-life behavior.

  base::Value* RunFunctionAndReturnResult(
      scoped_refptr<UIThreadExtensionFunction> function,
      const std::string& args) {
    SetUpExtensionFunction(function.get());
    return extension_function_test_utils::RunFunctionAndReturnSingleResult(
        function.get(), args, browser(), GetFlags());
  }

  std::string RunFunctionAndReturnError(
      scoped_refptr<UIThreadExtensionFunction> function,
      const std::string& args) {
    SetUpExtensionFunction(function.get());
    return extension_function_test_utils::RunFunctionAndReturnError(
        function.get(), args, browser(), GetFlags());
  }

  bool RunFunctionAndReturnString(
      scoped_refptr<UIThreadExtensionFunction> function,
      const std::string& args,
      std::string* result_string) {
    SetUpExtensionFunction(function.get());
    scoped_ptr<base::Value> result(RunFunctionAndReturnResult(function, args));
    EXPECT_TRUE(result.get());
    return result.get() && result->GetAsString(result_string);
  }

  std::string DownloadItemIdAsArgList(const DownloadItem* download_item) {
    return base::StringPrintf("[%d]", download_item->GetId());
  }

  const base::FilePath& downloads_directory() {
    return downloads_directory_.path();
  }

  DownloadsEventsListener* events_listener() { return events_listener_.get(); }

 private:
  void SetUpExtensionFunction(UIThreadExtensionFunction* function) {
    if (extension_) {
      // Recreate the tab each time for insulation.
      content::WebContents* tab = chrome::AddSelectedTabWithURL(
          current_browser(),
          extension_->GetResourceURL("empty.html"),
          content::PAGE_TRANSITION_LINK);
      function->set_extension(extension_);
      function->SetRenderViewHost(tab->GetRenderViewHost());
    }
  }

  void CreateAndSetDownloadsDirectory() {
    ASSERT_TRUE(downloads_directory_.CreateUniqueTempDir());
    current_browser()->profile()->GetPrefs()->SetFilePath(
        prefs::kDownloadDefaultDirectory,
        downloads_directory_.path());
  }

  base::ScopedTempDir downloads_directory_;
  const extensions::Extension* extension_;
  Browser* incognito_browser_;
  Browser* current_browser_;
  scoped_ptr<DownloadsEventsListener> events_listener_;

  DISALLOW_COPY_AND_ASSIGN(DownloadExtensionTest);
};

class MockIconExtractorImpl : public DownloadFileIconExtractor {
 public:
  MockIconExtractorImpl(const base::FilePath& path,
                        IconLoader::IconSize icon_size,
                        const std::string& response)
      : expected_path_(path),
        expected_icon_size_(icon_size),
        response_(response) {
  }
  virtual ~MockIconExtractorImpl() {}

  virtual bool ExtractIconURLForPath(const base::FilePath& path,
                                     IconLoader::IconSize icon_size,
                                     IconURLCallback callback) OVERRIDE {
    EXPECT_STREQ(expected_path_.value().c_str(), path.value().c_str());
    EXPECT_EQ(expected_icon_size_, icon_size);
    if (expected_path_ == path &&
        expected_icon_size_ == icon_size) {
      callback_ = callback;
      BrowserThread::PostTask(
          BrowserThread::UI, FROM_HERE,
          base::Bind(&MockIconExtractorImpl::RunCallback,
                     base::Unretained(this)));
      return true;
    } else {
      return false;
    }
  }

 private:
  void RunCallback() {
    callback_.Run(response_);
  }

  base::FilePath             expected_path_;
  IconLoader::IconSize expected_icon_size_;
  std::string          response_;
  IconURLCallback      callback_;
};

bool ItemNotInProgress(DownloadItem* item) {
  return item->GetState() != DownloadItem::IN_PROGRESS;
}

// Cancels the underlying DownloadItem when the ScopedCancellingItem goes out of
// scope. Like a scoped_ptr, but for DownloadItems.
class ScopedCancellingItem {
 public:
  explicit ScopedCancellingItem(DownloadItem* item) : item_(item) {}
  ~ScopedCancellingItem() {
    item_->Cancel(true);
    content::DownloadUpdatedObserver observer(
        item_, base::Bind(&ItemNotInProgress));
    observer.WaitForEvent();
  }
  DownloadItem* get() { return item_; }
 private:
  DownloadItem* item_;
  DISALLOW_COPY_AND_ASSIGN(ScopedCancellingItem);
};

// Cancels all the underlying DownloadItems when the ScopedItemVectorCanceller
// goes out of scope. Generalization of ScopedCancellingItem to many
// DownloadItems.
class ScopedItemVectorCanceller {
 public:
  explicit ScopedItemVectorCanceller(DownloadManager::DownloadVector* items)
    : items_(items) {
  }
  ~ScopedItemVectorCanceller() {
    for (DownloadManager::DownloadVector::const_iterator item = items_->begin();
         item != items_->end(); ++item) {
      if ((*item)->GetState() == DownloadItem::IN_PROGRESS)
        (*item)->Cancel(true);
      content::DownloadUpdatedObserver observer(
          (*item), base::Bind(&ItemNotInProgress));
      observer.WaitForEvent();
    }
  }

 private:
  DownloadManager::DownloadVector* items_;
  DISALLOW_COPY_AND_ASSIGN(ScopedItemVectorCanceller);
};

// Writes an HTML5 file so that it can be downloaded.
class HTML5FileWriter {
 public:
  static bool CreateFileForTesting(fileapi::FileSystemContext* context,
                                   const fileapi::FileSystemURL& path,
                                   const char*data,
                                   int length) {
    // Create a temp file.
    base::FilePath temp_file;
    if (!file_util::CreateTemporaryFile(&temp_file) ||
        file_util::WriteFile(temp_file, data, length) != length) {
      return false;
    }
    // Invoke the fileapi to copy it into the sandboxed filesystem.
    bool result = false;
    base::WaitableEvent done_event(true, false);
    BrowserThread::PostTask(
        BrowserThread::IO, FROM_HERE,
        base::Bind(&CreateFileForTestingOnIOThread,
                   base::Unretained(context),
                   path, temp_file,
                   base::Unretained(&result),
                   base::Unretained(&done_event)));
    // Wait for that to finish.
    done_event.Wait();
    base::DeleteFile(temp_file, false);
    return result;
  }

 private:
  static void CopyInCompletion(bool* result,
                               base::WaitableEvent* done_event,
                               base::PlatformFileError error) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    *result = error == base::PLATFORM_FILE_OK;
    done_event->Signal();
  }

  static void CreateFileForTestingOnIOThread(
      fileapi::FileSystemContext* context,
      const fileapi::FileSystemURL& path,
      const base::FilePath& temp_file,
      bool* result,
      base::WaitableEvent* done_event) {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
    context->operation_runner()->CopyInForeignFile(
        temp_file, path,
        base::Bind(&CopyInCompletion,
                   base::Unretained(result),
                   base::Unretained(done_event)));
  }
};

// TODO(benjhayden) Merge this with the other TestObservers.
class JustInProgressDownloadObserver
    : public content::DownloadTestObserverInProgress {
 public:
  JustInProgressDownloadObserver(
      DownloadManager* download_manager, size_t wait_count)
      : content::DownloadTestObserverInProgress(download_manager, wait_count) {
  }

  virtual ~JustInProgressDownloadObserver() {}

 private:
  virtual bool IsDownloadInFinalState(DownloadItem* item) OVERRIDE {
    return item->GetState() == DownloadItem::IN_PROGRESS;
  }

  DISALLOW_COPY_AND_ASSIGN(JustInProgressDownloadObserver);
};

bool ItemIsInterrupted(DownloadItem* item) {
  return item->GetState() == DownloadItem::INTERRUPTED;
}

content::DownloadInterruptReason InterruptReasonExtensionToContent(
    api::InterruptReason error) {
  switch (error) {
    case api::INTERRUPT_REASON_NONE:
      return content::DOWNLOAD_INTERRUPT_REASON_NONE;
#define INTERRUPT_REASON(name, value) \
    case api::INTERRUPT_REASON_##name: \
      return content::DOWNLOAD_INTERRUPT_REASON_##name;
#include "content/public/browser/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
  }
  NOTREACHED();
  return content::DOWNLOAD_INTERRUPT_REASON_NONE;
}

api::InterruptReason InterruptReasonContentToExtension(
    content::DownloadInterruptReason error) {
  switch (error) {
    case content::DOWNLOAD_INTERRUPT_REASON_NONE:
      return api::INTERRUPT_REASON_NONE;
#define INTERRUPT_REASON(name, value) \
    case content::DOWNLOAD_INTERRUPT_REASON_##name: \
      return api::INTERRUPT_REASON_##name;
#include "content/public/browser/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
  }
  NOTREACHED();
  return api::INTERRUPT_REASON_NONE;
}

}  // namespace

IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Open) {
  LoadExtension("downloads_split");
  EXPECT_STREQ(errors::kInvalidId,
               RunFunctionAndReturnError(
                   new DownloadsOpenFunction(),
                   "[-42]").c_str());

  DownloadItem* download_item = CreateSlowTestDownload();
  ASSERT_TRUE(download_item);
  EXPECT_FALSE(download_item->GetOpened());
  EXPECT_FALSE(download_item->GetOpenWhenComplete());
  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"application/octet-stream\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_item->GetURL().spec().c_str())));
  EXPECT_STREQ(errors::kNotComplete,
               RunFunctionAndReturnError(
                   new DownloadsOpenFunction(),
                   DownloadItemIdAsArgList(download_item)).c_str());

  FinishPendingSlowDownloads();
  EXPECT_FALSE(download_item->GetOpened());
  EXPECT_TRUE(RunFunction(new DownloadsOpenFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_TRUE(download_item->GetOpened());
}

IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_PauseResumeCancelErase) {
  DownloadItem* download_item = CreateSlowTestDownload();
  ASSERT_TRUE(download_item);

  // Call pause().  It should succeed and the download should be paused on
  // return.
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_TRUE(download_item->IsPaused());

  // Calling pause() twice shouldn't be an error.
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_TRUE(download_item->IsPaused());

  // Now try resuming this download.  It should succeed.
  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_FALSE(download_item->IsPaused());

  // Resume again.  Resuming a download that wasn't paused is not an error.
  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_FALSE(download_item->IsPaused());

  // Pause again.
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_TRUE(download_item->IsPaused());

  // And now cancel.
  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());

  // Cancel again.  Shouldn't have any effect.
  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(),
                          DownloadItemIdAsArgList(download_item)));
  EXPECT_EQ(DownloadItem::CANCELLED, download_item->GetState());

  // Calling paused on a non-active download yields kInvalidId.
  std::string error = RunFunctionAndReturnError(
      new DownloadsPauseFunction(), DownloadItemIdAsArgList(download_item));
  EXPECT_STREQ(errors::kNotInProgress, error.c_str());

  // Calling resume on a non-active download yields kInvalidId
  error = RunFunctionAndReturnError(
      new DownloadsResumeFunction(), DownloadItemIdAsArgList(download_item));
  EXPECT_STREQ(errors::kNotResumable, error.c_str());

  // Calling paused on a non-existent download yields kInvalidId.
  error = RunFunctionAndReturnError(
      new DownloadsPauseFunction(), "[-42]");
  EXPECT_STREQ(errors::kInvalidId, error.c_str());

  // Calling resume on a non-existent download yields kInvalidId
  error = RunFunctionAndReturnError(
      new DownloadsResumeFunction(), "[-42]");
  EXPECT_STREQ(errors::kInvalidId, error.c_str());

  int id = download_item->GetId();
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsEraseFunction(),
      base::StringPrintf("[{\"id\": %d}]", id)));
  DownloadManager::DownloadVector items;
  GetCurrentManager()->GetAllDownloads(&items);
  EXPECT_EQ(0UL, items.size());
  ASSERT_TRUE(result);
  download_item = NULL;
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
  int element = -1;
  ASSERT_TRUE(result_list->GetInteger(0, &element));
  EXPECT_EQ(id, element);
}

scoped_refptr<UIThreadExtensionFunction> MockedGetFileIconFunction(
    const base::FilePath& expected_path,
    IconLoader::IconSize icon_size,
    const std::string& response) {
  scoped_refptr<DownloadsGetFileIconFunction> function(
      new DownloadsGetFileIconFunction());
  function->SetIconExtractorForTesting(new MockIconExtractorImpl(
      expected_path, icon_size, response));
  return function;
}

// Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted
// download items.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_FileIcon_Active) {
  DownloadItem* download_item = CreateSlowTestDownload();
  ASSERT_TRUE(download_item);
  ASSERT_FALSE(download_item->GetTargetFilePath().empty());
  std::string args32(base::StringPrintf("[%d, {\"size\": 32}]",
                     download_item->GetId()));
  std::string result_string;

  // Get the icon for the in-progress download.  This call should succeed even
  // if the file type isn't registered.
  // Test whether the correct path is being pased into the icon extractor.
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      base::StringPrintf("[%d, {}]", download_item->GetId()), &result_string));

  // Now try a 16x16 icon.
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          download_item->GetTargetFilePath(), IconLoader::SMALL, "foo"),
      base::StringPrintf("[%d, {\"size\": 16}]", download_item->GetId()),
      &result_string));

  // Explicitly asking for 32x32 should give us a 32x32 icon.
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      args32, &result_string));

  // Finish the download and try again.
  FinishPendingSlowDownloads();
  EXPECT_EQ(DownloadItem::COMPLETE, download_item->GetState());
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      args32, &result_string));

  // Check the path passed to the icon extractor post-completion.
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      args32, &result_string));

  // Now create another download.
  download_item = CreateSlowTestDownload();
  ASSERT_TRUE(download_item);
  ASSERT_FALSE(download_item->GetTargetFilePath().empty());
  args32 = base::StringPrintf("[%d, {\"size\": 32}]", download_item->GetId());

  // Cancel the download. As long as the download has a target path, we should
  // be able to query the file icon.
  download_item->Cancel(true);
  ASSERT_FALSE(download_item->GetTargetFilePath().empty());
  // Let cleanup complete on the FILE thread.
  content::RunAllPendingInMessageLoop(BrowserThread::FILE);
  // Check the path passed to the icon extractor post-cancellation.
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          download_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      args32,
      &result_string));

  // Simulate an error during icon load by invoking the mock with an empty
  // result string.
  std::string error = RunFunctionAndReturnError(
      MockedGetFileIconFunction(download_item->GetTargetFilePath(),
                                IconLoader::NORMAL,
                                std::string()),
      args32);
  EXPECT_STREQ(errors::kIconNotFound, error.c_str());

  // Once the download item is deleted, we should return kInvalidId.
  int id = download_item->GetId();
  download_item->Remove();
  download_item = NULL;
  EXPECT_EQ(static_cast<DownloadItem*>(NULL),
            GetCurrentManager()->GetDownload(id));
  error = RunFunctionAndReturnError(new DownloadsGetFileIconFunction(), args32);
  EXPECT_STREQ(errors::kInvalidId,
               error.c_str());
}

// Test that we can acquire file icons for history downloads regardless of
// whether they exist or not.  If the file doesn't exist we should receive a
// generic icon from the OS/toolkit that may or may not be specific to the file
// type.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_FileIcon_History) {
  const HistoryDownloadInfo kHistoryInfo[] = {
    { FILE_PATH_LITERAL("real.txt"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
    { FILE_PATH_LITERAL("fake.txt"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
  };
  DownloadManager::DownloadVector all_downloads;
  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
                                     &all_downloads));

  base::FilePath real_path = all_downloads[0]->GetTargetFilePath();
  base::FilePath fake_path = all_downloads[1]->GetTargetFilePath();

  EXPECT_EQ(0, file_util::WriteFile(real_path, "", 0));
  ASSERT_TRUE(base::PathExists(real_path));
  ASSERT_FALSE(base::PathExists(fake_path));

  for (DownloadManager::DownloadVector::iterator iter = all_downloads.begin();
       iter != all_downloads.end();
       ++iter) {
    std::string result_string;
    // Use a MockIconExtractorImpl to test if the correct path is being passed
    // into the DownloadFileIconExtractor.
    EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
            (*iter)->GetTargetFilePath(), IconLoader::NORMAL, "hello"),
        base::StringPrintf("[%d, {\"size\": 32}]", (*iter)->GetId()),
        &result_string));
    EXPECT_STREQ("hello", result_string.c_str());
  }
}

// Test passing the empty query to search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_SearchEmptyQuery) {
  ScopedCancellingItem item(CreateSlowTestDownload());
  ASSERT_TRUE(item.get());

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
}

// Test the |filenameRegex| parameter for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchFilenameRegex) {
  const HistoryDownloadInfo kHistoryInfo[] = {
    { FILE_PATH_LITERAL("foobar"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
    { FILE_PATH_LITERAL("baz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
  };
  DownloadManager::DownloadVector all_downloads;
  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
                                     &all_downloads));

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{\"filenameRegex\": \"foobar\"}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
  base::DictionaryValue* item_value = NULL;
  ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
  int item_id = -1;
  ASSERT_TRUE(item_value->GetInteger("id", &item_id));
  ASSERT_EQ(all_downloads[0]->GetId(), static_cast<uint32>(item_id));
}

// Test the |id| parameter for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchId) {
  DownloadManager::DownloadVector items;
  CreateSlowTestDownloads(2, &items);
  ScopedItemVectorCanceller delete_items(&items);

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), base::StringPrintf(
          "[{\"id\": %u}]", items[0]->GetId())));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
  base::DictionaryValue* item_value = NULL;
  ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
  int item_id = -1;
  ASSERT_TRUE(item_value->GetInteger("id", &item_id));
  ASSERT_EQ(items[0]->GetId(), static_cast<uint32>(item_id));
}

// Test specifying both the |id| and |filename| parameters for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchIdAndFilename) {
  DownloadManager::DownloadVector items;
  CreateSlowTestDownloads(2, &items);
  ScopedItemVectorCanceller delete_items(&items);

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(),
      "[{\"id\": 0, \"filename\": \"foobar\"}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(0UL, result_list->GetSize());
}

// Test a single |orderBy| parameter for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchOrderBy) {
  const HistoryDownloadInfo kHistoryInfo[] = {
    { FILE_PATH_LITERAL("zzz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
    { FILE_PATH_LITERAL("baz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
  };
  DownloadManager::DownloadVector items;
  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
                                     &items));

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{\"orderBy\": [\"filename\"]}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(2UL, result_list->GetSize());
  base::DictionaryValue* item0_value = NULL;
  base::DictionaryValue* item1_value = NULL;
  ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
  ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
  std::string item0_name, item1_name;
  ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
  ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
  ASSERT_GT(items[0]->GetTargetFilePath().value(),
            items[1]->GetTargetFilePath().value());
  ASSERT_LT(item0_name, item1_name);
}

// Test specifying an empty |orderBy| parameter for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchOrderByEmpty) {
  const HistoryDownloadInfo kHistoryInfo[] = {
    { FILE_PATH_LITERAL("zzz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
    { FILE_PATH_LITERAL("baz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
  };
  DownloadManager::DownloadVector items;
  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
                                     &items));

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{\"orderBy\": []}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(2UL, result_list->GetSize());
  base::DictionaryValue* item0_value = NULL;
  base::DictionaryValue* item1_value = NULL;
  ASSERT_TRUE(result_list->GetDictionary(0, &item0_value));
  ASSERT_TRUE(result_list->GetDictionary(1, &item1_value));
  std::string item0_name, item1_name;
  ASSERT_TRUE(item0_value->GetString("filename", &item0_name));
  ASSERT_TRUE(item1_value->GetString("filename", &item1_name));
  ASSERT_GT(items[0]->GetTargetFilePath().value(),
            items[1]->GetTargetFilePath().value());
  ASSERT_GT(item0_name, item1_name);
}

// Test the |danger| option for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchDanger) {
  const HistoryDownloadInfo kHistoryInfo[] = {
    { FILE_PATH_LITERAL("zzz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
    { FILE_PATH_LITERAL("baz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS }
  };
  DownloadManager::DownloadVector items;
  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
                                     &items));

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{\"danger\": \"content\"}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
}

// Test the |state| option for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchState) {
  DownloadManager::DownloadVector items;
  CreateSlowTestDownloads(2, &items);
  ScopedItemVectorCanceller delete_items(&items);

  items[0]->Cancel(true);

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{\"state\": \"in_progress\"}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
}

// Test the |limit| option for search().
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_SearchLimit) {
  DownloadManager::DownloadVector items;
  CreateSlowTestDownloads(2, &items);
  ScopedItemVectorCanceller delete_items(&items);

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{\"limit\": 1}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
}

// Test invalid search parameters.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchInvalid) {
  std::string error = RunFunctionAndReturnError(
      new DownloadsSearchFunction(), "[{\"filenameRegex\": \"(\"}]");
  EXPECT_STREQ(errors::kInvalidFilter,
      error.c_str());
  error = RunFunctionAndReturnError(
      new DownloadsSearchFunction(), "[{\"orderBy\": [\"goat\"]}]");
  EXPECT_STREQ(errors::kInvalidOrderBy,
      error.c_str());
  error = RunFunctionAndReturnError(
      new DownloadsSearchFunction(), "[{\"limit\": -1}]");
  EXPECT_STREQ(errors::kInvalidQueryLimit,
      error.c_str());
}

// Test searching using multiple conditions through multiple downloads.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchPlural) {
  const HistoryDownloadInfo kHistoryInfo[] = {
    { FILE_PATH_LITERAL("aaa"),
      DownloadItem::CANCELLED,
      content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS },
    { FILE_PATH_LITERAL("zzz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
    { FILE_PATH_LITERAL("baz"),
      DownloadItem::COMPLETE,
      content::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT },
  };
  DownloadManager::DownloadVector items;
  ASSERT_TRUE(CreateHistoryDownloads(kHistoryInfo, arraysize(kHistoryInfo),
                                     &items));

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{"
      "\"state\": \"complete\", "
      "\"danger\": \"content\", "
      "\"orderBy\": [\"filename\"], "
      "\"limit\": 1}]"));
  ASSERT_TRUE(result.get());
  base::ListValue* result_list = NULL;
  ASSERT_TRUE(result->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
  base::DictionaryValue* item_value = NULL;
  ASSERT_TRUE(result_list->GetDictionary(0, &item_value));
  base::FilePath::StringType item_name;
  ASSERT_TRUE(item_value->GetString("filename", &item_name));
  ASSERT_EQ(items[2]->GetTargetFilePath().value(), item_name);
}

// Test that incognito downloads are only visible in incognito contexts, and
// test that on-record downloads are visible in both incognito and on-record
// contexts, for DownloadsSearchFunction, DownloadsPauseFunction,
// DownloadsResumeFunction, and DownloadsCancelFunction.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
    DownloadExtensionTest_SearchPauseResumeCancelGetFileIconIncognito) {
  scoped_ptr<base::Value> result_value;
  base::ListValue* result_list = NULL;
  base::DictionaryValue* result_dict = NULL;
  base::FilePath::StringType filename;
  bool is_incognito = false;
  std::string error;
  std::string on_item_arg;
  std::string off_item_arg;
  std::string result_string;

  // Set up one on-record item and one off-record item.
  // Set up the off-record item first because otherwise there are mysteriously 3
  // items total instead of 2.
  // TODO(benjhayden): Figure out where the third item comes from.
  GoOffTheRecord();
  DownloadItem* off_item = CreateSlowTestDownload();
  ASSERT_TRUE(off_item);
  off_item_arg = DownloadItemIdAsArgList(off_item);

  GoOnTheRecord();
  DownloadItem* on_item = CreateSlowTestDownload();
  ASSERT_TRUE(on_item);
  on_item_arg = DownloadItemIdAsArgList(on_item);
  ASSERT_TRUE(on_item->GetTargetFilePath() != off_item->GetTargetFilePath());

  // Extensions running in the incognito window should have access to both
  // items because the Test extension is in spanning mode.
  GoOffTheRecord();
  result_value.reset(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{}]"));
  ASSERT_TRUE(result_value.get());
  ASSERT_TRUE(result_value->GetAsList(&result_list));
  ASSERT_EQ(2UL, result_list->GetSize());
  ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
  ASSERT_TRUE(result_dict->GetString("filename", &filename));
  ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
  EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
  EXPECT_FALSE(is_incognito);
  ASSERT_TRUE(result_list->GetDictionary(1, &result_dict));
  ASSERT_TRUE(result_dict->GetString("filename", &filename));
  ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
  EXPECT_TRUE(off_item->GetTargetFilePath() == base::FilePath(filename));
  EXPECT_TRUE(is_incognito);

  // Extensions running in the on-record window should have access only to the
  // on-record item.
  GoOnTheRecord();
  result_value.reset(RunFunctionAndReturnResult(
      new DownloadsSearchFunction(), "[{}]"));
  ASSERT_TRUE(result_value.get());
  ASSERT_TRUE(result_value->GetAsList(&result_list));
  ASSERT_EQ(1UL, result_list->GetSize());
  ASSERT_TRUE(result_list->GetDictionary(0, &result_dict));
  ASSERT_TRUE(result_dict->GetString("filename", &filename));
  EXPECT_TRUE(on_item->GetTargetFilePath() == base::FilePath(filename));
  ASSERT_TRUE(result_dict->GetBoolean("incognito", &is_incognito));
  EXPECT_FALSE(is_incognito);

  // Pausing/Resuming the off-record item while on the record should return an
  // error. Cancelling "non-existent" downloads is not an error.
  error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
  EXPECT_STREQ(errors::kInvalidId,
               error.c_str());
  error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
                                    off_item_arg);
  EXPECT_STREQ(errors::kInvalidId,
               error.c_str());
  error = RunFunctionAndReturnError(
      new DownloadsGetFileIconFunction(),
      base::StringPrintf("[%d, {}]", off_item->GetId()));
  EXPECT_STREQ(errors::kInvalidId,
               error.c_str());

  GoOffTheRecord();

  // Do the FileIcon test for both the on- and off-items while off the record.
  // NOTE(benjhayden): This does not include the FileIcon test from history,
  // just active downloads. This shouldn't be a problem.
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          on_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      base::StringPrintf("[%d, {}]", on_item->GetId()), &result_string));
  EXPECT_TRUE(RunFunctionAndReturnString(MockedGetFileIconFunction(
          off_item->GetTargetFilePath(), IconLoader::NORMAL, "foo"),
      base::StringPrintf("[%d, {}]", off_item->GetId()), &result_string));

  // Do the pause/resume/cancel test for both the on- and off-items while off
  // the record.
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
  EXPECT_TRUE(on_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
  EXPECT_TRUE(on_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
  EXPECT_FALSE(on_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), on_item_arg));
  EXPECT_FALSE(on_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), on_item_arg));
  EXPECT_TRUE(on_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
  EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), on_item_arg));
  EXPECT_EQ(DownloadItem::CANCELLED, on_item->GetState());
  error = RunFunctionAndReturnError(new DownloadsPauseFunction(), on_item_arg);
  EXPECT_STREQ(errors::kNotInProgress, error.c_str());
  error = RunFunctionAndReturnError(new DownloadsResumeFunction(), on_item_arg);
  EXPECT_STREQ(errors::kNotResumable, error.c_str());
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
  EXPECT_TRUE(off_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
  EXPECT_TRUE(off_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
  EXPECT_FALSE(off_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsResumeFunction(), off_item_arg));
  EXPECT_FALSE(off_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsPauseFunction(), off_item_arg));
  EXPECT_TRUE(off_item->IsPaused());
  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
  EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
  EXPECT_TRUE(RunFunction(new DownloadsCancelFunction(), off_item_arg));
  EXPECT_EQ(DownloadItem::CANCELLED, off_item->GetState());
  error = RunFunctionAndReturnError(new DownloadsPauseFunction(), off_item_arg);
  EXPECT_STREQ(errors::kNotInProgress, error.c_str());
  error = RunFunctionAndReturnError(new DownloadsResumeFunction(),
                                    off_item_arg);
  EXPECT_STREQ(errors::kNotResumable, error.c_str());
}

// Test that we can start a download and that the correct sequence of events is
// fired for it.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Basic) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();
  GoOnTheRecord();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// Test that we can start a download from an incognito context, and that the
// download knows that it's incognito.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Incognito) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  GoOffTheRecord();
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": true,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\":%d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\":%d,"
                         "  \"state\": {"
                         "    \"current\": \"complete\","
                         "    \"previous\": \"in_progress\"}}]",
                         result_id)));
}

#if defined(OS_WIN) && defined(USE_AURA)
// This test is very flaky on Win Aura. http://crbug.com/248438
#define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
    DISABLED_DownloadExtensionTest_Download_UnsafeHeaders
#else
#define MAYBE_DownloadExtensionTest_Download_UnsafeHeaders \
    DownloadExtensionTest_Download_UnsafeHeaders
#endif

// Test that we disallow certain headers case-insensitively.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       MAYBE_DownloadExtensionTest_Download_UnsafeHeaders) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  GoOnTheRecord();

  static const char* kUnsafeHeaders[] = {
    "Accept-chArsEt",
    "accept-eNcoding",
    "coNNection",
    "coNteNt-leNgth",
    "cooKIE",
    "cOOkie2",
    "coNteNt-traNsfer-eNcodiNg",
    "dAtE",
    "ExpEcT",
    "hOsT",
    "kEEp-aLivE",
    "rEfErEr",
    "tE",
    "trAilER",
    "trANsfer-eNcodiNg",
    "upGRAde",
    "usER-agENt",
    "viA",
    "pRoxY-",
    "sEc-",
    "pRoxY-probably-not-evil",
    "sEc-probably-not-evil",
    "oRiGiN",
    "Access-Control-Request-Headers",
    "Access-Control-Request-Method",
  };

  for (size_t index = 0; index < arraysize(kUnsafeHeaders); ++index) {
    std::string download_url = test_server()->GetURL("slow?0").spec();
    EXPECT_STREQ(errors::kInvalidHeader,
                  RunFunctionAndReturnError(new DownloadsDownloadFunction(),
                                            base::StringPrintf(
        "[{\"url\": \"%s\","
        "  \"filename\": \"unsafe-header-%d.txt\","
        "  \"headers\": [{"
        "    \"name\": \"%s\","
        "    \"value\": \"unsafe\"}]}]",
        download_url.c_str(),
        static_cast<int>(index),
        kUnsafeHeaders[index])).c_str());
  }
}

#if defined(OS_WIN)
#define MAYBE_DownloadExtensionTest_Download_Subdirectory\
        DISABLED_DownloadExtensionTest_Download_Subdirectory
#else
#define MAYBE_DownloadExtensionTest_Download_Subdirectory\
        DownloadExtensionTest_Download_Subdirectory
#endif
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       MAYBE_DownloadExtensionTest_Download_Subdirectory) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\","
          "  \"filename\": \"sub/dir/ect/ory.txt\"}]",
          download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("sub/dir/ect/ory.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// Test that invalid filenames are disallowed.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_InvalidFilename) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();
  GoOnTheRecord();

  EXPECT_STREQ(errors::kInvalidFilename,
                RunFunctionAndReturnError(new DownloadsDownloadFunction(),
                                          base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"../../../../../etc/passwd\"}]",
      download_url.c_str())).c_str());
}

// Test that downloading invalid URLs immediately returns kInvalidURLError.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_InvalidURLs) {
  LoadExtension("downloads_split");
  GoOnTheRecord();

  static const char* kInvalidURLs[] = {
    "foo bar",
    "../hello",
    "/hello",
    "http://",
    "#frag",
    "foo/bar.html#frag",
    "google.com/",
  };

  for (size_t index = 0; index < arraysize(kInvalidURLs); ++index) {
    EXPECT_STREQ(errors::kInvalidURL,
                  RunFunctionAndReturnError(new DownloadsDownloadFunction(),
                                            base::StringPrintf(
        "[{\"url\": \"%s\"}]", kInvalidURLs[index])).c_str())
      << kInvalidURLs[index];
  }

  EXPECT_STREQ("net::ERR_ACCESS_DENIED", RunFunctionAndReturnError(
      new DownloadsDownloadFunction(),
      "[{\"url\": \"javascript:document.write(\\\"hello\\\");\"}]").c_str());
  EXPECT_STREQ("net::ERR_ACCESS_DENIED", RunFunctionAndReturnError(
      new DownloadsDownloadFunction(),
      "[{\"url\": \"javascript:return false;\"}]").c_str());
  EXPECT_STREQ("net::ERR_NOT_IMPLEMENTED", RunFunctionAndReturnError(
      new DownloadsDownloadFunction(),
      "[{\"url\": \"ftp://example.com/example.txt\"}]").c_str());
}

// TODO(benjhayden): Set up a test ftp server, add ftp://localhost* to
// permissions, test downloading from ftp.

// Valid URLs plus fragments are still valid URLs.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_URLFragment) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0#fragment").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// Valid data URLs are valid URLs.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_DataURL) {
  LoadExtension("downloads_split");
  std::string download_url = "data:text/plain,hello";
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"data.txt\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("data.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// Valid file URLs are valid URLs.
#if defined(OS_WIN) && defined(USE_AURA)
// Disabled due to crbug.com/175711
#define MAYBE_DownloadExtensionTest_Download_File \
        DISABLED_DownloadExtensionTest_Download_File
#else
#define MAYBE_DownloadExtensionTest_Download_File \
        DownloadExtensionTest_Download_File
#endif
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       MAYBE_DownloadExtensionTest_Download_File) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  std::string download_url = "file:///";
#if defined(OS_WIN)
  download_url += "C:/";
#endif

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"file.txt\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"mime\": \"text/html\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"filename\": {"
                          "    \"previous\": \"\","
                          "    \"current\": \"%s\"}}]",
                          result_id,
                          GetFilename("file.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"complete\"}}]",
                          result_id)));
}

// Test that auth-basic-succeed would fail if the resource requires the
// Authorization header and chrome fails to propagate it back to the server.
// This tests both that testserver.py does not succeed when it should fail as
// well as how the downloads extension API exposes the failure to extensions.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_AuthBasic_Fail) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("auth-basic").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"auth-basic-fail.txt\"}]",
      download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitForInterruption(
      item,
      content::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"text/html\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
}

// Test that DownloadsDownloadFunction propagates |headers| to the URLRequest.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Headers) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("files/downloads/"
      "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"headers-succeed.txt\","
      "  \"headers\": ["
      "    {\"name\": \"Foo\", \"value\": \"bar\"},"
      "    {\"name\": \"Qx\", \"value\":\"yo\"}]}]",
      download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"application/octet-stream\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("headers-succeed.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// Test that headers-succeed would fail if the resource requires the headers and
// chrome fails to propagate them back to the server.  This tests both that
// testserver.py does not succeed when it should fail as well as how the
// downloads extension api exposes the failure to extensions.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Headers_Fail) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("files/downloads/"
      "a_zip_file.zip?expected_headers=Foo:bar&expected_headers=Qx:yo").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"headers-fail.txt\"}]",
      download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitForInterruption(
      item,
      content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"bytesReceived\": 0,"
                         "  \"mime\": \"\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         download_url.c_str())));
}

// Test that DownloadsDownloadFunction propagates the Authorization header
// correctly.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_AuthBasic) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("auth-basic").spec();
  // This is just base64 of 'username:secret'.
  static const char* kAuthorization = "dXNlcm5hbWU6c2VjcmV0";
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"auth-basic-succeed.txt\","
      "  \"headers\": [{"
      "    \"name\": \"Authorization\","
      "    \"value\": \"Basic %s\"}]}]",
      download_url.c_str(), kAuthorization)));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"mime\": \"text/html\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"complete\"}}]", result_id)));
}

// Test that DownloadsDownloadFunction propagates the |method| and |body|
// parameters to the URLRequest.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Post) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("files/post/downloads/"
      "a_zip_file.zip?expected_body=BODY").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"filename\": \"post-succeed.txt\","
      "  \"method\": \"POST\","
      "  \"body\": \"BODY\"}]",
      download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"application/octet-stream\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("post-succeed.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// Test that downloadPostSuccess would fail if the resource requires the POST
// method, and chrome fails to propagate the |method| parameter back to the
// server. This tests both that testserver.py does not succeed when it should
// fail, and this tests how the downloads extension api exposes the failure to
// extensions.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Post_Get) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("files/post/downloads/"
      "a_zip_file.zip?expected_body=BODY").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
        new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"body\": \"BODY\","
      "  \"filename\": \"post-get.txt\"}]",
      download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitForInterruption(
      item,
      content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"\","
                         "  \"paused\": false,"
                         "  \"id\": %d,"
                         "  \"url\": \"%s\"}]",
                         result_id,
                         download_url.c_str())));
}

// Test that downloadPostSuccess would fail if the resource requires the POST
// method, and chrome fails to propagate the |body| parameter back to the
// server. This tests both that testserver.py does not succeed when it should
// fail, and this tests how the downloads extension api exposes the failure to
// extensions.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Post_NoBody) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("files/post/downloads/"
      "a_zip_file.zip?expected_body=BODY").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
      "[{\"url\": \"%s\","
      "  \"method\": \"POST\","
      "  \"filename\": \"post-nobody.txt\"}]",
      download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitForInterruption(
      item,
      content::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"mime\": \"\","
                         "  \"paused\": false,"
                         "  \"id\": %d,"
                         "  \"url\": \"%s\"}]",
                         result_id,
                         download_url.c_str())));
}

// Test that cancel()ing an in-progress download causes its state to transition
// to interrupted, and test that that state transition is detectable by an
// onChanged event listener.  TODO(benjhayden): Test other sources of
// interruptions such as server death.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_Cancel) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL(
      "download-known-size").spec();
  GoOnTheRecord();

  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"mime\": \"application/octet-stream\","
                          "  \"paused\": false,"
                          "  \"id\": %d,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  item->Cancel(true);
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"error\": {\"current\":\"USER_CANCELED\"},"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"interrupted\"}}]",
                          result_id)));
}

// Test downloading filesystem: URLs.
// NOTE: chrome disallows creating HTML5 FileSystem Files in incognito.
IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_Download_FileSystemURL) {
  static const char* kPayloadData = "on the record\ndata";
  GoOnTheRecord();
  LoadExtension("downloads_split");

  const std::string download_url = "filesystem:" + GetExtensionURL() +
    "temporary/on_record.txt";

  // Setup a file in the filesystem which we can download.
  ASSERT_TRUE(HTML5FileWriter::CreateFileForTesting(
      BrowserContext::GetDefaultStoragePartition(browser()->profile())->
          GetFileSystemContext(),
      fileapi::FileSystemURL::CreateForTest(GURL(download_url)),
      kPayloadData, strlen(kPayloadData)));

  // Now download it.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));

  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"filename\": {"
                          "    \"previous\": \"\","
                          "    \"current\": \"%s\"}}]",
                          result_id,
                          GetFilename("on_record.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"complete\"}}]",
                          result_id)));
  std::string disk_data;
  EXPECT_TRUE(file_util::ReadFileToString(item->GetTargetFilePath(),
                                          &disk_data));
  EXPECT_STREQ(kPayloadData, disk_data.c_str());
}

IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_OnDeterminingFilename_NoChange) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  // Wait for the onCreated and onDeterminingFilename events.
  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  // The download should complete successfully.
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_DangerousOverride) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("overridden.swf")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"danger\": {"
                         "    \"previous\":\"safe\","
                         "    \"current\":\"file\"}}]",
                         result_id)));

  item->ValidateDangerousDownload();
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"danger\": {"
                         "    \"previous\":\"file\","
                         "    \"current\":\"accepted\"}}]",
                         result_id)));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"complete\"}}]",
                          result_id)));
  EXPECT_EQ(downloads_directory().AppendASCII("overridden.swf"),
            item->GetTargetFilePath());
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_ReferencesParentInvalid) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("sneaky/../../sneaky.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"filename\": {"
                          "    \"previous\": \"\","
                          "    \"current\": \"%s\"}}]",
                          result_id,
                          GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"complete\"}}]",
                          result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_IllegalFilename) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("<")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, base::StringPrintf(
      "[{\"id\": %d,"
      "  \"filename\": {"
      "    \"previous\": \"\","
      "    \"current\": \"%s\"}}]",
      result_id,
      GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, base::StringPrintf(
      "[{\"id\": %d,"
      "  \"state\": {"
      "    \"previous\": \"in_progress\","
      "    \"current\": \"complete\"}}]",
      result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_IllegalFilenameExtension) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL(
          "My Computer.{20D04FE0-3AEA-1069-A2D8-08002B30309D}/foo")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, base::StringPrintf(
      "[{\"id\": %d,"
      "  \"filename\": {"
      "    \"previous\": \"\","
      "    \"current\": \"%s\"}}]",
      result_id,
      GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, base::StringPrintf(
      "[{\"id\": %d,"
      "  \"state\": {"
      "    \"previous\": \"in_progress\","
      "    \"current\": \"complete\"}}]",
      result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_ReservedFilename) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("con.foo")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, base::StringPrintf(
      "[{\"id\": %d,"
      "  \"filename\": {"
      "    \"previous\": \"\","
      "    \"current\": \"%s\"}}]",
      result_id,
      GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged, base::StringPrintf(
      "[{\"id\": %d,"
      "  \"state\": {"
      "    \"previous\": \"in_progress\","
      "    \"current\": \"complete\"}}]",
      result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_CurDirInvalid) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL(".")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_ParentDirInvalid) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("..")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_AbsPathInvalid) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename. Absolute paths should be rejected.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      downloads_directory().Append(FILE_PATH_LITERAL("sneaky.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"filename\": {"
                          "    \"previous\": \"\","
                          "    \"current\": \"%s\"}}]",
                          result_id,
                          GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                          "  \"state\": {"
                          "    \"previous\": \"in_progress\","
                          "    \"current\": \"complete\"}}]",
                          result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_EmptyBasenameInvalid) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename. Empty basenames should be rejected.
  std::string error;
  ASSERT_FALSE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("foo/")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_STREQ(errors::kInvalidFilename, error.c_str());

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_Override) {
  GoOnTheRecord();
  LoadExtension("downloads_split");
  AddFilenameDeterminer();
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());
  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"id\": %d,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         result_id,
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  std::string error;
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("slow.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));

  // Start downloading a file.
  result.reset(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller2(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"id\": %d,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         result_id,
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  // Also test that DetermineFilename allows (chrome) extensions to set
  // filenames without (filename) extensions. (Don't ask about v8 extensions or
  // python extensions or kernel extensions or firefox extensions...)
  error = "";
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("foo")),
      api::FILENAME_CONFLICT_ACTION_OVERWRITE,
      &error));
  EXPECT_EQ("", error);

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("foo").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

// TODO test precedence rules: install_time

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_RemoveFilenameDeterminer) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  GoOnTheRecord();
  LoadExtension("downloads_split");
  content::RenderProcessHost* host = AddFilenameDeterminer();
  std::string download_url = test_server()->GetURL("slow?0").spec();

  // Start downloading a file.
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Remove a determiner while waiting for it.
  RemoveFilenameDeterminer(host);

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_IncognitoSplit) {
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  GoOnTheRecord();
  AddFilenameDeterminer();

  GoOffTheRecord();
  AddFilenameDeterminer();

  // Start an on-record download.
  GoOnTheRecord();
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  // Wait for the onCreated and onDeterminingFilename events.
  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"incognito\": false,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename events.
  std::string error;
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      current_browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("42.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  // The download should complete successfully.
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("42.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));

  // Start an incognito download for comparison.
  GoOffTheRecord();
  result.reset(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller2(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": true,"
                         "  \"id\": %d,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         result_id,
                         download_url.c_str())));
  // On-Record renderers should not see events for off-record items.
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"incognito\": true,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  error = "";
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      current_browser()->profile(),
      false,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("5.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  // The download should complete successfully.
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("5.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    DownloadExtensionTest_OnDeterminingFilename_IncognitoSpanning) {
  LoadExtension("downloads_spanning");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  std::string download_url = test_server()->GetURL("slow?0").spec();

  GoOnTheRecord();
  AddFilenameDeterminer();

  // There is a single extension renderer that sees both on-record and
  // off-record events. The extension functions see the on-record profile with
  // include_incognito=true.

  // Start an on-record download.
  GoOnTheRecord();
  scoped_ptr<base::Value> result(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  int result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  DownloadItem* item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  // Wait for the onCreated and onDeterminingFilename events.
  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                          "  \"incognito\": false,"
                          "  \"id\": %d,"
                          "  \"mime\": \"text/plain\","
                          "  \"paused\": false,"
                          "  \"url\": \"%s\"}]",
                          result_id,
                          download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"incognito\": false,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename events.
  std::string error;
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      current_browser()->profile(),
      true,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("42.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  // The download should complete successfully.
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("42.txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));

  // Start an incognito download for comparison.
  GoOffTheRecord();
  result.reset(RunFunctionAndReturnResult(
      new DownloadsDownloadFunction(), base::StringPrintf(
          "[{\"url\": \"%s\"}]", download_url.c_str())));
  ASSERT_TRUE(result.get());
  result_id = -1;
  ASSERT_TRUE(result->GetAsInteger(&result_id));
  item = GetCurrentManager()->GetDownload(result_id);
  ASSERT_TRUE(item);
  ScopedCancellingItem canceller2(item);
  ASSERT_EQ(download_url, item->GetOriginalUrl().spec());

  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": true,"
                         "  \"id\": %d,"
                         "  \"mime\": \"text/plain\","
                         "  \"paused\": false,"
                         "  \"url\": \"%s\"}]",
                         result_id,
                         download_url.c_str())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"incognito\": true,"
                         "  \"filename\":\"slow.txt\"}]",
                         result_id)));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  // Respond to the onDeterminingFilename.
  error = "";
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      current_browser()->profile(),
      true,
      GetExtensionId(),
      result_id,
      base::FilePath(FILE_PATH_LITERAL("42.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error));
  EXPECT_EQ("", error);

  // The download should complete successfully.
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         result_id,
                         GetFilename("42 (1).txt").c_str())));
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         result_id)));
}

#if defined(OS_WIN)
// This test is very flaky on Win XP and Aura. http://crbug.com/248438
#define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
    DISABLED_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
#else
#define MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume \
    DownloadExtensionTest_OnDeterminingFilename_InterruptedResume
#endif

// Test download interruption while extensions determining filename. Should not
// re-dispatch onDeterminingFilename.
IN_PROC_BROWSER_TEST_F(
    DownloadExtensionTest,
    MAYBE_DownloadExtensionTest_OnDeterminingFilename_InterruptedResume) {
  CommandLine::ForCurrentProcess()->AppendSwitch(
      switches::kEnableDownloadResumption);
  LoadExtension("downloads_split");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(test_server()->Start());
  GoOnTheRecord();
  content::RenderProcessHost* host = AddFilenameDeterminer();

  // Start a download.
  DownloadItem* item = NULL;
  {
    DownloadManager* manager = GetCurrentManager();
    scoped_ptr<content::DownloadTestObserver> observer(
        new JustInProgressDownloadObserver(manager, 1));
    ASSERT_EQ(0, manager->InProgressCount());
    // Tabs created just for a download are automatically closed, invalidating
    // the download's WebContents. Downloads without WebContents cannot be
    // resumed. http://crbug.com/225901
    ui_test_utils::NavigateToURLWithDisposition(
        current_browser(),
        GURL(URLRequestSlowDownloadJob::kUnknownSizeUrl),
        CURRENT_TAB,
        ui_test_utils::BROWSER_TEST_NONE);
    observer->WaitForFinished();
    EXPECT_EQ(1u, observer->NumDownloadsSeenInState(DownloadItem::IN_PROGRESS));
    DownloadManager::DownloadVector items;
    manager->GetAllDownloads(&items);
    for (DownloadManager::DownloadVector::iterator iter = items.begin();
          iter != items.end(); ++iter) {
      if ((*iter)->GetState() == DownloadItem::IN_PROGRESS) {
        // There should be only one IN_PROGRESS item.
        EXPECT_EQ(NULL, item);
        item = *iter;
      }
    }
    ASSERT_TRUE(item);
  }
  ScopedCancellingItem canceller(item);

  // Wait for the onCreated and onDeterminingFilename event.
  ASSERT_TRUE(WaitFor(events::kOnDownloadCreated,
      base::StringPrintf("[{\"danger\": \"safe\","
                         "  \"incognito\": false,"
                         "  \"id\": %d,"
                         "  \"mime\": \"application/octet-stream\","
                         "  \"paused\": false}]",
                         item->GetId())));
  ASSERT_TRUE(WaitFor(
      events::kOnDownloadDeterminingFilename,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"incognito\": false,"
                         "  \"filename\":\"download-unknown-size\"}]",
                         item->GetId())));
  ASSERT_TRUE(item->GetTargetFilePath().empty());
  ASSERT_EQ(DownloadItem::IN_PROGRESS, item->GetState());

  ClearEvents();
  ui_test_utils::NavigateToURLWithDisposition(
      current_browser(),
      GURL(URLRequestSlowDownloadJob::kErrorDownloadUrl),
      NEW_BACKGROUND_TAB,
      ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);

  // Errors caught before filename determination are delayed until after
  // filename determination.
  std::string error;
  ASSERT_TRUE(ExtensionDownloadsEventRouter::DetermineFilename(
      current_browser()->profile(),
      false,
      GetExtensionId(),
      item->GetId(),
      base::FilePath(FILE_PATH_LITERAL("42.txt")),
      api::FILENAME_CONFLICT_ACTION_UNIQUIFY,
      &error)) << error;
  EXPECT_EQ("", error);
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"filename\": {"
                         "    \"previous\": \"\","
                         "    \"current\": \"%s\"}}]",
                         item->GetId(),
                         GetFilename("42.txt").c_str())));

  content::DownloadUpdatedObserver interrupted(item, base::Bind(
      ItemIsInterrupted));
  ASSERT_TRUE(interrupted.WaitForEvent());
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"error\":{\"current\":\"NETWORK_FAILED\"},"
                         "  \"state\":{"
                         "    \"previous\":\"in_progress\","
                         "    \"current\":\"interrupted\"}}]",
                         item->GetId())));

  ClearEvents();
  // Downloads that are restarted on resumption trigger another download target
  // determination.
  RemoveFilenameDeterminer(host);
  item->Resume();

  // Errors caught before filename determination is complete are delayed until
  // after filename determination so that, on resumption, filename determination
  // does not need to be re-done. So, there will not be a second
  // onDeterminingFilename event.

  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"error\":{\"previous\":\"NETWORK_FAILED\"},"
                         "  \"state\":{"
                         "    \"previous\":\"interrupted\","
                         "    \"current\":\"in_progress\"}}]",
                         item->GetId())));

  ClearEvents();
  FinishPendingSlowDownloads();

  // The download should complete successfully.
  ASSERT_TRUE(WaitFor(events::kOnDownloadChanged,
      base::StringPrintf("[{\"id\": %d,"
                         "  \"state\": {"
                         "    \"previous\": \"in_progress\","
                         "    \"current\": \"complete\"}}]",
                         item->GetId())));
}

IN_PROC_BROWSER_TEST_F(DownloadExtensionTest,
                       DownloadExtensionTest_SetShelfEnabled) {
  LoadExtension("downloads_split");
  EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[false]"));
  EXPECT_FALSE(DownloadServiceFactory::GetForBrowserContext(
      browser()->profile())->IsShelfEnabled());
  EXPECT_TRUE(RunFunction(new DownloadsSetShelfEnabledFunction(), "[true]"));
  EXPECT_TRUE(DownloadServiceFactory::GetForBrowserContext(
      browser()->profile())->IsShelfEnabled());
  // TODO(benjhayden) Test that existing shelves are hidden.
  // TODO(benjhayden) Test multiple extensions.
  // TODO(benjhayden) Test disabling extensions.
  // TODO(benjhayden) Test that browsers associated with other profiles are not
  // affected.
  // TODO(benjhayden) Test incognito.
}

// TODO(benjhayden) Figure out why DisableExtension() does not fire
// OnListenerRemoved.

// TODO(benjhayden) Test that the shelf is shown for download() both with and
// without a WebContents.

class DownloadsApiTest : public ExtensionApiTest {
 public:
  DownloadsApiTest() {}
  virtual ~DownloadsApiTest() {}
 private:
  DISALLOW_COPY_AND_ASSIGN(DownloadsApiTest);
};


IN_PROC_BROWSER_TEST_F(DownloadsApiTest, DownloadsApiTest) {
  ASSERT_TRUE(RunExtensionTest("downloads")) << message_;
}

TEST(DownloadInterruptReasonEnumsSynced,
     DownloadInterruptReasonEnumsSynced) {
#define INTERRUPT_REASON(name, value) \
  EXPECT_EQ(InterruptReasonContentToExtension( \
      content::DOWNLOAD_INTERRUPT_REASON_##name), \
      api::INTERRUPT_REASON_##name); \
  EXPECT_EQ(InterruptReasonExtensionToContent( \
      api::INTERRUPT_REASON_##name), \
      content::DOWNLOAD_INTERRUPT_REASON_##name);
#include "content/public/browser/download_interrupt_reason_values.h"
#undef INTERRUPT_REASON
}

TEST(ExtensionDetermineDownloadFilenameInternal,
     ExtensionDetermineDownloadFilenameInternal) {

  std::string winner_id;
  base::FilePath filename;
  extensions::api::downloads::FilenameConflictAction conflict_action =
    api::FILENAME_CONFLICT_ACTION_UNIQUIFY;
  extensions::ExtensionWarningSet warnings;

  // Empty incumbent determiner
  warnings.clear();
  ExtensionDownloadsEventRouter::DetermineFilenameInternal(
      base::FilePath(FILE_PATH_LITERAL("a")),
      api::FILENAME_CONFLICT_ACTION_OVERWRITE,
      "suggester",
      base::Time::Now(),
      "",
      base::Time(),
      &winner_id,
      &filename,
      &conflict_action,
      &warnings);
  EXPECT_EQ("suggester", winner_id);
  EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
  EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
  EXPECT_TRUE(warnings.empty());

  // Incumbent wins
  warnings.clear();
  ExtensionDownloadsEventRouter::DetermineFilenameInternal(
      base::FilePath(FILE_PATH_LITERAL("b")),
      api::FILENAME_CONFLICT_ACTION_PROMPT,
      "suggester",
      base::Time::Now() - base::TimeDelta::FromDays(1),
      "incumbent",
      base::Time::Now(),
      &winner_id,
      &filename,
      &conflict_action,
      &warnings);
  EXPECT_EQ("incumbent", winner_id);
  EXPECT_EQ(FILE_PATH_LITERAL("a"), filename.value());
  EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_OVERWRITE, conflict_action);
  EXPECT_FALSE(warnings.empty());
  EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
            warnings.begin()->warning_type());
  EXPECT_EQ("suggester", warnings.begin()->extension_id());

  // Suggester wins
  warnings.clear();
  ExtensionDownloadsEventRouter::DetermineFilenameInternal(
      base::FilePath(FILE_PATH_LITERAL("b")),
      api::FILENAME_CONFLICT_ACTION_PROMPT,
      "suggester",
      base::Time::Now(),
      "incumbent",
      base::Time::Now() - base::TimeDelta::FromDays(1),
      &winner_id,
      &filename,
      &conflict_action,
      &warnings);
  EXPECT_EQ("suggester", winner_id);
  EXPECT_EQ(FILE_PATH_LITERAL("b"), filename.value());
  EXPECT_EQ(api::FILENAME_CONFLICT_ACTION_PROMPT, conflict_action);
  EXPECT_FALSE(warnings.empty());
  EXPECT_EQ(extensions::ExtensionWarning::kDownloadFilenameConflict,
            warnings.begin()->warning_type());
  EXPECT_EQ("incumbent", warnings.begin()->extension_id());
}
