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"
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
)
67 // Base class observing notification events.
68 class MessageCenterChangeObserver
69 : public message_center::MessageCenterObserver
{
71 MessageCenterChangeObserver() {
72 message_center::MessageCenter::Get()->AddObserver(this);
75 ~MessageCenterChangeObserver() override
{
76 message_center::MessageCenter::Get()->RemoveObserver(this);
81 base::MessageLoop::ScopedNestableTaskAllower
allow(
82 base::MessageLoop::current());
91 base::RunLoop run_loop_
;
93 DISALLOW_COPY_AND_ASSIGN(MessageCenterChangeObserver
);
96 // Class observing of "ADD" notification events.
97 class NotificationAddObserver
: public MessageCenterChangeObserver
{
99 NotificationAddObserver() : count_(1) {
100 MessageCenterChangeObserver();
102 explicit NotificationAddObserver(int count
) : count_(count
) {
103 MessageCenterChangeObserver();
105 ~NotificationAddObserver() override
{}
117 // message_center::MessageCenterObserver:
118 void OnNotificationAdded(const std::string
& notification_id
) override
{
121 if (notification_id_
.empty())
122 notification_id_
= notification_id
;
128 std::string
notification_id() { return notification_id_
; }
131 std::string notification_id_
;
132 bool waiting_
= false;
135 DISALLOW_COPY_AND_ASSIGN(NotificationAddObserver
);
138 // Class observing of "UPDATE" notification events.
139 class NotificationUpdateObserver
: public MessageCenterChangeObserver
{
141 NotificationUpdateObserver() {
142 MessageCenterChangeObserver();
144 ~NotificationUpdateObserver() override
{}
147 if (!notification_id_
.empty())
148 return notification_id_
;
153 return notification_id_
;
156 void OnNotificationUpdated(const std::string
& notification_id
) override
{
157 if (notification_id_
.empty()) {
158 notification_id_
= notification_id
;
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
{
175 NotificationRemoveObserver() {
176 MessageCenterChangeObserver();
178 ~NotificationRemoveObserver() override
{}
181 if (!notification_id_
.empty())
182 return notification_id_
;
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
;
201 std::string notification_id_
;
202 bool waiting_
= false;
204 DISALLOW_COPY_AND_ASSIGN(NotificationRemoveObserver
);
207 class TestChromeDownloadManagerDelegate
: public ChromeDownloadManagerDelegate
{
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_
; }
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
{
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
{
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_
);
318 content::DownloadItem
* download_item_
= nullptr;
319 std::string notification_id_
;
322 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest
, DownloadFile
) {
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
) {
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
) {
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
) {
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.
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
{
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
];
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.
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();
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
) {
543 IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest
,
544 DownloadMultipleFiles
) {
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.
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.
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.
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());