// Copyright 2015 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 <stddef.h>
#include <utility>

#include "base/command_line.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/notifications/notification_display_service_tester.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chromeos/chromeos_switches.h"
#include "components/download/public/common/download_item.h"
#include "components/prefs/pref_service.h"
#include "components/session_manager/core/session_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager.h"
#include "content/public/test/download_test_observer.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/url_request/url_request_slow_download_job.h"
#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

enum {
  DUMMY_ACCOUNT_INDEX = 0,
  PRIMARY_ACCOUNT_INDEX = 1,
  SECONDARY_ACCOUNT_INDEX_START = 2,
};

// Structure to describe an account info.
struct TestAccountInfo {
  const char* const email;
  const char* const gaia_id;
  const char* const hash;
  const char* const display_name;
};

// Accounts for multi profile test.
static const TestAccountInfo kTestAccounts[] = {
    {"__dummy__@invalid.domain", "10000", "hashdummy", "Dummy Account"},
    {"alice@invalid.domain", "10001", "hashalice", "Alice"},
    {"bob@invalid.domain", "10002", "hashbobbo", "Bob"},
    {"charlie@invalid.domain", "10003", "hashcharl", "Charlie"},
};

class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
 public:
  explicit TestChromeDownloadManagerDelegate(Profile* profile)
      : ChromeDownloadManagerDelegate(profile), opened_(false) {}
  ~TestChromeDownloadManagerDelegate() override = default;

  // ChromeDownloadManagerDelegate override:
  void OpenDownload(download::DownloadItem* item) override { opened_ = true; }

  // Return if  the download is opened.
  bool opened() const { return opened_; }

 protected:
  // Disable DownloadProtectionService in order to disable content checking.
  safe_browsing::DownloadProtectionService* GetDownloadProtectionService()
      override {
    return nullptr;
  }

 private:
  bool opened_;
};

// Utility method to retrieve a notification object by id. Warning: this will
// check the last display service that was created. If there's a normal and an
// incognito one, you may want to be explicit.
base::Optional<message_center::Notification> GetNotification(
    const std::string& id) {
  return NotificationDisplayServiceTester::Get()->GetNotification(id);
}

// Waits for a notification to be updated/added on |display_service|.
void WaitForDownloadNotificationForDisplayService(
    NotificationDisplayServiceTester* display_service) {
  base::RunLoop run_loop;
  display_service->SetNotificationAddedClosure(base::BindRepeating(
      [](base::RunLoop* run_loop) { run_loop->Quit(); }, &run_loop));
  run_loop.Run();
  display_service->SetNotificationAddedClosure(base::RepeatingClosure());
}

}  // namespace

// Base class for tests
class DownloadNotificationTestBase : public InProcessBrowserTest {
 public:
  DownloadNotificationTestBase() = default;
  ~DownloadNotificationTestBase() override = default;

  void SetUpOnMainThread() override {
    ASSERT_TRUE(embedded_test_server()->Start());

    display_service_ = std::make_unique<NotificationDisplayServiceTester>(
        browser()->profile());

    base::PostTaskWithTraits(
        FROM_HERE, {content::BrowserThread::IO},
        base::BindOnce(&net::URLRequestSlowDownloadJob::AddUrlHandler));
  }

 protected:
  content::DownloadManager* GetDownloadManager(Browser* browser) {
    return content::BrowserContext::GetDownloadManager(browser->profile());
  }

  // Requests to complete the download and wait for it.
  void CompleteTheDownload(size_t wait_count = 1u) {
    content::DownloadTestObserverTerminal download_terminal_observer(
        GetDownloadManager(browser()), wait_count,
        content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
    ui_test_utils::NavigateToURL(
        browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
    download_terminal_observer.WaitForFinished();
  }

  std::unique_ptr<NotificationDisplayServiceTester> display_service_;
  std::unique_ptr<NotificationDisplayServiceTester> incognito_display_service_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DownloadNotificationTestBase);
};

//////////////////////////////////////////////////
// Test with a single profile
//////////////////////////////////////////////////

class DownloadNotificationTest : public DownloadNotificationTestBase {
 public:
  DownloadNotificationTest() = default;
  ~DownloadNotificationTest() override = default;

  void SetUpOnMainThread() override {
    Profile* profile = browser()->profile();

    std::unique_ptr<TestChromeDownloadManagerDelegate> test_delegate;
    test_delegate.reset(new TestChromeDownloadManagerDelegate(profile));
    test_delegate->GetDownloadIdReceiverCallback().Run(
        download::DownloadItem::kInvalidId + 1);
    DownloadCoreServiceFactory::GetForBrowserContext(profile)
        ->SetDownloadManagerDelegateForTesting(std::move(test_delegate));

    DownloadNotificationTestBase::SetUpOnMainThread();
  }

  TestChromeDownloadManagerDelegate* GetDownloadManagerDelegate() const {
    return static_cast<TestChromeDownloadManagerDelegate*>(
        DownloadCoreServiceFactory::GetForBrowserContext(browser()->profile())
            ->GetDownloadManagerDelegate());
  }

  void PrepareIncognitoBrowser() {
    incognito_browser_ = CreateIncognitoBrowser();
    Profile* incognito_profile = incognito_browser_->profile();

    std::unique_ptr<TestChromeDownloadManagerDelegate> incognito_test_delegate;
    incognito_test_delegate.reset(
        new TestChromeDownloadManagerDelegate(incognito_profile));
    DownloadCoreServiceFactory::GetForBrowserContext(incognito_profile)
        ->SetDownloadManagerDelegateForTesting(
            std::move(incognito_test_delegate));

    incognito_display_service_ =
        std::make_unique<NotificationDisplayServiceTester>(
            incognito_browser()->profile());
  }

  TestChromeDownloadManagerDelegate* GetIncognitoDownloadManagerDelegate()
      const {
    Profile* incognito_profile = incognito_browser()->profile();
    return static_cast<TestChromeDownloadManagerDelegate*>(
        DownloadCoreServiceFactory::GetForBrowserContext(incognito_profile)
            ->GetDownloadManagerDelegate());
  }

  void CreateDownload() {
    return CreateDownloadForBrowserAndURL(
        browser(), GURL(net::URLRequestSlowDownloadJob::kKnownSizeUrl));
  }

  // Returns the correct display service for the given Browser. If |browser| is
  // null, returns the service for browser().
  NotificationDisplayServiceTester* GetDisplayServiceForBrowser(
      Browser* browser) {
    return (browser && browser == DownloadNotificationTest::incognito_browser())
               ? incognito_display_service_.get()
               : display_service_.get();
  }

  void WaitForDownloadNotification(Browser* browser = nullptr) {
    WaitForDownloadNotificationForDisplayService(
        GetDisplayServiceForBrowser(browser));
  }

  void CreateDownloadForBrowserAndURL(Browser* browser, GURL url) {
    // Starts a download.
    ui_test_utils::NavigateToURL(browser, url);

    // Confirms that a notification is created.
    WaitForDownloadNotification(browser);
    auto download_notifications =
        GetDisplayServiceForBrowser(browser)->GetDisplayedNotificationsForType(
            NotificationHandler::Type::TRANSIENT);
    ASSERT_EQ(1u, download_notifications.size());
    notification_id_ = download_notifications[0].id();
    EXPECT_FALSE(notification_id_.empty());
    ASSERT_TRUE(notification());

    // Confirms that a download is also started.
    std::vector<download::DownloadItem*> downloads;
    GetDownloadManager(browser)->GetAllDownloads(&downloads);
    EXPECT_EQ(1u, downloads.size());
    download_item_ = downloads[0];
    ASSERT_TRUE(download_item_);
  }

  void CloseNotification() {
    EXPECT_TRUE(notification());
    display_service_->RemoveNotification(NotificationHandler::Type::TRANSIENT,
                                         notification_id(), true /* by_user */);
    EXPECT_FALSE(notification());
    EXPECT_EQ(0u, GetDownloadNotifications().size());
  }

  void VerifyDownloadState(download::DownloadItem::DownloadState state) {
    std::vector<download::DownloadItem*> downloads;
    GetDownloadManager(browser())->GetAllDownloads(&downloads);
    ASSERT_EQ(1u, downloads.size());
    EXPECT_EQ(state, downloads[0]->GetState());
  }

  void VerifyUpdatePropagatesToNotification(download::DownloadItem* item) {
    bool notification_updated = false;
    display_service_->SetNotificationAddedClosure(base::BindRepeating(
        [](bool* updated) { *updated = true; }, &notification_updated));
    item->UpdateObservers();
    EXPECT_TRUE(notification_updated);
    display_service_->SetNotificationAddedClosure(base::RepeatingClosure());
  }

  void InterruptTheDownload() {
    content::DownloadTestObserverInterrupted download_interrupted_observer(
        GetDownloadManager(browser()), 1u, /* wait_count */
        content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
    ui_test_utils::NavigateToURL(
        browser(), GURL(net::URLRequestSlowDownloadJob::kErrorDownloadUrl));
    download_interrupted_observer.WaitForFinished();
  }

  download::DownloadItem* download_item() const { return download_item_; }
  std::string notification_id() const { return notification_id_; }
  base::Optional<message_center::Notification> notification() const {
    return GetNotification(notification_id_);
  }
  Browser* incognito_browser() const { return incognito_browser_; }
  base::FilePath GetDownloadPath() {
    return DownloadPrefs::FromDownloadManager(GetDownloadManager(browser()))
        ->DownloadPath();
  }
  std::vector<message_center::Notification> GetDownloadNotifications() {
    return display_service_->GetDisplayedNotificationsForType(
        NotificationHandler::Type::TRANSIENT);
  }

 private:
  download::DownloadItem* download_item_ = nullptr;
  Browser* incognito_browser_ = nullptr;
  std::string notification_id_;

  DISALLOW_COPY_AND_ASSIGN(DownloadNotificationTest);
};

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadFile) {
  CreateDownload();

  EXPECT_EQ(l10n_util::GetStringFUTF16(
                IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE,
                download_item()->GetFileNameToReportUser().LossyDisplayName()),
            notification()->title());
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS, notification()->type());

  // Confirms that the download update is delivered to the notification.
  EXPECT_TRUE(notification());
  VerifyUpdatePropagatesToNotification(download_item());

  CompleteTheDownload();

  // Checks strings.
  ASSERT_TRUE(notification());
  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_COMPLETE_TITLE),
            notification()->title());
  EXPECT_EQ(download_item()->GetFileNameToReportUser().LossyDisplayName(),
            notification()->message());
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            notification()->type());

  // Confirms that there is only one notification.
  ASSERT_EQ(1u, GetDownloadNotifications().size());

  // Try to open the downloaded item by clicking the notification.
  EXPECT_FALSE(GetDownloadManagerDelegate()->opened());
  display_service_->SimulateClick(NotificationHandler::Type::TRANSIENT,
                                  notification_id(), base::nullopt,
                                  base::nullopt);
  EXPECT_TRUE(GetDownloadManagerDelegate()->opened());

  EXPECT_FALSE(GetNotification(notification_id()));
}

// Flaky test: crbug/822470.
IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       DISABLED_DownloadDangerousFile) {
  GURL download_url(
      embedded_test_server()->GetURL("/downloads/dangerous/dangerous.swf"));

  content::DownloadTestObserverTerminal download_terminal_observer(
      GetDownloadManager(browser()), 1u, /* wait_count */
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE);

  CreateDownloadForBrowserAndURL(browser(), download_url);

  base::FilePath filename = download_item()->GetFileNameToReportUser();

  // Checks the download status.
  EXPECT_EQ(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
            download_item()->GetDangerType());
  EXPECT_TRUE(download_item()->IsDangerous());

  // Clicks the "keep" button.
  display_service_->SimulateClick(NotificationHandler::Type::TRANSIENT,
                                  notification_id(), 1,  // 2nd button: "Keep"
                                  base::nullopt);

  // The notification is closed and re-shown.
  EXPECT_TRUE(notification());

  // Checks the download status.
  EXPECT_EQ(download::DOWNLOAD_DANGER_TYPE_USER_VALIDATED,
            download_item()->GetDangerType());
  EXPECT_FALSE(download_item()->IsDangerous());

  // Wait for the download completion.
  download_terminal_observer.WaitForFinished();

  // Checks the download status.
  EXPECT_FALSE(download_item()->IsDangerous());
  EXPECT_EQ(download::DownloadItem::COMPLETE, download_item()->GetState());

  // Checks the downloaded file.
  EXPECT_TRUE(base::PathExists(GetDownloadPath().Append(filename.BaseName())));
}

// Disabled due to timeouts; see https://crbug.com/810302.
IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       DISABLED_DiscardDangerousFile) {
  GURL download_url(
      embedded_test_server()->GetURL("/downloads/dangerous/dangerous.swf"));

  content::DownloadTestObserverTerminal download_terminal_observer(
      GetDownloadManager(browser()), 1u, /* wait_count */
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE);

  CreateDownloadForBrowserAndURL(browser(), download_url);

  base::FilePath filename = download_item()->GetFileNameToReportUser();

  // Checks the download status.
  EXPECT_EQ(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
            download_item()->GetDangerType());
  EXPECT_TRUE(download_item()->IsDangerous());

  // Ensures the notification exists.
  EXPECT_TRUE(notification());

  // Clicks the "Discard" button.
  display_service_->SimulateClick(NotificationHandler::Type::TRANSIENT,
                                  notification_id(),
                                  0,  // 1st button: "Discard"
                                  base::nullopt);

  EXPECT_FALSE(notification());

  // Wait for the download completion.
  download_terminal_observer.WaitForFinished();

  // Checks there is neither any download nor any notification.
  EXPECT_FALSE(notification());
  EXPECT_EQ(0u, GetDownloadNotifications().size());
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(0u, downloads.size());

  // Checks the downloaded file doesn't exist.
  EXPECT_FALSE(base::PathExists(GetDownloadPath().Append(filename.BaseName())));
}

// Disabled due to timeouts; see https://crbug.com/810302.
IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DISABLED_DownloadImageFile) {
  GURL download_url(
      embedded_test_server()->GetURL("/downloads/image-octet-stream.png"));

  content::DownloadTestObserverTerminal download_terminal_observer(
      GetDownloadManager(browser()), 1u, /* wait_count */
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_IGNORE);

  CreateDownloadForBrowserAndURL(browser(), download_url);

  // Wait for the download completion.
  download_terminal_observer.WaitForFinished();

  WaitForDownloadNotification();
  EXPECT_FALSE(notification()->image().IsEmpty());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       CloseNotificationAfterDownload) {
  CreateDownload();

  CompleteTheDownload();

  CloseNotification();

  VerifyDownloadState(download::DownloadItem::COMPLETE);
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       CloseNotificationWhileDownloading) {
  CreateDownload();

  CloseNotification();

  VerifyDownloadState(download::DownloadItem::IN_PROGRESS);

  CompleteTheDownload();

  EXPECT_TRUE(notification());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, InterruptDownload) {
  CreateDownload();

  InterruptTheDownload();

  EXPECT_EQ(1u, GetDownloadNotifications().size());
  ASSERT_TRUE(notification());

  // Checks strings.
  EXPECT_EQ(l10n_util::GetStringFUTF16(
                IDS_DOWNLOAD_STATUS_DOWNLOAD_FAILED_TITLE,
                download_item()->GetFileNameToReportUser().LossyDisplayName()),
            notification()->title());
  EXPECT_NE(notification()->message().find(l10n_util::GetStringFUTF16(
                IDS_DOWNLOAD_STATUS_INTERRUPTED,
                l10n_util::GetStringUTF16(
                    IDS_DOWNLOAD_INTERRUPTED_DESCRIPTION_NETWORK_ERROR))),
            std::string::npos);
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            notification()->type());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       InterruptDownloadAfterClosingNotification) {
  CreateDownload();

  CloseNotification();

  // Confirms that a download is still in progress.
  std::vector<download::DownloadItem*> downloads;
  content::DownloadManager* download_manager = GetDownloadManager(browser());
  download_manager->GetAllDownloads(&downloads);
  EXPECT_EQ(1u, downloads.size());
  EXPECT_EQ(download::DownloadItem::IN_PROGRESS, downloads[0]->GetState());

  // Installs observers before requesting the completion.
  content::DownloadTestObserverInterrupted download_terminal_observer(
      download_manager, 1u, /* wait_count */
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);

  InterruptTheDownload();

  // Confirms that there is only one notification.
  EXPECT_EQ(1u, GetDownloadNotifications().size());
  ASSERT_TRUE(notification());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadRemoved) {
  CreateDownload();

  EXPECT_TRUE(notification());
  download_item()->Remove();
  EXPECT_FALSE(notification());

  // Confirms that the download item is removed.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(0u, downloads.size());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadMultipleFiles) {
  GURL url1(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
  GURL url2(net::URLRequestSlowDownloadJob::kKnownSizeUrl);

  // Starts the 1st download.
  ui_test_utils::NavigateToURL(browser(), url1);
  WaitForDownloadNotification();
  auto notifications = GetDownloadNotifications();
  ASSERT_EQ(1u, notifications.size());
  std::string notification_id1 = notifications[0].id();
  EXPECT_FALSE(notification_id1.empty());

  // Confirms that there is a download.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());
  download::DownloadItem* download1 = downloads[0];

  // Starts the 2nd download.
  ui_test_utils::NavigateToURL(browser(), url2);
  WaitForDownloadNotification();

  // Confirms that there are 2 downloads.
  downloads.clear();
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  ASSERT_EQ(2u, downloads.size());
  download::DownloadItem* download2;
  if (download1 == downloads[0])
    download2 = downloads[1];
  else if (download1 == downloads[1])
    download2 = downloads[0];
  else
    NOTREACHED();
  EXPECT_NE(download1, download2);

  notifications = GetDownloadNotifications();
  // Confirms that there are 2 notifications.
  EXPECT_EQ(2u, notifications.size());

  std::string notification_id2;
  for (const auto& notification : notifications) {
    if (notification.id() == notification_id1)
      continue;

    notification_id2 = notification.id();
  }
  EXPECT_FALSE(notification_id2.empty());

  // Confirms that the old one is low priority, and the new one is default.
  EXPECT_EQ(message_center::LOW_PRIORITY,
            GetNotification(notification_id1)->priority());
  EXPECT_EQ(message_center::DEFAULT_PRIORITY,
            GetNotification(notification_id2)->priority());

  // Confirms that the updates of both download are delivered to the
  // notifications.
  VerifyUpdatePropagatesToNotification(download1);
  VerifyUpdatePropagatesToNotification(download2);

  // Confirms the correct type of notification while download is in progress.
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
            GetNotification(notification_id1)->type());
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
            GetNotification(notification_id2)->type());

  // Requests to complete the downloads.
  CompleteTheDownload(2);

  // Confirms that the both notifications are visible.
  notifications = GetDownloadNotifications();
  EXPECT_EQ(2u, notifications.size());
  ASSERT_TRUE(GetNotification(notification_id1));
  ASSERT_TRUE(GetNotification(notification_id2));

  // Confirms that both ask to be re-shown when finished.
  EXPECT_TRUE(GetNotification(notification_id1)->renotify());
  EXPECT_TRUE(GetNotification(notification_id2)->renotify());

  // Confirms that both are default priority after finishing.
  EXPECT_EQ(message_center::DEFAULT_PRIORITY,
            GetNotification(notification_id1)->priority());
  EXPECT_EQ(message_center::DEFAULT_PRIORITY,
            GetNotification(notification_id2)->priority());

  // Confirms the types of download notifications are correct.
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            GetNotification(notification_id1)->type());
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            GetNotification(notification_id2)->type());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       DownloadMultipleFilesOneByOne) {
  CreateDownload();
  download::DownloadItem* first_download_item = download_item();
  std::string first_notification_id = notification_id();

  CompleteTheDownload();
  EXPECT_EQ(download::DownloadItem::COMPLETE, first_download_item->GetState());

  // Checks the message center.
  EXPECT_TRUE(notification());

  // Starts the second download.
  GURL url(net::URLRequestSlowDownloadJob::kKnownSizeUrl);
  ui_test_utils::NavigateToURL(browser(), url);
  WaitForDownloadNotification();

  // Confirms that the second notification is created.
  auto notifications = GetDownloadNotifications();
  ASSERT_EQ(2u, notifications.size());
  std::string second_notification_id =
      notifications[(notifications[0].id() == notification_id() ? 1 : 0)].id();
  EXPECT_FALSE(second_notification_id.empty());
  ASSERT_TRUE(GetNotification(second_notification_id));

  // Confirms that the second download is also started.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(2u, downloads.size());
  EXPECT_TRUE(first_download_item == downloads[0] ||
              first_download_item == downloads[1]);
  download::DownloadItem* second_download_item =
      downloads[first_download_item == downloads[0] ? 1 : 0];

  EXPECT_EQ(download::DownloadItem::IN_PROGRESS,
            second_download_item->GetState());

  // Requests to complete the second download.
  CompleteTheDownload();

  EXPECT_EQ(2u, GetDownloadNotifications().size());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, CancelDownload) {
  CreateDownload();

  // Cancels the notification by clicking the "cancel" button.
  display_service_->SimulateClick(NotificationHandler::Type::TRANSIENT,
                                  notification_id(), 1, base::nullopt);
  EXPECT_FALSE(notification());
  EXPECT_EQ(0u, GetDownloadNotifications().size());

  // Confirms that the download is cancelled.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());
  EXPECT_EQ(download::DownloadItem::CANCELLED, downloads[0]->GetState());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       DownloadCancelledByUserExternally) {
  CreateDownload();

  // Cancels the notification through the DownloadItem.
  download_item()->Cancel(true /* by_user */);
  EXPECT_FALSE(notification());
  EXPECT_EQ(0u, GetDownloadNotifications().size());

  // Confirms that the download is cancelled.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(1u, downloads.size());
  EXPECT_EQ(download::DownloadItem::CANCELLED, downloads[0]->GetState());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, IncognitoDownloadFile) {
  PrepareIncognitoBrowser();

  // Starts an incognito download.
  CreateDownloadForBrowserAndURL(
      incognito_browser(), GURL(net::URLRequestSlowDownloadJob::kKnownSizeUrl));

  EXPECT_EQ(l10n_util::GetStringFUTF16(
                IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE,
                download_item()->GetFileNameToReportUser().LossyDisplayName()),
            notification()->title());
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS, notification()->type());
  EXPECT_TRUE(content::DownloadItemUtils::GetBrowserContext(download_item())
                  ->IsOffTheRecord());

  // Requests to complete the download.
  content::DownloadTestObserverTerminal download_terminal_observer(
      GetDownloadManager(incognito_browser()), 1,
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
  ui_test_utils::NavigateToURL(
      incognito_browser(),
      GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
  download_terminal_observer.WaitForFinished();

  EXPECT_EQ(l10n_util::GetStringUTF16(IDS_DOWNLOAD_STATUS_COMPLETE_TITLE),
            notification()->title());
  EXPECT_EQ(download_item()->GetFileNameToReportUser().LossyDisplayName(),
            notification()->message());
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            notification()->type());

  // Try to open the downloaded item by clicking the notification.
  EXPECT_TRUE(incognito_display_service_->GetNotification(notification_id()));
  EXPECT_FALSE(GetIncognitoDownloadManagerDelegate()->opened());
  incognito_display_service_->SimulateClick(
      NotificationHandler::Type::TRANSIENT, notification_id(), base::nullopt,
      base::nullopt);
  EXPECT_TRUE(GetIncognitoDownloadManagerDelegate()->opened());
  EXPECT_FALSE(GetDownloadManagerDelegate()->opened());

  EXPECT_FALSE(incognito_display_service_->GetNotification(notification_id()));
  chrome::CloseWindow(incognito_browser());
}

IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
                       SimultaneousIncognitoAndNormalDownloads) {
  PrepareIncognitoBrowser();

  GURL url_incognito(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
  GURL url_normal(net::URLRequestSlowDownloadJob::kKnownSizeUrl);

  // Starts the incognito download.
  ui_test_utils::NavigateToURL(incognito_browser(), url_incognito);
  WaitForDownloadNotification(incognito_browser());
  auto incognito_notifications =
      incognito_display_service_->GetDisplayedNotificationsForType(
          NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(1u, incognito_notifications.size());
  std::string notification_id1 = incognito_notifications[0].id();
  EXPECT_FALSE(notification_id1.empty());

  // Confirms that there is a download.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(0u, downloads.size());
  downloads.clear();
  GetDownloadManager(incognito_browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(1u, downloads.size());
  download::DownloadItem* download_incognito = downloads[0];

  // Starts the normal download.
  ui_test_utils::NavigateToURL(browser(), url_normal);
  WaitForDownloadNotification();
  auto normal_notifications = GetDownloadNotifications();
  ASSERT_EQ(1u, normal_notifications.size());
  std::string notification_id2 = normal_notifications[0].id();
  EXPECT_FALSE(notification_id2.empty());

  // Confirms that there are 2 downloads.
  downloads.clear();
  GetDownloadManager(browser())->GetAllDownloads(&downloads);
  download::DownloadItem* download_normal = downloads[0];
  EXPECT_EQ(1u, downloads.size());
  EXPECT_NE(download_normal, download_incognito);
  downloads.clear();
  GetDownloadManager(incognito_browser())->GetAllDownloads(&downloads);
  EXPECT_EQ(1u, downloads.size());
  EXPECT_EQ(download_incognito, downloads[0]);

  // Confirms the types of download notifications are correct.
  auto incognito_notification =
      incognito_display_service_->GetNotification(notification_id1);
  ASSERT_TRUE(incognito_notification);
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
            incognito_notification->type());
  EXPECT_EQ(-1, incognito_notification->progress());

  auto normal_notification =
      display_service_->GetNotification(notification_id2);
  ASSERT_TRUE(normal_notification);
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
            normal_notification->type());
  EXPECT_LE(0, normal_notification->progress());

  EXPECT_TRUE(content::DownloadItemUtils::GetBrowserContext(download_incognito)
                  ->IsOffTheRecord());
  EXPECT_FALSE(content::DownloadItemUtils::GetBrowserContext(download_normal)
                   ->IsOffTheRecord());

  // Request to complete the normal download.
  CompleteTheDownload();

  // Confirms the types of download notifications are correct.
  incognito_notification =
      incognito_display_service_->GetNotification(notification_id1);
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            incognito_notification->type());
  normal_notification = display_service_->GetNotification(notification_id2);
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            normal_notification->type());

  chrome::CloseWindow(incognito_browser());
}

//////////////////////////////////////////////////
// Test with multi profiles
//////////////////////////////////////////////////

class MultiProfileDownloadNotificationTest
    : public DownloadNotificationTestBase {
 public:
  MultiProfileDownloadNotificationTest() = default;
  ~MultiProfileDownloadNotificationTest() override = default;

  void SetUpCommandLine(base::CommandLine* command_line) override {
    DownloadNotificationTestBase::SetUpCommandLine(command_line);

    // Logs in to a dummy profile.
    command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
                                    kTestAccounts[DUMMY_ACCOUNT_INDEX].email);
    command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
                                    kTestAccounts[DUMMY_ACCOUNT_INDEX].hash);
    // Don't require policy for our sessions - this is required because
    // this test creates a secondary profile synchronously, so we need to
    // let the policy code know not to expect cached policy.
    command_line->AppendSwitchASCII(chromeos::switches::kProfileRequiresPolicy,
                                    "false");
  }

  // Logs in to the primary profile.
  void SetUpOnMainThread() override {
    const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX];

    AddUser(info, true);
    DownloadNotificationTestBase::SetUpOnMainThread();
  }

  // Loads all users to the current session and sets up necessary fields.
  // This is used for preparing all accounts in PRE_ test setup, and for testing
  // actual login behavior.
  void AddAllUsers() {
    for (size_t i = 0; i < base::size(kTestAccounts); ++i) {
      // The primary account was already set up in SetUpOnMainThread, so skip it
      // here.
      if (i == PRIMARY_ACCOUNT_INDEX)
        continue;
      AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
    }
  }

  Profile* GetProfileByIndex(int index) {
    return chromeos::ProfileHelper::GetProfileByUserIdHashForTest(
        kTestAccounts[index].hash);
  }

  // Adds a new user for testing to the current session.
  void AddUser(const TestAccountInfo& info, bool log_in) {
    if (log_in) {
      session_manager::SessionManager::Get()->CreateSession(
          AccountId::FromUserEmailGaiaId(info.email, info.gaia_id), info.hash,
          false);
    }
    user_manager::UserManager::Get()->SaveUserDisplayName(
        AccountId::FromUserEmailGaiaId(info.email, info.gaia_id),
        base::UTF8ToUTF16(info.display_name));
    Profile* profile =
        chromeos::ProfileHelper::GetProfileByUserIdHashForTest(info.hash);

    identity::IdentityManager* identity_manager =
        IdentityManagerFactory::GetForProfile(profile);
    if (!identity_manager->HasPrimaryAccount())
      identity::MakePrimaryAccountAvailable(identity_manager, info.email);
  }

  std::unique_ptr<NotificationDisplayServiceTester> display_service1_;
  std::unique_ptr<NotificationDisplayServiceTester> display_service2_;

 private:
  DISALLOW_COPY_AND_ASSIGN(MultiProfileDownloadNotificationTest);
};

IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest,
                       PRE_DownloadMultipleFiles) {
  AddAllUsers();
}

IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest,
                       DownloadMultipleFiles) {
  AddAllUsers();

  GURL url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);

  Profile* profile1 = GetProfileByIndex(1);
  Profile* profile2 = GetProfileByIndex(2);
  Browser* browser1 = CreateBrowser(profile1);
  Browser* browser2 = CreateBrowser(profile2);
  EXPECT_NE(browser1, browser2);

  display_service1_ =
      std::make_unique<NotificationDisplayServiceTester>(profile1);
  display_service2_ =
      std::make_unique<NotificationDisplayServiceTester>(profile2);

  // First user starts a download.
  ui_test_utils::NavigateToURL(browser1, url);
  WaitForDownloadNotificationForDisplayService(display_service1_.get());

  // Confirms that the download is started.
  std::vector<download::DownloadItem*> downloads;
  GetDownloadManager(browser1)->GetAllDownloads(&downloads);
  EXPECT_EQ(1u, downloads.size());
  download::DownloadItem* download1 = downloads[0];

  // Confirms that a download notification is generated.
  auto notifications1 = display_service1_->GetDisplayedNotificationsForType(
      NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(1u, notifications1.size());
  std::string notification_id_user1 = notifications1[0].id();
  EXPECT_FALSE(notification_id_user1.empty());

  // Second user starts a download.
  ui_test_utils::NavigateToURL(browser2, url);
  WaitForDownloadNotificationForDisplayService(display_service2_.get());
  auto notifications2 = display_service2_->GetDisplayedNotificationsForType(
      NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(1u, notifications2.size());
  std::string notification_id_user2 = notifications2[0].id();
  EXPECT_FALSE(notification_id_user2.empty());

  // Confirms that the second user has only 1 download.
  downloads.clear();
  GetDownloadManager(browser2)->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());

  // Second user starts another download.
  ui_test_utils::NavigateToURL(browser2, url);
  WaitForDownloadNotificationForDisplayService(display_service2_.get());
  notifications2 = display_service2_->GetDisplayedNotificationsForType(
      NotificationHandler::Type::TRANSIENT);
  ASSERT_EQ(2u, notifications2.size());

  // Confirms that the second user has 2 downloads.
  downloads.clear();
  GetDownloadManager(browser2)->GetAllDownloads(&downloads);
  ASSERT_EQ(2u, downloads.size());
  download::DownloadItem* download2 = downloads[0];
  download::DownloadItem* download3 = downloads[1];
  EXPECT_NE(download1, download2);
  EXPECT_NE(download1, download3);
  EXPECT_NE(download2, download3);

  // Confirms that the first user still has only 1 download.
  downloads.clear();
  GetDownloadManager(browser1)->GetAllDownloads(&downloads);
  ASSERT_EQ(1u, downloads.size());
  EXPECT_EQ(download1, downloads[0]);

  // Confirms the types of download notifications are correct.
  // Normal notification for user1.
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
            display_service1_->GetNotification(notification_id_user1)->type());
  EXPECT_EQ(
      -1,
      display_service1_->GetNotification(notification_id_user1)->progress());
  // Normal notifications for user2.
  notifications2 = display_service2_->GetDisplayedNotificationsForType(
      NotificationHandler::Type::TRANSIENT);
  EXPECT_EQ(2u, notifications2.size());
  for (const auto& notification : notifications2) {
    EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS, notification.type());
    EXPECT_EQ(-1, notification.progress());
  }

  // Requests to complete the downloads.
  content::DownloadTestObserverTerminal download_terminal_observer(
      GetDownloadManager(browser1), 1u /* wait_count */,
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
  content::DownloadTestObserverTerminal download_terminal_observer2(
      GetDownloadManager(browser2), 2u /* wait_count */,
      content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL);
  ui_test_utils::NavigateToURL(
      browser1, GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
  ui_test_utils::NavigateToURL(
      browser2, GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
  download_terminal_observer.WaitForFinished();
  download_terminal_observer2.WaitForFinished();

  // Confirms the types of download notifications are correct.
  EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
            display_service1_->GetNotification(notification_id_user1)->type());
  notifications2 = display_service2_->GetDisplayedNotificationsForType(
      NotificationHandler::Type::TRANSIENT);
  EXPECT_EQ(2u, notifications2.size());
  for (const auto& notification : notifications2) {
    EXPECT_EQ(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
              notification.type());
  }
}
