1 // Copyright 2013 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 "chrome/browser/notifications/welcome_notification.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/notifications/notification.h"
14 #include "chrome/common/pref_names.h"
15 #include "chrome/test/base/testing_pref_service_syncable.h"
16 #include "chrome/test/base/testing_profile.h"
17 #include "components/user_prefs/pref_registry_syncable.h"
18 #include "sync/api/sync_error_factory_mock.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 #include "ui/message_center/fake_message_center.h"
21 #include "ui/message_center/notification.h"
23 const char kChromeNowExtensionID
[] = "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
25 class MockMessageCenter
: public message_center::FakeMessageCenter
{
28 : add_notification_calls_(0),
29 remove_notification_calls_(0),
30 notifications_with_shown_as_popup_(0) {};
32 int add_notification_calls() { return add_notification_calls_
; }
33 int remove_notification_calls() { return remove_notification_calls_
; }
34 int notifications_with_shown_as_popup() {
35 return notifications_with_shown_as_popup_
;
38 // message_center::FakeMessageCenter Overrides
39 virtual bool HasNotification(const std::string
& id
) OVERRIDE
{
40 return last_notification
.get() &&
41 (last_notification
->id() == id
);
44 virtual void AddNotification(
45 scoped_ptr
<message_center::Notification
> notification
) OVERRIDE
{
46 EXPECT_FALSE(last_notification
.get());
47 last_notification
.swap(notification
);
48 add_notification_calls_
++;
49 if (last_notification
->shown_as_popup())
50 notifications_with_shown_as_popup_
++;
53 virtual void RemoveNotification(const std::string
& id
, bool by_user
)
55 EXPECT_TRUE(last_notification
.get());
56 last_notification
.reset();
57 remove_notification_calls_
++;
60 void CloseCurrentNotification() {
61 EXPECT_TRUE(last_notification
.get());
62 last_notification
->delegate()->Close(true);
63 RemoveNotification(last_notification
->id(), true);
67 scoped_ptr
<message_center::Notification
> last_notification
;
68 int add_notification_calls_
;
69 int remove_notification_calls_
;
70 int notifications_with_shown_as_popup_
;
73 class TestSyncProcessor
: public syncer::SyncChangeProcessor
{
74 virtual syncer::SyncError
ProcessSyncChanges(
75 const tracked_objects::Location
& from_here
,
76 const syncer::SyncChangeList
& change_list
) OVERRIDE
{
77 return syncer::SyncError();
80 virtual syncer::SyncDataList
GetAllSyncData(
81 syncer::ModelType type
) const OVERRIDE
{
82 return syncer::SyncDataList();
86 class WelcomeNotificationTest
: public testing::Test
{
88 WelcomeNotificationTest() {
89 scoped_refptr
<user_prefs::PrefRegistrySyncable
> pref_registry(
90 new user_prefs::PrefRegistrySyncable());
91 WelcomeNotification::RegisterProfilePrefs(pref_registry
.get());
94 virtual void SetUp() {
95 message_loop_
.reset(new base::MessageLoop());
96 profile_
.reset(new TestingProfile());
97 message_center_
.reset(new MockMessageCenter());
98 welcome_notification_
.reset(
99 new WelcomeNotification(profile_
.get(), message_center_
.get()));
102 virtual void TearDown() {
103 welcome_notification_
.reset();
104 message_center_
.reset();
106 message_loop_
.reset();
109 void StartPreferenceSyncing() {
110 PrefServiceSyncable::FromProfile(profile())->GetSyncableService(
111 syncer::PREFERENCES
)->MergeDataAndStartSyncing(
113 syncer::SyncDataList(),
114 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessor
),
115 scoped_ptr
<syncer::SyncErrorFactory
>(
116 new syncer::SyncErrorFactoryMock()));
119 void ShowChromeNowNotification() {
121 "ChromeNowNotification",
122 message_center::NotifierId(
123 message_center::NotifierId::APPLICATION
,
124 kChromeNowExtensionID
));
127 void ShowRegularNotification() {
129 "RegularNotification",
130 message_center::NotifierId(
131 message_center::NotifierId::APPLICATION
,
132 "aaaabbbbccccddddeeeeffffggghhhhi"));
135 void FlushMessageLoop() {
136 message_loop_
->RunUntilIdle();
139 TestingProfile
* profile() { return profile_
.get(); }
140 MockMessageCenter
* message_center() { return message_center_
.get(); }
143 class TestNotificationDelegate
: public NotificationDelegate
{
145 explicit TestNotificationDelegate(const std::string
& id
)
148 // Overridden from NotificationDelegate:
149 virtual void Display() OVERRIDE
{}
150 virtual void Error() OVERRIDE
{}
151 virtual void Close(bool by_user
) OVERRIDE
{}
152 virtual void Click() OVERRIDE
{}
153 virtual void ButtonClick(int index
) OVERRIDE
{}
155 virtual std::string
id() const OVERRIDE
{ return id_
; }
157 virtual content::RenderViewHost
* GetRenderViewHost() const OVERRIDE
{
162 virtual ~TestNotificationDelegate() {}
164 const std::string id_
;
166 DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate
);
169 void ShowNotification(
170 std::string notification_id
,
171 const message_center::NotifierId
& notifier_id
) {
172 message_center::RichNotificationData rich_notification_data
;
173 rich_notification_data
.priority
= 0;
174 Notification
notification(
175 message_center::NOTIFICATION_TYPE_BASE_FORMAT
,
176 GURL("http://tests.url"),
177 base::UTF8ToUTF16("Title"),
178 base::UTF8ToUTF16("Body"),
180 blink::WebTextDirectionDefault
,
182 base::UTF8ToUTF16("Source"),
183 base::UTF8ToUTF16(notification_id
),
184 rich_notification_data
,
185 new TestNotificationDelegate("TestNotification"));
186 welcome_notification_
->ShowWelcomeNotificationIfNecessary(notification
);
189 scoped_ptr
<TestingProfile
> profile_
;
190 scoped_ptr
<MockMessageCenter
> message_center_
;
191 scoped_ptr
<WelcomeNotification
> welcome_notification_
;
192 scoped_ptr
<base::MessageLoop
> message_loop_
;
195 // Show a regular notification. Expect that WelcomeNotification will
196 // not show a welcome notification.
197 TEST_F(WelcomeNotificationTest
, FirstRunShowRegularNotification
) {
198 StartPreferenceSyncing();
200 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
202 profile()->GetPrefs()->GetBoolean(
203 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
205 ShowRegularNotification();
207 EXPECT_TRUE(message_center()->add_notification_calls() == 0);
208 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
209 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
211 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
213 profile()->GetPrefs()->GetBoolean(
214 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
217 // Show a Chrome Now notification. Expect that WelcomeNotification will
218 // show a welcome notification.
219 TEST_F(WelcomeNotificationTest
, FirstRunChromeNowNotification
) {
220 StartPreferenceSyncing();
222 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
224 profile()->GetPrefs()->GetBoolean(
225 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
227 ShowChromeNowNotification();
229 EXPECT_TRUE(message_center()->add_notification_calls() == 1);
230 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
231 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
233 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
235 profile()->GetPrefs()->GetBoolean(
236 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
239 // Show a Chrome Now notification that was already shown before.
240 TEST_F(WelcomeNotificationTest
, ShowWelcomeNotificationAgain
) {
241 StartPreferenceSyncing();
242 profile()->GetPrefs()->SetBoolean(
243 prefs::kWelcomeNotificationPreviouslyPoppedUp
, true);
245 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
247 profile()->GetPrefs()->GetBoolean(
248 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
250 ShowChromeNowNotification();
252 EXPECT_TRUE(message_center()->add_notification_calls() == 1);
253 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
254 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 1);
256 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
258 profile()->GetPrefs()->GetBoolean(
259 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
262 // Don't show a welcome notification if it was previously dismissed
263 TEST_F(WelcomeNotificationTest
, WelcomeNotificationPreviouslyDismissed
) {
264 StartPreferenceSyncing();
265 profile()->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed
, true);
267 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
269 profile()->GetPrefs()->GetBoolean(
270 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
272 ShowChromeNowNotification();
274 EXPECT_TRUE(message_center()->add_notification_calls() == 0);
275 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
276 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
278 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
280 profile()->GetPrefs()->GetBoolean(
281 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
284 // Show a Chrome Now notification and dismiss it.
285 // Expect welcome toast dismissed to be true.
286 TEST_F(WelcomeNotificationTest
, DismissWelcomeNotification
) {
287 StartPreferenceSyncing();
289 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
291 profile()->GetPrefs()->GetBoolean(
292 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
294 ShowChromeNowNotification();
295 message_center()->CloseCurrentNotification();
298 EXPECT_TRUE(message_center()->add_notification_calls() == 1);
299 EXPECT_TRUE(message_center()->remove_notification_calls() == 1);
300 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
302 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
304 profile()->GetPrefs()->GetBoolean(
305 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
308 // Show a Chrome Now notification and dismiss it via a synced preference change.
309 // Expect welcome toast dismissed to be true.
310 TEST_F(WelcomeNotificationTest
, SyncedDismissalWelcomeNotification
) {
311 StartPreferenceSyncing();
313 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
315 profile()->GetPrefs()->GetBoolean(
316 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
318 ShowChromeNowNotification();
319 profile()->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed
, true);
321 EXPECT_TRUE(message_center()->add_notification_calls() == 1);
322 EXPECT_TRUE(message_center()->remove_notification_calls() == 1);
323 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
325 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
327 profile()->GetPrefs()->GetBoolean(
328 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
331 // Simulate a delayed preference sync when the welcome notification was
332 // previously dismissed.
333 TEST_F(WelcomeNotificationTest
, DelayedPreferenceSyncPreviouslyDismissed
) {
334 // Show a notification while the preference system is not syncing.
336 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
338 profile()->GetPrefs()->GetBoolean(
339 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
341 ShowChromeNowNotification();
343 EXPECT_TRUE(message_center()->add_notification_calls() == 0);
344 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
345 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
347 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
349 profile()->GetPrefs()->GetBoolean(
350 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
352 // Now start the preference syncing with a previously dismissed welcome.
353 profile()->GetPrefs()->SetBoolean(prefs::kWelcomeNotificationDismissed
, true);
355 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
357 profile()->GetPrefs()->GetBoolean(
358 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
360 StartPreferenceSyncing();
362 EXPECT_TRUE(message_center()->add_notification_calls() == 0);
363 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
364 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
366 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
368 profile()->GetPrefs()->GetBoolean(
369 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
372 // Simulate a delayed preference sync when the welcome notification was
374 TEST_F(WelcomeNotificationTest
, DelayedPreferenceSyncNeverShown
) {
375 // Show a notification while the preference system is not syncing.
377 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
379 profile()->GetPrefs()->GetBoolean(
380 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
382 ShowChromeNowNotification();
384 EXPECT_TRUE(message_center()->add_notification_calls() == 0);
385 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
386 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
388 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
390 profile()->GetPrefs()->GetBoolean(
391 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
393 // Now start the preference syncing with the default preference values.
395 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
397 profile()->GetPrefs()->GetBoolean(
398 prefs::kWelcomeNotificationPreviouslyPoppedUp
));
400 StartPreferenceSyncing();
402 EXPECT_TRUE(message_center()->add_notification_calls() == 1);
403 EXPECT_TRUE(message_center()->remove_notification_calls() == 0);
404 EXPECT_TRUE(message_center()->notifications_with_shown_as_popup() == 0);
406 profile()->GetPrefs()->GetBoolean(prefs::kWelcomeNotificationDismissed
));
408 profile()->GetPrefs()->GetBoolean(
409 prefs::kWelcomeNotificationPreviouslyPoppedUp
));