Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / notifications / notifications_apitest.cc
1 // Copyright (c) 2012 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/strings/string_number_conversions.h"
6 #include "base/strings/stringprintf.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/browser_process.h"
9 #include "chrome/browser/extensions/api/notifications/notifications_api.h"
10 #include "chrome/browser/extensions/extension_apitest.h"
11 #include "chrome/browser/extensions/extension_function_test_utils.h"
12 #include "chrome/browser/notifications/notification.h"
13 #include "chrome/browser/notifications/notification_ui_manager.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/test/test_utils.h"
16 #include "extensions/browser/api/test/test_api.h"
17 #include "extensions/browser/notification_types.h"
18 #include "extensions/common/features/feature.h"
19 #include "extensions/common/test_util.h"
20 #include "extensions/test/result_catcher.h"
21 #include "ui/message_center/message_center.h"
22 #include "ui/message_center/notification_list.h"
23 #include "ui/message_center/notifier_settings.h"
24
25 using extensions::Extension;
26 using extensions::ResultCatcher;
27
28 namespace utils = extension_function_test_utils;
29
30 namespace {
31
32 // A class that waits for a |chrome.test.sendMessage| call, ignores the message,
33 // and writes down the user gesture status of the message.
34 class UserGestureCatcher : public content::NotificationObserver {
35  public:
36   UserGestureCatcher() : waiting_(false) {
37     registrar_.Add(this,
38                    extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE,
39                    content::NotificationService::AllSources());
40   }
41
42   virtual ~UserGestureCatcher() {}
43
44   bool GetNextResult() {
45     if (results_.empty()) {
46       waiting_ = true;
47       content::RunMessageLoop();
48       waiting_ = false;
49     }
50
51     if (!results_.empty()) {
52       bool ret = results_.front();
53       results_.pop_front();
54       return ret;
55     }
56     NOTREACHED();
57     return false;
58   }
59
60  private:
61   virtual void Observe(int type,
62                        const content::NotificationSource& source,
63                        const content::NotificationDetails& details) OVERRIDE {
64     results_.push_back(
65         static_cast<content::Source<extensions::TestSendMessageFunction> >(
66             source)
67             .ptr()
68             ->user_gesture());
69     if (waiting_)
70       base::MessageLoopForUI::current()->Quit();
71   }
72
73   content::NotificationRegistrar registrar_;
74
75   // A sequential list of user gesture notifications from the test extension(s).
76   std::deque<bool> results_;
77
78   // True if we're in a nested message loop waiting for results from
79   // the extension.
80   bool waiting_;
81 };
82
83 class NotificationsApiTest : public ExtensionApiTest {
84  public:
85   const extensions::Extension* LoadExtensionAndWait(
86       const std::string& test_name) {
87     base::FilePath extdir = test_data_dir_.AppendASCII(test_name);
88     content::WindowedNotificationObserver page_created(
89         extensions::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
90         content::NotificationService::AllSources());
91     const extensions::Extension* extension = LoadExtension(extdir);
92     if (extension) {
93       page_created.Wait();
94     }
95     return extension;
96   }
97 };
98
99 }  // namespace
100
101 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestBasicUsage) {
102   ASSERT_TRUE(RunExtensionTest("notifications/api/basic_usage")) << message_;
103 }
104
105 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestEvents) {
106   ASSERT_TRUE(RunExtensionTest("notifications/api/events")) << message_;
107 }
108
109 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestCSP) {
110   ASSERT_TRUE(RunExtensionTest("notifications/api/csp")) << message_;
111 }
112
113 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestByUser) {
114   const extensions::Extension* extension =
115       LoadExtensionAndWait("notifications/api/by_user");
116   ASSERT_TRUE(extension) << message_;
117
118   {
119     ResultCatcher catcher;
120     g_browser_process->message_center()->RemoveNotification(
121         extension->id() + "-FOO",
122         false);
123     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
124   }
125
126   {
127     ResultCatcher catcher;
128     g_browser_process->message_center()->RemoveNotification(
129         extension->id() + "-BAR",
130         true);
131     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
132   }
133
134   {
135     ResultCatcher catcher;
136     g_browser_process->message_center()->RemoveAllNotifications(false);
137     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
138   }
139   {
140     ResultCatcher catcher;
141     g_browser_process->message_center()->RemoveAllNotifications(true);
142     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
143   }
144 }
145
146 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestPartialUpdate) {
147   ASSERT_TRUE(RunExtensionTest("notifications/api/partial_update")) << message_;
148   const extensions::Extension* extension = GetSingleLoadedExtension();
149   ASSERT_TRUE(extension) << message_;
150
151   const char kNewTitle[] = "Changed!";
152   const char kNewMessage[] = "Too late! The show ended yesterday";
153   int kNewPriority = 2;
154
155   const message_center::NotificationList::Notifications& notifications =
156       g_browser_process->message_center()->GetVisibleNotifications();
157   ASSERT_EQ(1u, notifications.size());
158   message_center::Notification* notification = *(notifications.begin());
159   LOG(INFO) << "Notification ID: " << notification->id();
160
161   EXPECT_EQ(base::ASCIIToUTF16(kNewTitle), notification->title());
162   EXPECT_EQ(base::ASCIIToUTF16(kNewMessage), notification->message());
163   EXPECT_EQ(kNewPriority, notification->priority());
164   EXPECT_EQ(0u, notification->buttons().size());
165 }
166
167 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestGetPermissionLevel) {
168   scoped_refptr<Extension> empty_extension(
169       extensions::test_util::CreateEmptyExtension());
170
171   // Get permission level for the extension whose notifications are enabled.
172   {
173     scoped_refptr<extensions::NotificationsGetPermissionLevelFunction>
174         notification_function(
175             new extensions::NotificationsGetPermissionLevelFunction());
176
177     notification_function->set_extension(empty_extension.get());
178     notification_function->set_has_callback(true);
179
180     scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
181         notification_function.get(),
182         "[]",
183         browser(),
184         utils::NONE));
185
186     EXPECT_EQ(base::Value::TYPE_STRING, result->GetType());
187     std::string permission_level;
188     EXPECT_TRUE(result->GetAsString(&permission_level));
189     EXPECT_EQ("granted", permission_level);
190   }
191
192   // Get permission level for the extension whose notifications are disabled.
193   {
194     scoped_refptr<extensions::NotificationsGetPermissionLevelFunction>
195         notification_function(
196             new extensions::NotificationsGetPermissionLevelFunction());
197
198     notification_function->set_extension(empty_extension.get());
199     notification_function->set_has_callback(true);
200
201     message_center::NotifierId notifier_id(
202         message_center::NotifierId::APPLICATION,
203         empty_extension->id());
204     message_center::Notifier notifier(notifier_id, base::string16(), true);
205     g_browser_process->message_center()->GetNotifierSettingsProvider()->
206         SetNotifierEnabled(notifier, false);
207
208     scoped_ptr<base::Value> result(utils::RunFunctionAndReturnSingleResult(
209         notification_function.get(),
210         "[]",
211         browser(),
212         utils::NONE));
213
214     EXPECT_EQ(base::Value::TYPE_STRING, result->GetType());
215     std::string permission_level;
216     EXPECT_TRUE(result->GetAsString(&permission_level));
217     EXPECT_EQ("denied", permission_level);
218   }
219 }
220
221 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestOnPermissionLevelChanged) {
222   const extensions::Extension* extension =
223       LoadExtensionAndWait("notifications/api/permission");
224   ASSERT_TRUE(extension) << message_;
225
226   // Test permission level changing from granted to denied.
227   {
228     ResultCatcher catcher;
229
230     message_center::NotifierId notifier_id(
231         message_center::NotifierId::APPLICATION,
232         extension->id());
233     message_center::Notifier notifier(notifier_id, base::string16(), true);
234     g_browser_process->message_center()->GetNotifierSettingsProvider()->
235         SetNotifierEnabled(notifier, false);
236
237     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
238   }
239
240   // Test permission level changing from denied to granted.
241   {
242     ResultCatcher catcher;
243
244     message_center::NotifierId notifier_id(
245         message_center::NotifierId::APPLICATION,
246         extension->id());
247     message_center::Notifier notifier(notifier_id, base::string16(), false);
248     g_browser_process->message_center()->GetNotifierSettingsProvider()->
249         SetNotifierEnabled(notifier, true);
250
251     EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
252   }
253 }
254
255 IN_PROC_BROWSER_TEST_F(NotificationsApiTest, TestUserGesture) {
256   const extensions::Extension* extension =
257       LoadExtensionAndWait("notifications/api/user_gesture");
258   ASSERT_TRUE(extension) << message_;
259
260   const message_center::NotificationList::Notifications& notifications =
261       g_browser_process->message_center()->GetVisibleNotifications();
262   ASSERT_EQ(1u, notifications.size());
263   message_center::Notification* notification = *(notifications.begin());
264
265   {
266     UserGestureCatcher catcher;
267     notification->ButtonClick(0);
268     EXPECT_TRUE(catcher.GetNextResult());
269     notification->Click();
270     EXPECT_TRUE(catcher.GetNextResult());
271     notification->Close(true);
272     EXPECT_TRUE(catcher.GetNextResult());
273     notification->Close(false);
274     EXPECT_FALSE(catcher.GetNextResult());
275   }
276 }