Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / notifications / extension_welcome_notification_unittest.cc
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 "chrome/browser/notifications/extension_welcome_notification.h"
6
7 #include <string>
8
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 "base/test/test_simple_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "chrome/browser/notifications/notification.h"
16 #include "chrome/common/pref_names.h"
17 #include "chrome/test/base/testing_pref_service_syncable.h"
18 #include "chrome/test/base/testing_profile.h"
19 #include "components/user_prefs/pref_registry_syncable.h"
20 #include "sync/api/sync_error_factory_mock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/message_center/fake_message_center.h"
23 #include "ui/message_center/notification.h"
24
25 const char kChromeNowExtensionID[] = "pafkbggdmjlpgkdkcbjmhmfcdpncadgh";
26
27 class MockMessageCenter : public message_center::FakeMessageCenter {
28  public:
29   MockMessageCenter()
30       : add_notification_calls_(0),
31         remove_notification_calls_(0),
32         notifications_with_shown_as_popup_(0) {
33   }
34
35   int add_notification_calls() { return add_notification_calls_; }
36   int remove_notification_calls() { return remove_notification_calls_; }
37   int notifications_with_shown_as_popup() {
38     return notifications_with_shown_as_popup_;
39   }
40
41   // message_center::FakeMessageCenter Overrides
42   virtual bool HasNotification(const std::string& id) OVERRIDE {
43     return last_notification.get() && (last_notification->id() == id);
44   }
45
46   virtual void AddNotification(
47       scoped_ptr<message_center::Notification> notification) OVERRIDE {
48     EXPECT_FALSE(last_notification.get());
49     last_notification.swap(notification);
50     add_notification_calls_++;
51     if (last_notification->shown_as_popup())
52       notifications_with_shown_as_popup_++;
53   }
54
55   virtual void RemoveNotification(const std::string& id,
56                                   bool by_user) OVERRIDE {
57     EXPECT_TRUE(last_notification.get());
58     last_notification.reset();
59     remove_notification_calls_++;
60   }
61
62   void CloseCurrentNotification() {
63     EXPECT_TRUE(last_notification.get());
64     last_notification->delegate()->Close(true);
65     RemoveNotification(last_notification->id(), true);
66   }
67
68  private:
69   scoped_ptr<message_center::Notification> last_notification;
70   int add_notification_calls_;
71   int remove_notification_calls_;
72   int notifications_with_shown_as_popup_;
73
74   DISALLOW_COPY_AND_ASSIGN(MockMessageCenter);
75 };
76
77 class WelcomeNotificationDelegate
78     : public ExtensionWelcomeNotification::Delegate {
79 public:
80   WelcomeNotificationDelegate()
81       : start_time_(base::Time::Now()),
82         message_center_(new MockMessageCenter()) {
83   }
84
85   // ExtensionWelcomeNotification::Delegate
86   virtual message_center::MessageCenter* GetMessageCenter() OVERRIDE {
87     return message_center_.get();
88   }
89
90   virtual base::Time GetCurrentTime() OVERRIDE {
91     return start_time_ + elapsed_time_;
92   }
93
94   virtual void PostTask(
95       const tracked_objects::Location& from_here,
96       const base::Closure& task) OVERRIDE {
97     EXPECT_TRUE(pending_task_.is_null());
98     pending_task_ = task;
99   }
100
101   // WelcomeNotificationDelegate
102   MockMessageCenter* message_center() const { return message_center_.get(); }
103
104   base::Time GetStartTime() const { return start_time_; }
105
106   void SetElapsedTime(base::TimeDelta elapsed_time) {
107     elapsed_time_ = elapsed_time;
108   }
109
110   void RunPendingTask() {
111     base::Closure task_to_run = pending_task_;
112     pending_task_.Reset();
113     task_to_run.Run();
114   }
115
116  private:
117   const base::Time start_time_;
118   base::TimeDelta elapsed_time_;
119   scoped_ptr<MockMessageCenter> message_center_;
120   base::Closure pending_task_;
121
122   DISALLOW_COPY_AND_ASSIGN(WelcomeNotificationDelegate);
123 };
124
125 class TestSyncProcessor : public syncer::SyncChangeProcessor {
126  public:
127   TestSyncProcessor() {}
128
129   virtual syncer::SyncError ProcessSyncChanges(
130       const tracked_objects::Location& from_here,
131       const syncer::SyncChangeList& change_list) OVERRIDE {
132     return syncer::SyncError();
133   }
134
135   virtual syncer::SyncDataList GetAllSyncData(syncer::ModelType type)
136       const OVERRIDE {
137     return syncer::SyncDataList();
138   }
139
140  private:
141   DISALLOW_COPY_AND_ASSIGN(TestSyncProcessor);
142 };
143
144 class ExtensionWelcomeNotificationTest : public testing::Test {
145  protected:
146   ExtensionWelcomeNotificationTest() {
147     scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry(
148         new user_prefs::PrefRegistrySyncable());
149     ExtensionWelcomeNotification::RegisterProfilePrefs(pref_registry.get());
150   }
151
152   virtual void SetUp() {
153     task_runner_ = new base::TestSimpleTaskRunner();
154     thread_task_runner_handle_.reset(
155         new base::ThreadTaskRunnerHandle(task_runner_));
156     profile_.reset(new TestingProfile());
157     delegate_ = new WelcomeNotificationDelegate();
158     welcome_notification_ = ExtensionWelcomeNotification::Create(
159         kChromeNowExtensionID, profile_.get(), delegate_);
160   }
161
162   virtual void TearDown() {
163     delegate_ = NULL;
164     welcome_notification_.reset();
165     profile_.reset();
166     thread_task_runner_handle_.reset();
167     task_runner_ = NULL;
168   }
169
170   void StartPreferenceSyncing() const {
171     PrefServiceSyncable::FromProfile(profile_.get())
172         ->GetSyncableService(syncer::PREFERENCES)
173         ->MergeDataAndStartSyncing(
174               syncer::PREFERENCES,
175               syncer::SyncDataList(),
176               scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessor),
177               scoped_ptr<syncer::SyncErrorFactory>(
178                   new syncer::SyncErrorFactoryMock()));
179   }
180
181   void ShowChromeNowNotification() const {
182     ShowNotification(
183         "ChromeNowNotification",
184         message_center::NotifierId(message_center::NotifierId::APPLICATION,
185                                    kChromeNowExtensionID));
186   }
187
188   void ShowRegularNotification() const {
189     ShowNotification(
190         "RegularNotification",
191         message_center::NotifierId(message_center::NotifierId::APPLICATION,
192                                    "aaaabbbbccccddddeeeeffffggghhhhi"));
193   }
194
195   void FlushMessageLoop() { delegate_->RunPendingTask(); }
196
197   MockMessageCenter* message_center() const {
198     return delegate_->message_center();
199   }
200   base::TestSimpleTaskRunner* task_runner() const {
201     return task_runner_.get();
202   }
203   base::Time GetStartTime() const {
204     return delegate_->GetStartTime();
205   }
206   void SetElapsedTime(base::TimeDelta elapsed_time) const {
207     delegate_->SetElapsedTime(elapsed_time);
208   }
209   bool GetBooleanPref(const char* path) const {
210     return profile_->GetPrefs()->GetBoolean(path);
211   }
212   void SetBooleanPref(const char* path, bool value) const {
213     profile_->GetPrefs()->SetBoolean(path, value);
214   }
215   int64 GetInt64Pref(const char* path) const {
216     return profile_->GetPrefs()->GetInt64(path);
217   }
218   void SetInt64Pref(const char* path, int64 value) const {
219     profile_->GetPrefs()->SetInt64(path, value);
220   }
221
222  private:
223   class TestNotificationDelegate : public NotificationDelegate {
224    public:
225     explicit TestNotificationDelegate(const std::string& id) : id_(id) {}
226
227     // Overridden from NotificationDelegate:
228     virtual void Display() OVERRIDE {}
229     virtual void Error() OVERRIDE {}
230     virtual void Close(bool by_user) OVERRIDE {}
231     virtual void Click() OVERRIDE {}
232     virtual void ButtonClick(int index) OVERRIDE {}
233
234     virtual std::string id() const OVERRIDE { return id_; }
235
236     virtual content::RenderViewHost* GetRenderViewHost() const OVERRIDE {
237       return NULL;
238     }
239
240    private:
241     virtual ~TestNotificationDelegate() {}
242
243     const std::string id_;
244
245     DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate);
246   };
247
248   void ShowNotification(std::string notification_id,
249                         const message_center::NotifierId& notifier_id) const {
250     message_center::RichNotificationData rich_notification_data;
251     rich_notification_data.priority = 0;
252     Notification notification(message_center::NOTIFICATION_TYPE_BASE_FORMAT,
253                               GURL("http://tests.url"),
254                               base::UTF8ToUTF16("Title"),
255                               base::UTF8ToUTF16("Body"),
256                               gfx::Image(),
257                               blink::WebTextDirectionDefault,
258                               notifier_id,
259                               base::UTF8ToUTF16("Source"),
260                               base::UTF8ToUTF16(notification_id),
261                               rich_notification_data,
262                               new TestNotificationDelegate("TestNotification"));
263     welcome_notification_->ShowWelcomeNotificationIfNecessary(notification);
264   }
265
266   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
267   scoped_ptr<base::ThreadTaskRunnerHandle> thread_task_runner_handle_;
268   scoped_ptr<TestingProfile> profile_;
269   // Weak Ref owned by welcome_notification_
270   WelcomeNotificationDelegate* delegate_;
271   scoped_ptr<ExtensionWelcomeNotification> welcome_notification_;
272
273   DISALLOW_COPY_AND_ASSIGN(ExtensionWelcomeNotificationTest);
274 };
275
276 // Show a regular notification. Expect that WelcomeNotification will
277 // not show a welcome notification.
278 TEST_F(ExtensionWelcomeNotificationTest, FirstRunShowRegularNotification) {
279   StartPreferenceSyncing();
280   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
281   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
282
283   ShowRegularNotification();
284
285   EXPECT_EQ(message_center()->add_notification_calls(), 0);
286   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
287   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
288   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
289   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
290 }
291
292 // Show a Chrome Now notification. Expect that WelcomeNotification will
293 // show a welcome notification.
294 TEST_F(ExtensionWelcomeNotificationTest, FirstRunChromeNowNotification) {
295   StartPreferenceSyncing();
296   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
297   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
298
299   ShowChromeNowNotification();
300
301   EXPECT_EQ(message_center()->add_notification_calls(), 1);
302   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
303   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
304   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
305   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
306 }
307
308 // Show a Chrome Now notification that was already shown before.
309 TEST_F(ExtensionWelcomeNotificationTest, ShowWelcomeNotificationAgain) {
310   StartPreferenceSyncing();
311   SetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
312   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
313   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
314
315   ShowChromeNowNotification();
316
317   EXPECT_EQ(message_center()->add_notification_calls(), 1);
318   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
319   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 1);
320   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
321   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
322 }
323
324 // Don't show a welcome notification if it was previously dismissed
325 TEST_F(ExtensionWelcomeNotificationTest,
326        WelcomeNotificationPreviouslyDismissed) {
327   StartPreferenceSyncing();
328   SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
329   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
330   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
331
332   ShowChromeNowNotification();
333
334   EXPECT_EQ(message_center()->add_notification_calls(), 0);
335   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
336   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
337   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
338   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
339 }
340
341 // Show a Chrome Now notification and dismiss it.
342 // Expect welcome toast dismissed to be true.
343 TEST_F(ExtensionWelcomeNotificationTest, DismissWelcomeNotification) {
344   StartPreferenceSyncing();
345   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
346   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
347
348   ShowChromeNowNotification();
349   message_center()->CloseCurrentNotification();
350   FlushMessageLoop();
351
352   EXPECT_EQ(message_center()->add_notification_calls(), 1);
353   EXPECT_EQ(message_center()->remove_notification_calls(), 1);
354   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
355   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
356   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
357 }
358
359 // Show a Chrome Now notification and dismiss it via a synced preference change.
360 // Expect welcome toast dismissed to be true.
361 TEST_F(ExtensionWelcomeNotificationTest, SyncedDismissalWelcomeNotification) {
362   StartPreferenceSyncing();
363   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
364   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
365
366   ShowChromeNowNotification();
367   SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
368
369   EXPECT_EQ(message_center()->add_notification_calls(), 1);
370   EXPECT_EQ(message_center()->remove_notification_calls(), 1);
371   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
372   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
373   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
374 }
375
376 // Simulate a delayed preference sync when the welcome notification was
377 // previously dismissed.
378 TEST_F(ExtensionWelcomeNotificationTest,
379        DelayedPreferenceSyncPreviouslyDismissed) {
380   // Show a notification while the preference system is not syncing.
381   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
382   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
383
384   ShowChromeNowNotification();
385
386   EXPECT_EQ(message_center()->add_notification_calls(), 0);
387   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
388   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
389   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
390   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
391
392   // Now start the preference syncing with a previously dismissed welcome.
393   SetBooleanPref(prefs::kWelcomeNotificationDismissed, true);
394   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
395   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
396
397   StartPreferenceSyncing();
398
399   EXPECT_EQ(message_center()->add_notification_calls(), 0);
400   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
401   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
402   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
403   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
404 }
405
406 // Simulate a delayed preference sync when the welcome notification was
407 // never shown.
408 TEST_F(ExtensionWelcomeNotificationTest, DelayedPreferenceSyncNeverShown) {
409   // Show a notification while the preference system is not syncing.
410   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
411   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
412
413   ShowChromeNowNotification();
414
415   EXPECT_EQ(message_center()->add_notification_calls(), 0);
416   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
417   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
418   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
419   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
420
421   // Now start the preference syncing with the default preference values.
422   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
423   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
424
425   StartPreferenceSyncing();
426
427   EXPECT_EQ(message_center()->add_notification_calls(), 1);
428   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
429   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
430   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
431   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
432 }
433
434 // Simulate the passage of time when the welcome notification
435 // automatically dismisses.
436 TEST_F(ExtensionWelcomeNotificationTest, TimeExpiredNotification) {
437   StartPreferenceSyncing();
438   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
439   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
440   EXPECT_EQ(GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp), 0);
441   EXPECT_TRUE(task_runner()->GetPendingTasks().empty());
442
443   ShowChromeNowNotification();
444
445   base::TimeDelta requested_show_time =
446       base::TimeDelta::FromDays(
447           ExtensionWelcomeNotification::kRequestedShowTimeDays);
448
449   EXPECT_EQ(task_runner()->GetPendingTasks().size(), 1U);
450   EXPECT_EQ(task_runner()->NextPendingTaskDelay(), requested_show_time);
451
452   EXPECT_EQ(message_center()->add_notification_calls(), 1);
453   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
454   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
455   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
456   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
457   EXPECT_EQ(
458       GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp),
459       (GetStartTime() + requested_show_time).ToInternalValue());
460
461   SetElapsedTime(requested_show_time);
462   task_runner()->RunPendingTasks();
463
464   EXPECT_TRUE(task_runner()->GetPendingTasks().empty());
465   EXPECT_EQ(message_center()->add_notification_calls(), 1);
466   EXPECT_EQ(message_center()->remove_notification_calls(), 1);
467   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
468   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
469   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
470   EXPECT_EQ(
471       GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp),
472       (GetStartTime() + requested_show_time).ToInternalValue());
473 }
474
475 // Simulate the passage of time after Chrome is closed and the welcome
476 // notification expiration elapses.
477 TEST_F(ExtensionWelcomeNotificationTest, NotificationPreviouslyExpired) {
478   StartPreferenceSyncing();
479   SetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp, true);
480   SetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp, 1);
481   EXPECT_FALSE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
482   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
483   EXPECT_EQ(GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp), 1);
484   EXPECT_TRUE(task_runner()->GetPendingTasks().empty());
485
486   const base::TimeDelta requested_show_time =
487       base::TimeDelta::FromDays(
488           ExtensionWelcomeNotification::kRequestedShowTimeDays);
489   SetElapsedTime(requested_show_time);
490   ShowChromeNowNotification();
491
492   EXPECT_TRUE(task_runner()->GetPendingTasks().empty());
493   EXPECT_EQ(message_center()->add_notification_calls(), 0);
494   EXPECT_EQ(message_center()->remove_notification_calls(), 0);
495   EXPECT_EQ(message_center()->notifications_with_shown_as_popup(), 0);
496   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationDismissed));
497   EXPECT_TRUE(GetBooleanPref(prefs::kWelcomeNotificationPreviouslyPoppedUp));
498   EXPECT_EQ(GetInt64Pref(prefs::kWelcomeNotificationExpirationTimestamp), 1);
499 }
500
501 // C++ Readability Review Change Trigger