Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5158)

Unified Diff: chrome/browser/download/notification/download_notification_browsertest.cc

Issue 1047243002: Add initial browsertest of download notification (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make the test runs only in chromeos build Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/download/notification/download_notification_browsertest.cc
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..287bbbd453645d4a8b3a77f0f4d24ca61e087612
--- /dev/null
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -0,0 +1,501 @@
+// 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 "base/command_line.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/chromeos/profiles/profile_helper.h"
+#include "chrome/browser/download/chrome_download_manager_delegate.h"
+#include "chrome/browser/download/download_service.h"
+#include "chrome/browser/download/download_service_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/grit/chromium_strings.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/signin/core/browser/signin_manager_base.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/download_item.h"
+#include "content/public/browser/download_manager.h"
+#include "grit/theme_resources.h"
+#include "net/test/url_request/url_request_slow_download_job.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/message_center/message_center.h"
+#include "ui/message_center/message_center_observer.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"},
+};
+
+// Base class observing notification events.
+class MessageCenterChangeObserver
+ : public message_center::MessageCenterObserver {
+ public:
+ MessageCenterChangeObserver() {
+ message_center::MessageCenter::Get()->AddObserver(this);
+ }
+
+ ~MessageCenterChangeObserver() override {
+ message_center::MessageCenter::Get()->RemoveObserver(this);
+ }
+
+ protected:
+ void RunLoop() {
+ base::MessageLoop::ScopedNestableTaskAllower allow(
+ base::MessageLoop::current());
+ run_loop_.Run();
+ }
+
+ void QuitRunLoop() {
+ run_loop_.Quit();
+ }
+
+ private:
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(MessageCenterChangeObserver);
+};
+
+// Class observing of "ADD" notification events.
+class NotificationAddObserver : public MessageCenterChangeObserver {
+ public:
+ NotificationAddObserver() : count_(1) {
+ MessageCenterChangeObserver();
+ }
+ explicit NotificationAddObserver(int count) : count_(count) {
+ MessageCenterChangeObserver();
+ }
+ ~NotificationAddObserver() override {}
+
+ bool Wait() {
+ if (count_ <= 0)
+ return count_ == 0;
+
+ waiting_ = true;
+ RunLoop();
+ waiting_ = false;
+ return count_ == 0;
+ }
+
+ // message_center::MessageCenterObserver:
+ void OnNotificationAdded(const std::string& notification_id) override {
+ count_--;
+
+ if (notification_id_.empty())
+ notification_id_ = notification_id;
+
+ if (waiting_)
+ QuitRunLoop();
+ }
+
+ std::string notification_id() { return notification_id_; }
+
+ private:
+ std::string notification_id_;
+ bool waiting_ = false;
+ int count_;
+
+ DISALLOW_COPY_AND_ASSIGN(NotificationAddObserver);
+};
+
+// Class observing of "UPDATE" notification events.
+class NotificationUpdateObserver : public MessageCenterChangeObserver {
+ public:
+ NotificationUpdateObserver() : waiting_(false) {
+ MessageCenterChangeObserver();
Nico 2015/05/22 18:41:48 This is not how you call a superclass constructor.
+ }
+ ~NotificationUpdateObserver() override {}
+
+ std::string Wait() {
+ if (!notification_id_.empty())
+ return notification_id_;
+
+ waiting_ = true;
+ RunLoop();
+ waiting_ = false;
+ return notification_id_;
+ }
+
+ void OnNotificationUpdated(const std::string& notification_id) override {
+ if (notification_id_.empty()) {
+ notification_id_ = notification_id;
+
+ if (waiting_)
+ QuitRunLoop();
+ }
+ }
+
+ private:
+ std::string notification_id_;
+ bool waiting_;
+
+ DISALLOW_COPY_AND_ASSIGN(NotificationUpdateObserver);
+};
+
+class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
+ public:
+ explicit TestChromeDownloadManagerDelegate(Profile* profile)
+ : ChromeDownloadManagerDelegate(profile), opened_(false) {}
+ ~TestChromeDownloadManagerDelegate() override {}
+
+ // ChromeDownloadManagerDelegate override:
+ void OpenDownload(content::DownloadItem* item) override { opened_ = true; }
+
+ // Return if the download is opened.
+ bool opened() const { return opened_; }
+
+ private:
+ bool opened_;
+};
+
+// Utility method to retrieve a message center.
+message_center::MessageCenter* GetMessageCenter() {
+ return message_center::MessageCenter::Get();
+}
+
+// Utility method to retrieve a notification object by id.
+message_center::Notification* GetNotification(const std::string& id) {
+ return GetMessageCenter()->FindVisibleNotificationById(id);
+}
+
+} // anonnymous namespace
+
+// Base class for tests
+class DownloadNotificationTestBase : public InProcessBrowserTest {
+ public:
+ ~DownloadNotificationTestBase() override {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ // TODO(yoshiki): Remove this after the download notification launches.
+ command_line->AppendSwitch(switches::kEnableDownloadNotification);
+ }
+
+ void SetUpOnMainThread() override {
+ content::BrowserThread::PostTask(
+ content::BrowserThread::IO, FROM_HERE,
+ base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler));
+ }
+
+ content::DownloadManager* GetDownloadManager(Browser* browser) {
+ return content::BrowserContext::GetDownloadManager(browser->profile());
+ }
+};
+
+//////////////////////////////////////////////////
+// Test with a single profile
+//////////////////////////////////////////////////
+
+class DownloadNotificationTest : public DownloadNotificationTestBase {
+ public:
+ ~DownloadNotificationTest() override {}
+
+ void SetUpOnMainThread() override {
+ Profile* profile = browser()->profile();
+
+ scoped_ptr<TestChromeDownloadManagerDelegate> test_delegate;
+ test_delegate.reset(new TestChromeDownloadManagerDelegate(profile));
+ test_delegate->GetDownloadIdReceiverCallback().Run(
+ content::DownloadItem::kInvalidId + 1);
+
+ DownloadServiceFactory::GetForBrowserContext(profile)
+ ->SetDownloadManagerDelegateForTesting(test_delegate.Pass());
+
+ DownloadNotificationTestBase::SetUpOnMainThread();
+ }
+
+ TestChromeDownloadManagerDelegate* GetDownloadManagerDelegate() const {
+ return static_cast<TestChromeDownloadManagerDelegate*>(
+ DownloadServiceFactory::GetForBrowserContext(browser()->profile())
+ ->GetDownloadManagerDelegate());
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadFile) {
+ GURL url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
+
+ // Starts a download.
+ NotificationAddObserver download_start_notification_observer;
+ ui_test_utils::NavigateToURL(browser(), url);
+ EXPECT_TRUE(download_start_notification_observer.Wait());
+
+ // Confirms that a notification is created.
+ std::string notification_id =
+ download_start_notification_observer.notification_id();
+ EXPECT_FALSE(notification_id.empty());
+
+ // Confirms that a download is also started.
+ std::vector<content::DownloadItem*> downloads;
+ GetDownloadManager(browser())->GetAllDownloads(&downloads);
+ EXPECT_EQ(1u, downloads.size());
+ content::DownloadItem* download = downloads[0];
+
+ EXPECT_EQ(l10n_util::GetStringFUTF16(
+ IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE,
+ download->GetFileNameToReportUser().LossyDisplayName()),
+ GetNotification(notification_id)->title());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
+ GetNotification(notification_id)->type());
+
+ // Requests to complete the download.
+ ui_test_utils::NavigateToURL(
+ browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
+
+ // Waits for download completion.
+ while (download->GetState() != content::DownloadItem::COMPLETE) {
+ NotificationUpdateObserver download_change_notification_observer;
+ download_change_notification_observer.Wait();
+ }
+
+ EXPECT_EQ(l10n_util::GetStringFUTF16(
+ IDS_DOWNLOAD_STATUS_DOWNLOADED_TITLE,
+ download->GetFileNameToReportUser().LossyDisplayName()),
+ GetNotification(notification_id)->title());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
+ GetNotification(notification_id)->type());
+
+ // Try to open the downloaded item by clicking the notification.
+ EXPECT_FALSE(GetDownloadManagerDelegate()->opened());
+ GetMessageCenter()->ClickOnNotification(notification_id);
+ EXPECT_TRUE(GetDownloadManagerDelegate()->opened());
+
+ EXPECT_FALSE(GetNotification(notification_id));
+}
+
+IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadMultipleFiles) {
+ GURL url1(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
+ GURL url2(net::URLRequestSlowDownloadJob::kKnownSizeUrl);
+
+ // Starts the 1st download.
+ NotificationAddObserver download_start_notification_observer1;
+ ui_test_utils::NavigateToURL(browser(), url1);
+ EXPECT_TRUE(download_start_notification_observer1.Wait());
+ std::string notification_id1 =
+ download_start_notification_observer1.notification_id();
+ EXPECT_FALSE(notification_id1.empty());
+
+ // Confirms that there is a download.
+ std::vector<content::DownloadItem*> downloads;
+ GetDownloadManager(browser())->GetAllDownloads(&downloads);
+ EXPECT_EQ(1u, downloads.size());
+ content::DownloadItem* download1or2 = downloads[0];
+
+ // Starts the 2nd download.
+ NotificationAddObserver download_start_notification_observer2;
+ ui_test_utils::NavigateToURL(browser(), url2);
+ EXPECT_TRUE(download_start_notification_observer2.Wait());
+ std::string notification_id2 =
+ download_start_notification_observer2.notification_id();
+ EXPECT_FALSE(notification_id2.empty());
+
+ // Confirms that there are 2 downloads.
+ downloads.clear();
+ GetDownloadManager(browser())->GetAllDownloads(&downloads);
+ content::DownloadItem* download1 = downloads[0];
+ content::DownloadItem* download2 = downloads[1];
+ EXPECT_EQ(2u, downloads.size());
+ EXPECT_NE(download1, download2);
+ EXPECT_TRUE(download1 == download1or2 || download2 == download1or2);
+
+ // Confirms the types of download notifications are correct.
+ 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.
+ ui_test_utils::NavigateToURL(
+ browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
+
+ // Waits for the completion of downloads.
+ while (download1->GetState() != content::DownloadItem::COMPLETE ||
+ download2->GetState() != content::DownloadItem::COMPLETE) {
+ NotificationUpdateObserver download_change_notification_observer;
+ download_change_notification_observer.Wait();
+ }
+
+ // Confirms the types of download notifications are correct.
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
+ GetNotification(notification_id1)->type());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
+ GetNotification(notification_id2)->type());
+}
+
+//////////////////////////////////////////////////
+// Test with multi profiles
+//////////////////////////////////////////////////
+
+class MultiProfileDownloadNotificationTest
+ : public DownloadNotificationTestBase {
+ public:
+ ~MultiProfileDownloadNotificationTest() override {}
+
+ 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);
+ }
+
+ // 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 < arraysize(kTestAccounts); ++i)
+ AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
+ }
+
+ Profile* GetProfileByIndex(int index) {
+ return chromeos::ProfileHelper::GetProfileByUserIdHash(
+ kTestAccounts[index].hash);
+ }
+
+ // Adds a new user for testing to the current session.
+ void AddUser(const TestAccountInfo& info, bool log_in) {
+ user_manager::UserManager* const user_manager =
+ user_manager::UserManager::Get();
+ if (log_in)
+ user_manager->UserLoggedIn(info.email, info.hash, false);
+ user_manager->SaveUserDisplayName(info.email,
+ base::UTF8ToUTF16(info.display_name));
+ SigninManagerFactory::GetForProfile(
+ chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash))
+ ->SetAuthenticatedAccountInfo(info.gaia_id, info.email);
+ }
+};
+
+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);
+
+ // First user starts a download.
+ NotificationAddObserver download_start_notification_observer1;
+ ui_test_utils::NavigateToURL(browser1, url);
+ download_start_notification_observer1.Wait();
+
+ // Confirms that the download is started.
+ std::vector<content::DownloadItem*> downloads;
+ GetDownloadManager(browser1)->GetAllDownloads(&downloads);
+ EXPECT_EQ(1u, downloads.size());
+ content::DownloadItem* download1 = downloads[0];
+
+ // Confirms that a download notification is generated.
+ std::string notification_id1 =
+ download_start_notification_observer1.notification_id();
+ EXPECT_FALSE(notification_id1.empty());
+
+ // Second user starts a download.
+ NotificationAddObserver download_start_notification_observer2;
+ ui_test_utils::NavigateToURL(browser2, url);
+ download_start_notification_observer2.Wait();
+ std::string notification_id2 =
+ download_start_notification_observer2.notification_id();
+ EXPECT_FALSE(notification_id2.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.
+ NotificationAddObserver download_start_notification_observer3;
+ ui_test_utils::NavigateToURL(browser2, url);
+ download_start_notification_observer3.Wait();
+ std::string notification_id3 =
+ download_start_notification_observer3.notification_id();
+ EXPECT_FALSE(notification_id3.empty());
+
+ // Confirms that the second user has 2 downloads.
+ downloads.clear();
+ GetDownloadManager(browser2)->GetAllDownloads(&downloads);
+ ASSERT_EQ(2u, downloads.size());
+ content::DownloadItem* download2 = downloads[0];
+ content::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.
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
+ GetNotification(notification_id1)->type());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
+ GetNotification(notification_id2)->type());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
+ GetNotification(notification_id3)->type());
+
+ // Requests to complete the downloads.
+ ui_test_utils::NavigateToURL(
+ browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
+
+ // Waits for the completion of downloads.
+ while (download1->GetState() != content::DownloadItem::COMPLETE ||
+ download2->GetState() != content::DownloadItem::COMPLETE ||
+ download3->GetState() != content::DownloadItem::COMPLETE) {
+ NotificationUpdateObserver download_change_notification_observer;
+ download_change_notification_observer.Wait();
+ }
+
+ // Confirms the types of download notifications are correct.
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
+ GetNotification(notification_id1)->type());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
+ GetNotification(notification_id2)->type());
+ EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
+ GetNotification(notification_id3)->type());
+}
« no previous file with comments | « no previous file | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698