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 // Base class observing notification events.
58 class MessageCenterChangeObserver
59 : public message_center::MessageCenterObserver
{
61 MessageCenterChangeObserver() {
62 message_center::MessageCenter::Get()->AddObserver(this);
65 ~MessageCenterChangeObserver() override
{
66 message_center::MessageCenter::Get()->RemoveObserver(this);
71 base::MessageLoop::ScopedNestableTaskAllower
allow(
72 base::MessageLoop::current());
81 base::RunLoop run_loop_
;
83 DISALLOW_COPY_AND_ASSIGN(MessageCenterChangeObserver
);
86 // Class observing of "ADD" notification events.
87 class NotificationAddObserver
: public MessageCenterChangeObserver
{
89 NotificationAddObserver() : count_(1) {
90 MessageCenterChangeObserver();
92 explicit NotificationAddObserver(int count
) : count_(count
) {
93 MessageCenterChangeObserver();
95 ~NotificationAddObserver() override
{}
107 // message_center::MessageCenterObserver:
108 void OnNotificationAdded(const std::string
& notification_id
) override
{
111 if (notification_id_
.empty())
112 notification_id_
= notification_id
;
118 std::string
notification_id() { return notification_id_
; }
121 std::string notification_id_
;
122 bool waiting_
= false;
125 DISALLOW_COPY_AND_ASSIGN(NotificationAddObserver
);
128 // Class observing of "UPDATE" notification events.
129 class NotificationUpdateObserver
: public MessageCenterChangeObserver
{
131 NotificationUpdateObserver() : waiting_(false) {
132 MessageCenterChangeObserver();
134 ~NotificationUpdateObserver() override
{}
137 if (!notification_id_
.empty())
138 return notification_id_
;
143 return notification_id_
;
146 void OnNotificationUpdated(const std::string
& notification_id
) override
{
147 if (notification_id_
.empty()) {
148 notification_id_
= notification_id
;
156 std::string notification_id_
;
159 DISALLOW_COPY_AND_ASSIGN(NotificationUpdateObserver
);
162 class TestChromeDownloadManagerDelegate
: public ChromeDownloadManagerDelegate
{
164 explicit TestChromeDownloadManagerDelegate(Profile
* profile
)
165 : ChromeDownloadManagerDelegate(profile
), opened_(false) {}
166 ~TestChromeDownloadManagerDelegate() override
{}
168 // ChromeDownloadManagerDelegate override:
169 void OpenDownload(content::DownloadItem
* item
) override
{ opened_
= true; }
171 // Return if the download is opened.
172 bool opened() const { return opened_
; }
178 // Utility method to retrieve a message center.
179 message_center::MessageCenter
* GetMessageCenter() {
180 return message_center::MessageCenter::Get();
183 // Utility method to retrieve a notification object by id.
184 message_center::Notification
* GetNotification(const std::string
& id
) {
185 return GetMessageCenter()->FindVisibleNotificationById(id
);
188 } // anonnymous namespace
190 // Base class for tests
191 class DownloadNotificationTestBase
: public InProcessBrowserTest
{
193 ~DownloadNotificationTestBase() override
{}
195 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
196 // TODO(yoshiki): Remove this after the download notification launches.
197 command_line
->AppendSwitch(switches::kEnableDownloadNotification
);
200 void SetUpOnMainThread() override
{
201 content::BrowserThread::PostTask(
202 content::BrowserThread::IO
, FROM_HERE
,
203 base::Bind(&net::URLRequestSlowDownloadJob::AddUrlHandler
));
206 content::DownloadManager
* GetDownloadManager(Browser
* browser
) {
207 return content::BrowserContext::GetDownloadManager(browser
->profile());
211 //////////////////////////////////////////////////
212 // Test with a single profile
213 //////////////////////////////////////////////////
215 class DownloadNotificationTest
: public DownloadNotificationTestBase
{
217 ~DownloadNotificationTest() override
{}
219 void SetUpOnMainThread() override
{
220 Profile
* profile
= browser()->profile();
222 scoped_ptr
<TestChromeDownloadManagerDelegate
> test_delegate
;
223 test_delegate
.reset(new TestChromeDownloadManagerDelegate(profile
));
224 test_delegate
->GetDownloadIdReceiverCallback().Run(
225 content::DownloadItem::kInvalidId
+ 1);
227 DownloadServiceFactory::GetForBrowserContext(profile
)
228 ->SetDownloadManagerDelegateForTesting(test_delegate
.Pass());
230 DownloadNotificationTestBase::SetUpOnMainThread();
233 TestChromeDownloadManagerDelegate
* GetDownloadManagerDelegate() const {
234 return static_cast<TestChromeDownloadManagerDelegate
*>(
235 DownloadServiceFactory::GetForBrowserContext(browser()->profile())
236 ->GetDownloadManagerDelegate());
240 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest
, DownloadFile
) {
241 GURL
url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
);
243 // Starts a download.
244 NotificationAddObserver download_start_notification_observer
;
245 ui_test_utils::NavigateToURL(browser(), url
);
246 EXPECT_TRUE(download_start_notification_observer
.Wait());
248 // Confirms that a notification is created.
249 std::string notification_id
=
250 download_start_notification_observer
.notification_id();
251 EXPECT_FALSE(notification_id
.empty());
253 // Confirms that a download is also started.
254 std::vector
<content::DownloadItem
*> downloads
;
255 GetDownloadManager(browser())->GetAllDownloads(&downloads
);
256 EXPECT_EQ(1u, downloads
.size());
257 content::DownloadItem
* download
= downloads
[0];
259 EXPECT_EQ(l10n_util::GetStringFUTF16(
260 IDS_DOWNLOAD_STATUS_IN_PROGRESS_TITLE
,
261 download
->GetFileNameToReportUser().LossyDisplayName()),
262 GetNotification(notification_id
)->title());
263 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS
,
264 GetNotification(notification_id
)->type());
266 // Requests to complete the download.
267 ui_test_utils::NavigateToURL(
268 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl
));
270 // Waits for download completion.
271 while (download
->GetState() != content::DownloadItem::COMPLETE
) {
272 NotificationUpdateObserver download_change_notification_observer
;
273 download_change_notification_observer
.Wait();
276 EXPECT_EQ(l10n_util::GetStringFUTF16(
277 IDS_DOWNLOAD_STATUS_DOWNLOADED_TITLE
,
278 download
->GetFileNameToReportUser().LossyDisplayName()),
279 GetNotification(notification_id
)->title());
280 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE
,
281 GetNotification(notification_id
)->type());
283 // Try to open the downloaded item by clicking the notification.
284 EXPECT_FALSE(GetDownloadManagerDelegate()->opened());
285 GetMessageCenter()->ClickOnNotification(notification_id
);
286 EXPECT_TRUE(GetDownloadManagerDelegate()->opened());
288 EXPECT_FALSE(GetNotification(notification_id
));
291 IN_PROC_BROWSER_TEST_F(DownloadNotificationTest
, DownloadMultipleFiles
) {
292 GURL
url1(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
);
293 GURL
url2(net::URLRequestSlowDownloadJob::kKnownSizeUrl
);
295 // Starts the 1st download.
296 NotificationAddObserver download_start_notification_observer1
;
297 ui_test_utils::NavigateToURL(browser(), url1
);
298 EXPECT_TRUE(download_start_notification_observer1
.Wait());
299 std::string notification_id1
=
300 download_start_notification_observer1
.notification_id();
301 EXPECT_FALSE(notification_id1
.empty());
303 // Confirms that there is a download.
304 std::vector
<content::DownloadItem
*> downloads
;
305 GetDownloadManager(browser())->GetAllDownloads(&downloads
);
306 EXPECT_EQ(1u, downloads
.size());
307 content::DownloadItem
* download1or2
= downloads
[0];
309 // Starts the 2nd download.
310 NotificationAddObserver download_start_notification_observer2
;
311 ui_test_utils::NavigateToURL(browser(), url2
);
312 EXPECT_TRUE(download_start_notification_observer2
.Wait());
313 std::string notification_id2
=
314 download_start_notification_observer2
.notification_id();
315 EXPECT_FALSE(notification_id2
.empty());
317 // Confirms that there are 2 downloads.
319 GetDownloadManager(browser())->GetAllDownloads(&downloads
);
320 content::DownloadItem
* download1
= downloads
[0];
321 content::DownloadItem
* download2
= downloads
[1];
322 EXPECT_EQ(2u, downloads
.size());
323 EXPECT_NE(download1
, download2
);
324 EXPECT_TRUE(download1
== download1or2
|| download2
== download1or2
);
326 // Confirms the types of download notifications are correct.
327 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS
,
328 GetNotification(notification_id1
)->type());
329 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS
,
330 GetNotification(notification_id2
)->type());
332 // Requests to complete the downloads.
333 ui_test_utils::NavigateToURL(
334 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl
));
336 // Waits for the completion of downloads.
337 while (download1
->GetState() != content::DownloadItem::COMPLETE
||
338 download2
->GetState() != content::DownloadItem::COMPLETE
) {
339 NotificationUpdateObserver download_change_notification_observer
;
340 download_change_notification_observer
.Wait();
343 // Confirms the types of download notifications are correct.
344 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE
,
345 GetNotification(notification_id1
)->type());
346 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE
,
347 GetNotification(notification_id2
)->type());
350 //////////////////////////////////////////////////
351 // Test with multi profiles
352 //////////////////////////////////////////////////
354 class MultiProfileDownloadNotificationTest
355 : public DownloadNotificationTestBase
{
357 ~MultiProfileDownloadNotificationTest() override
{}
359 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
360 DownloadNotificationTestBase::SetUpCommandLine(command_line
);
362 // Logs in to a dummy profile.
363 command_line
->AppendSwitchASCII(chromeos::switches::kLoginUser
,
364 kTestAccounts
[DUMMY_ACCOUNT_INDEX
].email
);
365 command_line
->AppendSwitchASCII(chromeos::switches::kLoginProfile
,
366 kTestAccounts
[DUMMY_ACCOUNT_INDEX
].hash
);
369 // Logs in to the primary profile.
370 void SetUpOnMainThread() override
{
371 const TestAccountInfo
& info
= kTestAccounts
[PRIMARY_ACCOUNT_INDEX
];
374 DownloadNotificationTestBase::SetUpOnMainThread();
377 // Loads all users to the current session and sets up necessary fields.
378 // This is used for preparing all accounts in PRE_ test setup, and for testing
379 // actual login behavior.
381 for (size_t i
= 0; i
< arraysize(kTestAccounts
); ++i
)
382 AddUser(kTestAccounts
[i
], i
>= SECONDARY_ACCOUNT_INDEX_START
);
385 Profile
* GetProfileByIndex(int index
) {
386 return chromeos::ProfileHelper::GetProfileByUserIdHash(
387 kTestAccounts
[index
].hash
);
390 // Adds a new user for testing to the current session.
391 void AddUser(const TestAccountInfo
& info
, bool log_in
) {
392 user_manager::UserManager
* const user_manager
=
393 user_manager::UserManager::Get();
395 user_manager
->UserLoggedIn(info
.email
, info
.hash
, false);
396 user_manager
->SaveUserDisplayName(info
.email
,
397 base::UTF8ToUTF16(info
.display_name
));
398 SigninManagerFactory::GetForProfile(
399 chromeos::ProfileHelper::GetProfileByUserIdHash(info
.hash
))
400 ->SetAuthenticatedAccountInfo(info
.gaia_id
, info
.email
);
404 IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest
,
405 PRE_DownloadMultipleFiles
) {
409 IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest
,
410 DownloadMultipleFiles
) {
413 GURL
url(net::URLRequestSlowDownloadJob::kUnknownSizeUrl
);
415 Profile
* profile1
= GetProfileByIndex(1);
416 Profile
* profile2
= GetProfileByIndex(2);
417 Browser
* browser1
= CreateBrowser(profile1
);
418 Browser
* browser2
= CreateBrowser(profile2
);
419 EXPECT_NE(browser1
, browser2
);
421 // First user starts a download.
422 NotificationAddObserver download_start_notification_observer1
;
423 ui_test_utils::NavigateToURL(browser1
, url
);
424 download_start_notification_observer1
.Wait();
426 // Confirms that the download is started.
427 std::vector
<content::DownloadItem
*> downloads
;
428 GetDownloadManager(browser1
)->GetAllDownloads(&downloads
);
429 EXPECT_EQ(1u, downloads
.size());
430 content::DownloadItem
* download1
= downloads
[0];
432 // Confirms that a download notification is generated.
433 std::string notification_id1
=
434 download_start_notification_observer1
.notification_id();
435 EXPECT_FALSE(notification_id1
.empty());
437 // Second user starts a download.
438 NotificationAddObserver download_start_notification_observer2
;
439 ui_test_utils::NavigateToURL(browser2
, url
);
440 download_start_notification_observer2
.Wait();
441 std::string notification_id2
=
442 download_start_notification_observer2
.notification_id();
443 EXPECT_FALSE(notification_id2
.empty());
445 // Confirms that the second user has only 1 download.
447 GetDownloadManager(browser2
)->GetAllDownloads(&downloads
);
448 ASSERT_EQ(1u, downloads
.size());
450 // Second user starts another download.
451 NotificationAddObserver download_start_notification_observer3
;
452 ui_test_utils::NavigateToURL(browser2
, url
);
453 download_start_notification_observer3
.Wait();
454 std::string notification_id3
=
455 download_start_notification_observer3
.notification_id();
456 EXPECT_FALSE(notification_id3
.empty());
458 // Confirms that the second user has 2 downloads.
460 GetDownloadManager(browser2
)->GetAllDownloads(&downloads
);
461 ASSERT_EQ(2u, downloads
.size());
462 content::DownloadItem
* download2
= downloads
[0];
463 content::DownloadItem
* download3
= downloads
[1];
464 EXPECT_NE(download1
, download2
);
465 EXPECT_NE(download1
, download3
);
466 EXPECT_NE(download2
, download3
);
468 // Confirms that the first user still has only 1 download.
470 GetDownloadManager(browser1
)->GetAllDownloads(&downloads
);
471 ASSERT_EQ(1u, downloads
.size());
472 EXPECT_EQ(download1
, downloads
[0]);
474 // Confirms the types of download notifications are correct.
475 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS
,
476 GetNotification(notification_id1
)->type());
477 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS
,
478 GetNotification(notification_id2
)->type());
479 EXPECT_EQ(message_center::NOTIFICATION_TYPE_PROGRESS
,
480 GetNotification(notification_id3
)->type());
482 // Requests to complete the downloads.
483 ui_test_utils::NavigateToURL(
484 browser(), GURL(net::URLRequestSlowDownloadJob::kFinishDownloadUrl
));
486 // Waits for the completion of downloads.
487 while (download1
->GetState() != content::DownloadItem::COMPLETE
||
488 download2
->GetState() != content::DownloadItem::COMPLETE
||
489 download3
->GetState() != content::DownloadItem::COMPLETE
) {
490 NotificationUpdateObserver download_change_notification_observer
;
491 download_change_notification_observer
.Wait();
494 // Confirms the types of download notifications are correct.
495 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE
,
496 GetNotification(notification_id1
)->type());
497 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE
,
498 GetNotification(notification_id2
)->type());
499 EXPECT_EQ(message_center::NOTIFICATION_TYPE_SIMPLE
,
500 GetNotification(notification_id3
)->type());