[Download Notification] Add cancel-button and download-removed tests
[chromium-blink-merge.git] / chrome / browser / download / notification / download_notification_browsertest.cc
blob2d85906ebeee0abbf6121e6c44ef283ca7031930
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/command_line.h"
6 #include "base/message_loop/message_loop.h"
7 #include "base/run_loop.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chromeos/profiles/profile_helper.h"
10 #include "chrome/browser/download/chrome_download_manager_delegate.h"
11 #include "chrome/browser/download/download_service.h"
12 #include "chrome/browser/download/download_service_factory.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/signin/signin_manager_factory.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "chrome/grit/chromium_strings.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "chromeos/chromeos_switches.h"
22 #include "components/signin/core/browser/signin_manager_base.h"
23 #include "content/public/browser/browser_context.h"
24 #include "content/public/browser/download_item.h"
25 #include "content/public/browser/download_manager.h"
26 #include "grit/theme_resources.h"
27 #include "net/test/url_request/url_request_slow_download_job.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/message_center/message_center.h"
30 #include "ui/message_center/message_center_observer.h"
31 #include "url/gurl.h"
33 namespace {
35 enum {
36 DUMMY_ACCOUNT_INDEX = 0,
37 PRIMARY_ACCOUNT_INDEX = 1,
38 SECONDARY_ACCOUNT_INDEX_START = 2,
41 // Structure to describe an account info.
42 struct TestAccountInfo {
43 const char* const email;
44 const char* const gaia_id;
45 const char* const hash;
46 const char* const display_name;
49 // Accounts for multi profile test.
50 static const TestAccountInfo kTestAccounts[] = {
51 {"__dummy__@invalid.domain", "10000", "hashdummy", "Dummy Account"},
52 {"alice@invalid.domain", "10001", "hashalice", "Alice"},
53 {"bob@invalid.domain", "10002", "hashbobbo", "Bob"},
54 {"charlie@invalid.domain", "10003", "hashcharl", "Charlie"},
57 bool IsInNotifications(
58 const message_center::NotificationList::Notifications& notifications,
59 const std::string& id) {
60 for (const auto& notification : notifications) {
61 if (notification->id() == id)
62 return true;
64 return false;
67 // Base class observing notification events.
68 class MessageCenterChangeObserver
69 : public message_center::MessageCenterObserver {
70 public:
71 MessageCenterChangeObserver() {
72 message_center::MessageCenter::Get()->AddObserver(this);
75 ~MessageCenterChangeObserver() override {
76 message_center::MessageCenter::Get()->RemoveObserver(this);
79 protected:
80 void RunLoop() {
81 base::MessageLoop::ScopedNestableTaskAllower allow(
82 base::MessageLoop::current());
83 run_loop_.Run();
86 void QuitRunLoop() {
87 run_loop_.Quit();
90 private:
91 base::RunLoop run_loop_;
93 DISALLOW_COPY_AND_ASSIGN(MessageCenterChangeObserver);
96 // Class observing of "ADD" notification events.
97 class NotificationAddObserver : public MessageCenterChangeObserver {
98 public:
99 NotificationAddObserver() : count_(1) {
100 MessageCenterChangeObserver();
102 explicit NotificationAddObserver(int count) : count_(count) {
103 MessageCenterChangeObserver();
105 ~NotificationAddObserver() override {}
107 bool Wait() {
108 if (count_ <= 0)
109 return count_ == 0;
111 waiting_ = true;
112 RunLoop();
113 waiting_ = false;
114 return count_ == 0;
117 // message_center::MessageCenterObserver:
118 void OnNotificationAdded(const std::string& notification_id) override {
119 count_--;
121 if (notification_id_.empty())
122 notification_id_ = notification_id;
124 if (waiting_)
125 QuitRunLoop();
128 std::string notification_id() { return notification_id_; }
130 private:
131 std::string notification_id_;
132 bool waiting_ = false;
133 int count_;
135 DISALLOW_COPY_AND_ASSIGN(NotificationAddObserver);
138 // Class observing of "UPDATE" notification events.
139 class NotificationUpdateObserver : public MessageCenterChangeObserver {
140 public:
141 NotificationUpdateObserver() {
142 MessageCenterChangeObserver();
144 ~NotificationUpdateObserver() override {}
146 std::string Wait() {
147 if (!notification_id_.empty())
148 return notification_id_;
150 waiting_ = true;
151 RunLoop();
152 waiting_ = false;
153 return notification_id_;
156 void OnNotificationUpdated(const std::string& notification_id) override {
157 if (notification_id_.empty()) {
158 notification_id_ = notification_id;
160 if (waiting_)
161 QuitRunLoop();
165 private:
166 std::string notification_id_;
167 bool waiting_ = false;
169 DISALLOW_COPY_AND_ASSIGN(NotificationUpdateObserver);
172 // Class observing of "REMOVE" notification events.
173 class NotificationRemoveObserver : public MessageCenterChangeObserver {
174 public:
175 NotificationRemoveObserver() {
176 MessageCenterChangeObserver();
178 ~NotificationRemoveObserver() override {}
180 std::string Wait() {
181 if (!notification_id_.empty())
182 return notification_id_;
184 waiting_ = true;
185 RunLoop();
186 waiting_ = false;
187 return notification_id_;
190 void OnNotificationRemoved(
191 const std::string& notification_id, bool by_user) override {
192 if (notification_id_.empty()) {
193 notification_id_ = notification_id;
195 if (waiting_)
196 QuitRunLoop();
200 private:
201 std::string notification_id_;
202 bool waiting_ = false;
204 DISALLOW_COPY_AND_ASSIGN(NotificationRemoveObserver);
207 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
208 public:
209 explicit TestChromeDownloadManagerDelegate(Profile* profile)
210 : ChromeDownloadManagerDelegate(profile), opened_(false) {}
211 ~TestChromeDownloadManagerDelegate() override {}
213 // ChromeDownloadManagerDelegate override:
214 void OpenDownload(content::DownloadItem* item) override { opened_ = true; }
216 // Return if the download is opened.
217 bool opened() const { return opened_; }
219 private:
220 bool opened_;
223 // Utility method to retrieve a message center.
224 message_center::MessageCenter* GetMessageCenter() {
225 return message_center::MessageCenter::Get();
228 // Utility method to retrieve a notification object by id.
229 message_center::Notification* GetNotification(const std::string& id) {
230 return GetMessageCenter()->FindVisibleNotificationById(id);
233 } // anonnymous namespace
235 // Base class for tests
236 class DownloadNotificationTestBase : public InProcessBrowserTest {
237 public:
238 ~DownloadNotificationTestBase() override {}
240 void SetUpCommandLine(base::CommandLine* command_line) override {
241 // TODO(yoshiki): Remove this after the download notification launches.
242 command_line->AppendSwitch(switches::kEnableDownloadNotification);
245 void SetUpOnMainThread() override {
246 content::BrowserThread::PostTask(
247 content::BrowserThread::IO, FROM_HERE,
248 base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler));
251 content::DownloadManager* GetDownloadManager(Browser* browser) {
252 return content::BrowserContext::GetDownloadManager(browser->profile());
256 //////////////////////////////////////////////////
257 // Test with a single profile
258 //////////////////////////////////////////////////
260 class DownloadNotificationTest : public DownloadNotificationTestBase {
261 public:
262 ~DownloadNotificationTest() override {}
264 void SetUpOnMainThread() override {
265 Profile* profile = browser()->profile();
267 scoped_ptr<TestChromeDownloadManagerDelegate> test_delegate;
268 test_delegate.reset(new TestChromeDownloadManagerDelegate(profile));
269 test_delegate->GetDownloadIdReceiverCallback().Run(
270 content::DownloadItem::kInvalidId + 1);
272 DownloadServiceFactory::GetForBrowserContext(profile)
273 ->SetDownloadManagerDelegateForTesting(test_delegate.Pass());
275 DownloadNotificationTestBase::SetUpOnMainThread();
278 TestChromeDownloadManagerDelegate* GetDownloadManagerDelegate() const {
279 return static_cast<TestChromeDownloadManagerDelegate*>(
280 DownloadServiceFactory::GetForBrowserContext(browser()->profile())
281 ->GetDownloadManagerDelegate());
284 void CreateDownload() {
285 GURL url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
287 // Starts a download.
288 NotificationAddObserver download_start_notification_observer;
289 ui_test_utils::NavigateToURL(browser(), url);
290 EXPECT_TRUE(download_start_notification_observer.Wait());
292 // Confirms that a notification is created.
293 notification_id_ = download_start_notification_observer.notification_id();
294 EXPECT_FALSE(notification_id_.empty());
295 ASSERT_TRUE(notification());
297 // Confirms that there is only a notification.
298 message_center::NotificationList::Notifications
299 visible_notifications = GetMessageCenter()->GetVisibleNotifications();
300 EXPECT_EQ(1u, visible_notifications.size());
301 EXPECT_TRUE(IsInNotifications(visible_notifications, notification_id_));
303 // Confirms that a download is also started.
304 std::vector<content::DownloadItem*> downloads;
305 GetDownloadManager(browser())->GetAllDownloads(&downloads);
306 EXPECT_EQ(1u, downloads.size());
307 download_item_ = downloads[0];
308 ASSERT_TRUE(download_item_);
311 content::DownloadItem* download_item() const { return download_item_; }
312 std::string notification_id() const { return notification_id_; }
313 message_center::Notification* notification() const {
314 return GetNotification(notification_id_);
317 private:
318 content::DownloadItem* download_item_ = nullptr;
319 std::string notification_id_;
322 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadFile) {
323 CreateDownload();
325 EXPECT_EQ(l10n_util::GetStringFUTF16(
326 IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE,
327 download_item()->GetFileNameToReportUser().LossyDisplayName()),
328 GetNotification(notification_id())->title());
329 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
330 GetNotification(notification_id())->type());
332 // Requests to complete the download.
333 ui_test_utils::NavigateToURL(
334 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
336 // Waits for download completion.
337 while (download_item()->GetState() != content::DownloadItem::COMPLETE) {
338 NotificationUpdateObserver download_change_notification_observer;
339 download_change_notification_observer.Wait();
342 EXPECT_EQ(l10n_util::GetStringFUTF16(
343 IDS_DOWNLOAD_STATUS_DOWNLOADED_TITLE,
344 download_item()->GetFileNameToReportUser().LossyDisplayName()),
345 GetNotification(notification_id())->title());
346 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
347 GetNotification(notification_id())->type());
349 // Try to open the downloaded item by clicking the notification.
350 EXPECT_FALSE(GetDownloadManagerDelegate()->opened());
351 GetMessageCenter()->ClickOnNotification(notification_id());
352 EXPECT_TRUE(GetDownloadManagerDelegate()->opened());
354 EXPECT_FALSE(GetNotification(notification_id()));
357 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
358 CloseNotificationAfterDownload) {
359 CreateDownload();
361 // Requests to complete the download.
362 ui_test_utils::NavigateToURL(
363 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
365 // Waits for download completion.
366 while (download_item()->GetState() != content::DownloadItem::COMPLETE) {
367 NotificationUpdateObserver download_change_notification_observer;
368 download_change_notification_observer.Wait();
371 // Opens the message center.
372 GetMessageCenter()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
374 // Closes the notification.
375 NotificationRemoveObserver notification_close_observer;
376 GetMessageCenter()->RemoveNotification(notification_id(), true /* by_user */);
377 EXPECT_EQ(notification_id(), notification_close_observer.Wait());
379 EXPECT_EQ(0u, GetMessageCenter()->GetVisibleNotifications().size());
381 // Confirms that a download is also started.
382 std::vector<content::DownloadItem*> downloads;
383 GetDownloadManager(browser())->GetAllDownloads(&downloads);
384 EXPECT_EQ(1u, downloads.size());
385 EXPECT_EQ(content::DownloadItem::COMPLETE, downloads[0]->GetState());
388 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest,
389 CloseNotificationWhileDownloading) {
390 CreateDownload();
392 // Closes the notification.
393 NotificationRemoveObserver notification_close_observer;
394 GetMessageCenter()->RemoveNotification(notification_id(), true /* by_user */);
395 EXPECT_EQ(notification_id(), notification_close_observer.Wait());
397 EXPECT_EQ(0u, GetMessageCenter()->GetVisibleNotifications().size());
399 // Confirms that a download is still in progress.
400 std::vector<content::DownloadItem*> downloads;
401 GetDownloadManager(browser())->GetAllDownloads(&downloads);
402 EXPECT_EQ(1u, downloads.size());
403 EXPECT_EQ(content::DownloadItem::IN_PROGRESS, downloads[0]->GetState());
405 // Cleans the downloading.
406 downloads[0]->Cancel(true);
409 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadRemoved) {
410 CreateDownload();
412 NotificationRemoveObserver notification_close_observer;
413 download_item()->Remove();
414 EXPECT_EQ(notification_id(), notification_close_observer.Wait());
416 // Confirms that the notification is removed.
417 EXPECT_EQ(0u, GetMessageCenter()->GetVisibleNotifications().size());
419 // Confirms that the download item is removed.
420 std::vector<content::DownloadItem*> downloads;
421 GetDownloadManager(browser())->GetAllDownloads(&downloads);
422 EXPECT_EQ(0u, downloads.size());
425 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest, DownloadMultipleFiles) {
426 GURL url1(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
427 GURL url2(net::URLRequestSlowDownloadJob::kKnownSizeUrl);
429 // Starts the 1st download.
430 NotificationAddObserver download_start_notification_observer1;
431 ui_test_utils::NavigateToURL(browser(), url1);
432 EXPECT_TRUE(download_start_notification_observer1.Wait());
433 std::string notification_id1 =
434 download_start_notification_observer1.notification_id();
435 EXPECT_FALSE(notification_id1.empty());
437 // Confirms that there is a download.
438 std::vector<content::DownloadItem*> downloads;
439 GetDownloadManager(browser())->GetAllDownloads(&downloads);
440 EXPECT_EQ(1u, downloads.size());
441 content::DownloadItem* download1or2 = downloads[0];
443 // Starts the 2nd download.
444 NotificationAddObserver download_start_notification_observer2;
445 ui_test_utils::NavigateToURL(browser(), url2);
446 EXPECT_TRUE(download_start_notification_observer2.Wait());
447 std::string notification_id2 =
448 download_start_notification_observer2.notification_id();
449 EXPECT_FALSE(notification_id2.empty());
451 // Confirms that there are 2 downloads.
452 downloads.clear();
453 GetDownloadManager(browser())->GetAllDownloads(&downloads);
454 content::DownloadItem* download1 = downloads[0];
455 content::DownloadItem* download2 = downloads[1];
456 EXPECT_EQ(2u, downloads.size());
457 EXPECT_NE(download1, download2);
458 EXPECT_TRUE(download1 == download1or2 || download2 == download1or2);
460 // Confirms the types of download notifications are correct.
461 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
462 GetNotification(notification_id1)->type());
463 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
464 GetNotification(notification_id2)->type());
466 // Requests to complete the downloads.
467 ui_test_utils::NavigateToURL(
468 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
470 // Waits for the completion of downloads.
471 while (download1->GetState() != content::DownloadItem::COMPLETE ||
472 download2->GetState() != content::DownloadItem::COMPLETE) {
473 NotificationUpdateObserver download_change_notification_observer;
474 download_change_notification_observer.Wait();
477 // Confirms the types of download notifications are correct.
478 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
479 GetNotification(notification_id1)->type());
480 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
481 GetNotification(notification_id2)->type());
484 //////////////////////////////////////////////////
485 // Test with multi profiles
486 //////////////////////////////////////////////////
488 class MultiProfileDownloadNotificationTest
489 : public DownloadNotificationTestBase {
490 public:
491 ~MultiProfileDownloadNotificationTest() override {}
493 void SetUpCommandLine(base::CommandLine* command_line) override {
494 DownloadNotificationTestBase::SetUpCommandLine(command_line);
496 // Logs in to a dummy profile.
497 command_line->AppendSwitchASCII(chromeos::switches::kLoginUser,
498 kTestAccounts[DUMMY_ACCOUNT_INDEX].email);
499 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile,
500 kTestAccounts[DUMMY_ACCOUNT_INDEX].hash);
503 // Logs in to the primary profile.
504 void SetUpOnMainThread() override {
505 const TestAccountInfo& info = kTestAccounts[PRIMARY_ACCOUNT_INDEX];
507 AddUser(info, true);
508 DownloadNotificationTestBase::SetUpOnMainThread();
511 // Loads all users to the current session and sets up necessary fields.
512 // This is used for preparing all accounts in PRE_ test setup, and for testing
513 // actual login behavior.
514 void AddAllUsers() {
515 for (size_t i = 0; i < arraysize(kTestAccounts); ++i)
516 AddUser(kTestAccounts[i], i >= SECONDARY_ACCOUNT_INDEX_START);
519 Profile* GetProfileByIndex(int index) {
520 return chromeos::ProfileHelper::GetProfileByUserIdHash(
521 kTestAccounts[index].hash);
524 // Adds a new user for testing to the current session.
525 void AddUser(const TestAccountInfo& info, bool log_in) {
526 user_manager::UserManager* const user_manager =
527 user_manager::UserManager::Get();
528 if (log_in)
529 user_manager->UserLoggedIn(info.email, info.hash, false);
530 user_manager->SaveUserDisplayName(info.email,
531 base::UTF8ToUTF16(info.display_name));
532 SigninManagerFactory::GetForProfile(
533 chromeos::ProfileHelper::GetProfileByUserIdHash(info.hash))
534 ->SetAuthenticatedAccountInfo(info.gaia_id, info.email);
538 IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest,
539 PRE_DownloadMultipleFiles) {
540 AddAllUsers();
543 IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest,
544 DownloadMultipleFiles) {
545 AddAllUsers();
547 GURL url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl);
549 Profile* profile1 = GetProfileByIndex(1);
550 Profile* profile2 = GetProfileByIndex(2);
551 Browser* browser1 = CreateBrowser(profile1);
552 Browser* browser2 = CreateBrowser(profile2);
553 EXPECT_NE(browser1, browser2);
555 // First user starts a download.
556 NotificationAddObserver download_start_notification_observer1;
557 ui_test_utils::NavigateToURL(browser1, url);
558 download_start_notification_observer1.Wait();
560 // Confirms that the download is started.
561 std::vector<content::DownloadItem*> downloads;
562 GetDownloadManager(browser1)->GetAllDownloads(&downloads);
563 EXPECT_EQ(1u, downloads.size());
564 content::DownloadItem* download1 = downloads[0];
566 // Confirms that a download notification is generated.
567 std::string notification_id1 =
568 download_start_notification_observer1.notification_id();
569 EXPECT_FALSE(notification_id1.empty());
571 // Second user starts a download.
572 NotificationAddObserver download_start_notification_observer2;
573 ui_test_utils::NavigateToURL(browser2, url);
574 download_start_notification_observer2.Wait();
575 std::string notification_id2 =
576 download_start_notification_observer2.notification_id();
577 EXPECT_FALSE(notification_id2.empty());
579 // Confirms that the second user has only 1 download.
580 downloads.clear();
581 GetDownloadManager(browser2)->GetAllDownloads(&downloads);
582 ASSERT_EQ(1u, downloads.size());
584 // Second user starts another download.
585 NotificationAddObserver download_start_notification_observer3;
586 ui_test_utils::NavigateToURL(browser2, url);
587 download_start_notification_observer3.Wait();
588 std::string notification_id3 =
589 download_start_notification_observer3.notification_id();
590 EXPECT_FALSE(notification_id3.empty());
592 // Confirms that the second user has 2 downloads.
593 downloads.clear();
594 GetDownloadManager(browser2)->GetAllDownloads(&downloads);
595 ASSERT_EQ(2u, downloads.size());
596 content::DownloadItem* download2 = downloads[0];
597 content::DownloadItem* download3 = downloads[1];
598 EXPECT_NE(download1, download2);
599 EXPECT_NE(download1, download3);
600 EXPECT_NE(download2, download3);
602 // Confirms that the first user still has only 1 download.
603 downloads.clear();
604 GetDownloadManager(browser1)->GetAllDownloads(&downloads);
605 ASSERT_EQ(1u, downloads.size());
606 EXPECT_EQ(download1, downloads[0]);
608 // Confirms the types of download notifications are correct.
609 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
610 GetNotification(notification_id1)->type());
611 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
612 GetNotification(notification_id2)->type());
613 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS,
614 GetNotification(notification_id3)->type());
616 // Requests to complete the downloads.
617 ui_test_utils::NavigateToURL(
618 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl));
620 // Waits for the completion of downloads.
621 while (download1->GetState() != content::DownloadItem::COMPLETE ||
622 download2->GetState() != content::DownloadItem::COMPLETE ||
623 download3->GetState() != content::DownloadItem::COMPLETE) {
624 NotificationUpdateObserver download_change_notification_observer;
625 download_change_notification_observer.Wait();
628 // Confirms the types of download notifications are correct.
629 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
630 GetNotification(notification_id1)->type());
631 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
632 GetNotification(notification_id2)->type());
633 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE,
634 GetNotification(notification_id3)->type());