Add initial browsertest of download notification
[chromium-blink-merge.git] / chrome / browser / download / notification / download_notification_browsertest.cc
blob287bbbd453645d4a8b3a77f0f4d24ca61e087612
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 // Base class observing notification events.
58 class MessageCenterChangeObserver
59 : public message_center::MessageCenterObserver {
60 public:
61 MessageCenterChangeObserver() {
62 message_center::MessageCenter::Get()->AddObserver(this);
65 ~MessageCenterChangeObserver() override {
66 message_center::MessageCenter::Get()->RemoveObserver(this);
69 protected:
70 void RunLoop() {
71 base::MessageLoop::ScopedNestableTaskAllower allow(
72 base::MessageLoop::current());
73 run_loop_.Run();
76 void QuitRunLoop() {
77 run_loop_.Quit();
80 private:
81 base::RunLoop run_loop_;
83 DISALLOW_COPY_AND_ASSIGN(MessageCenterChangeObserver);
86 // Class observing of "ADD" notification events.
87 class NotificationAddObserver : public MessageCenterChangeObserver {
88 public:
89 NotificationAddObserver() : count_(1) {
90 MessageCenterChangeObserver();
92 explicit NotificationAddObserver(int count) : count_(count) {
93 MessageCenterChangeObserver();
95 ~NotificationAddObserver() override {}
97 bool Wait() {
98 if (count_ <= 0)
99 return count_ == 0;
101 waiting_ = true;
102 RunLoop();
103 waiting_ = false;
104 return count_ == 0;
107 // message_center::MessageCenterObserver:
108 void OnNotificationAdded(const std::string& notification_id) override {
109 count_--;
111 if (notification_id_.empty())
112 notification_id_ = notification_id;
114 if (waiting_)
115 QuitRunLoop();
118 std::string notification_id() { return notification_id_; }
120 private:
121 std::string notification_id_;
122 bool waiting_ = false;
123 int count_;
125 DISALLOW_COPY_AND_ASSIGN(NotificationAddObserver);
128 // Class observing of "UPDATE" notification events.
129 class NotificationUpdateObserver : public MessageCenterChangeObserver {
130 public:
131 NotificationUpdateObserver() : waiting_(false) {
132 MessageCenterChangeObserver();
134 ~NotificationUpdateObserver() override {}
136 std::string Wait() {
137 if (!notification_id_.empty())
138 return notification_id_;
140 waiting_ = true;
141 RunLoop();
142 waiting_ = false;
143 return notification_id_;
146 void OnNotificationUpdated(const std::string& notification_id) override {
147 if (notification_id_.empty()) {
148 notification_id_ = notification_id;
150 if (waiting_)
151 QuitRunLoop();
155 private:
156 std::string notification_id_;
157 bool waiting_;
159 DISALLOW_COPY_AND_ASSIGN(NotificationUpdateObserver);
162 class TestChromeDownloadManagerDelegate : public ChromeDownloadManagerDelegate {
163 public:
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_; }
174 private:
175 bool 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 {
192 public:
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 {
216 public:
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.
318 downloads.clear();
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 {
356 public:
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];
373 AddUser(info, true);
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.
380 void AddAllUsers() {
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();
394 if (log_in)
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) {
406 AddAllUsers();
409 IN_PROC_BROWSER_TEST_F(MultiProfileDownloadNotificationTest,
410 DownloadMultipleFiles) {
411 AddAllUsers();
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.
446 downloads.clear();
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.
459 downloads.clear();
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.
469 downloads.clear();
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());