1// Copyright 2014 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.
4
5#include "base/memory/scoped_ptr.h"
6#include "base/prefs/testing_pref_service.h"
7#include "base/run_loop.h"
8#include "base/strings/utf_string_conversions.h"
9#include "base/test/test_timeouts.h"
10#include "base/values.h"
11#include "chrome/browser/notifications/message_center_notification_manager.h"
12#include "chrome/browser/notifications/notification.h"
13#include "chrome/browser/notifications/notification_test_util.h"
14#include "chrome/common/pref_names.h"
15#include "chrome/test/base/browser_with_test_window_test.h"
16#include "chrome/test/base/scoped_testing_local_state.h"
17#include "chrome/test/base/testing_browser_process.h"
18#include "chrome/test/base/testing_profile.h"
19#include "chrome/test/base/testing_profile_manager.h"
20#include "content/public/test/test_browser_thread_bundle.h"
21#include "testing/gtest/include/gtest/gtest.h"
22#include "ui/message_center/fake_message_center_tray_delegate.h"
23#include "ui/message_center/fake_notifier_settings_provider.h"
24#include "ui/message_center/message_center_impl.h"
25#include "ui/message_center/message_center_tray.h"
26#include "ui/message_center/message_center_types.h"
27#include "ui/message_center/notifier_settings.h"
28
29#if defined(OS_CHROMEOS)
30#include "chrome/browser/ui/ash/multi_user/multi_user_notification_blocker_chromeos.h"
31#include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
32#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
33#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
34#endif
35
36namespace message_center {
37
38class MessageCenterNotificationManagerTest : public BrowserWithTestWindowTest {
39 public:
40  MessageCenterNotificationManagerTest() {}
41
42 protected:
43  virtual void SetUp() {
44    BrowserWithTestWindowTest::SetUp();
45#if !defined(OS_CHROMEOS)
46    // BrowserWithTestWindowTest owns an AshTestHelper on OS_CHROMEOS, which
47    // in turn initializes the message center.  On other platforms, we need to
48    // initialize it here.
49    MessageCenter::Initialize();
50#endif
51
52
53    // Clear the preference and initialize.
54    TestingBrowserProcess* browser_process = TestingBrowserProcess::GetGlobal();
55    profile_manager_.reset(new TestingProfileManager(browser_process));
56    ASSERT_TRUE(profile_manager_->SetUp());
57    local_state()->ClearPref(prefs::kMessageCenterShowedFirstRunBalloon);
58    first_run_pref_.reset(new BooleanPrefMember);
59    first_run_pref_->Init(prefs::kMessageCenterShowedFirstRunBalloon,
60                         local_state());
61
62    // Get ourselves a run loop.
63    run_loop_.reset(new base::RunLoop());
64
65    message_center_ = MessageCenter::Get();
66    scoped_ptr<NotifierSettingsProvider> settings_provider(
67        new FakeNotifierSettingsProvider(notifiers_));
68    delegate_ = new FakeMessageCenterTrayDelegate(message_center_,
69                                                  run_loop_->QuitClosure());
70    notification_manager()->SetMessageCenterTrayDelegateForTest(delegate_);
71#if defined(OS_WIN)
72    // First run features are only implemented on Windows, where the
73    // notification center is hard to find.
74    notification_manager()->SetFirstRunTimeoutForTest(
75        TestTimeouts::tiny_timeout());
76#endif
77  }
78
79  virtual void TearDown() {
80    run_loop_.reset();
81    first_run_pref_.reset();
82    profile_manager_.reset();
83
84#if !defined(OS_CHROMEOS)
85    // Shutdown the message center if we initialized it manually.
86    MessageCenter::Shutdown();
87#endif
88
89    BrowserWithTestWindowTest::TearDown();
90  }
91
92  MessageCenterNotificationManager* notification_manager() {
93    return (MessageCenterNotificationManager*)
94        g_browser_process->notification_ui_manager();
95  }
96
97  FakeMessageCenterTrayDelegate* delegate() { return delegate_; }
98
99  MessageCenter* message_center() { return message_center_; }
100
101  const ::Notification GetANotification(const std::string& id) {
102    return ::Notification(
103        GURL("chrome-extension://adflkjsdflkdsfdsflkjdsflkdjfs"),
104        GURL(),
105        base::string16(),
106        base::string16(),
107        blink::WebTextDirectionDefault,
108        base::string16(),
109        base::UTF8ToUTF16(id),
110        new MockNotificationDelegate(id));
111  }
112
113  base::RunLoop* run_loop() { return run_loop_.get(); }
114  PrefService* local_state() {
115    return TestingBrowserProcess::GetGlobal()->local_state();
116  }
117  bool DidFirstRunPref() { return first_run_pref_->GetValue(); }
118
119 private:
120  scoped_ptr<TestingProfileManager> profile_manager_;
121  scoped_ptr<base::RunLoop> run_loop_;
122  MessageCenter* message_center_;
123  std::vector<Notifier*> notifiers_;
124  FakeMessageCenterTrayDelegate* delegate_;
125  scoped_ptr<BooleanPrefMember> first_run_pref_;
126};
127
128TEST_F(MessageCenterNotificationManagerTest, SetupNotificationManager) {
129  TestingProfile profile;
130  notification_manager()->Add(GetANotification("test"), &profile);
131  EXPECT_FALSE(DidFirstRunPref());
132}
133
134TEST_F(MessageCenterNotificationManagerTest, UpdateNotification) {
135  TestingProfile profile;
136  EXPECT_TRUE(message_center()->NotificationCount() == 0);
137  notification_manager()->Add(GetANotification("test"), &profile);
138  EXPECT_TRUE(message_center()->NotificationCount() == 1);
139  ASSERT_TRUE(
140      notification_manager()->Update(GetANotification("test"), &profile));
141  EXPECT_TRUE(message_center()->NotificationCount() == 1);
142}
143
144#if defined(OS_CHROMEOS)
145TEST_F(MessageCenterNotificationManagerTest, MultiUserUpdates) {
146  TestingProfile profile;
147  std::string active_user_id = multi_user_util::GetUserIDFromProfile(&profile);
148  chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager =
149      new chrome::MultiUserWindowManagerChromeOS(active_user_id);
150  chrome::MultiUserWindowManager::SetInstanceForTest(
151      multi_user_window_manager,
152      chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED);
153  scoped_ptr<MultiUserNotificationBlockerChromeOS> blocker(
154      new MultiUserNotificationBlockerChromeOS(
155          message_center::MessageCenter::Get(),
156          active_user_id));
157  EXPECT_EQ(0u, message_center()->NotificationCount());
158  notification_manager()->Add(GetANotification("test"), &profile);
159  EXPECT_EQ(1u, message_center()->NotificationCount());
160  notification_manager()->Update(GetANotification("test"), &profile);
161  EXPECT_EQ(1u, message_center()->NotificationCount());
162  chrome::MultiUserWindowManager::DeleteInstance();
163}
164#endif
165
166#if defined(OS_WIN)
167// The following tests test the first run balloon, which is only implemented for
168// Windows.
169TEST_F(MessageCenterNotificationManagerTest, FirstRunShown) {
170  TestingProfile profile;
171  notification_manager()->Add(GetANotification("test"), &profile);
172  message_center()->DisplayedNotification(
173      "test", message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
174  message_center()->MarkSinglePopupAsShown("test", false);
175
176  run_loop()->Run();
177  base::RunLoop run_loop_2;
178  run_loop_2.RunUntilIdle();
179  EXPECT_TRUE(delegate()->displayed_first_run_balloon());
180  EXPECT_TRUE(DidFirstRunPref());
181}
182
183TEST_F(MessageCenterNotificationManagerTest,
184       FirstRunNotShownWithPopupsVisible) {
185  TestingProfile profile;
186  notification_manager()->Add(GetANotification("test"), &profile);
187  message_center()->DisplayedNotification(
188      "test", message_center::DISPLAY_SOURCE_MESSAGE_CENTER);
189  run_loop()->RunUntilIdle();
190  EXPECT_FALSE(delegate()->displayed_first_run_balloon());
191  EXPECT_FALSE(notification_manager()->FirstRunTimerIsActive());
192  EXPECT_FALSE(DidFirstRunPref());
193}
194
195TEST_F(MessageCenterNotificationManagerTest,
196       FirstRunNotShownWithMessageCenter) {
197  TestingProfile profile;
198  notification_manager()->Add(GetANotification("test"), &profile);
199  message_center()->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER);
200  run_loop()->RunUntilIdle();
201  EXPECT_FALSE(notification_manager()->FirstRunTimerIsActive());
202  EXPECT_FALSE(DidFirstRunPref());
203}
204
205#endif
206}  // namespace message_center
207