- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / subscribe_page_action_browsertest.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 "chrome/browser/extensions/extension_browsertest.h"
6 #include "chrome/browser/ui/browser.h"
7 #include "chrome/browser/ui/tabs/tab_strip_model.h"
8 #include "chrome/common/extensions/extension.h"
9 #include "chrome/common/url_constants.h"
10 #include "chrome/test/base/ui_test_utils.h"
11 #include "content/public/browser/web_contents.h"
12 #include "content/public/test/browser_test_utils.h"
13 #include "extensions/common/constants.h"
14
15 using content::WebContents;
16 using extensions::Extension;
17
18 namespace {
19
20 const char kSubscribePage[] = "/subscribe.html";
21 const char kFeedPageMultiRel[] = "files/feeds/feed_multi_rel.html";
22 const char kValidFeedNoLinks[] = "files/feeds/feed_nolinks.xml";
23 const char kValidFeed0[] = "files/feeds/feed_script.xml";
24 const char kValidFeed1[] = "files/feeds/feed1.xml";
25 const char kValidFeed2[] = "files/feeds/feed2.xml";
26 const char kValidFeed3[] = "files/feeds/feed3.xml";
27 const char kValidFeed4[] = "files/feeds/feed4.xml";
28 const char kValidFeed5[] = "files/feeds/feed5.xml";
29 const char kValidFeed6[] = "files/feeds/feed6.xml";
30 const char kInvalidFeed1[] = "files/feeds/feed_invalid1.xml";
31 const char kInvalidFeed2[] = "files/feeds/feed_invalid2.xml";
32 // We need a triple encoded string to prove that we are not decoding twice in
33 // subscribe.js because one layer is also stripped off when subscribe.js passes
34 // it to the XMLHttpRequest object.
35 const char kFeedTripleEncoded[] = "files/feeds/url%25255Fdecoding.html";
36
37 static const char kScriptFeedTitle[] =
38     "window.domAutomationController.send("
39     "  document.getElementById('title') ? "
40     "    document.getElementById('title').textContent : "
41     "    \"element 'title' not found\""
42     ");";
43 static const char kScriptAnchor[] =
44     "window.domAutomationController.send("
45     "  document.getElementById('anchor_0') ? "
46     "    document.getElementById('anchor_0').textContent : "
47     "    \"element 'anchor_0' not found\""
48     ");";
49 static const char kScriptDesc[] =
50     "window.domAutomationController.send("
51     "  document.getElementById('desc_0') ? "
52     "    document.getElementById('desc_0').textContent : "
53     "    \"element 'desc_0' not found\""
54     ");";
55 static const char kScriptError[] =
56     "window.domAutomationController.send("
57     "  document.getElementById('error') ? "
58     "    document.getElementById('error').textContent : "
59     "    \"No error\""
60     ");";
61
62 GURL GetFeedUrl(net::SpawnedTestServer* server, const std::string& feed_page,
63                 bool direct_url, std::string extension_id) {
64   GURL feed_url = server->GetURL(feed_page);
65   if (direct_url) {
66     // We navigate directly to the subscribe page for feeds where the feed
67     // sniffing won't work, in other words, as is the case for malformed feeds.
68     return GURL(std::string(extensions::kExtensionScheme) +
69         content::kStandardSchemeSeparator +
70         extension_id + std::string(kSubscribePage) + std::string("?") +
71         feed_url.spec() + std::string("&synchronous"));
72   } else {
73     // Navigate to the feed content (which will cause the extension to try to
74     // sniff the type and display the subscribe page in another tab.
75     return GURL(feed_url.spec());
76   }
77 }
78
79 bool ValidatePageElement(WebContents* tab,
80                          const std::string& frame_xpath,
81                          const std::string& javascript,
82                          const std::string& expected_value) {
83   std::string returned_value;
84
85   if (!content::ExecuteScriptInFrameAndExtractString(tab, frame_xpath,
86                                                      javascript,
87                                                      &returned_value))
88     return false;
89
90   EXPECT_STREQ(expected_value.c_str(), returned_value.c_str());
91   return expected_value == returned_value;
92 }
93
94 // Navigates to a feed page and, if |sniff_xml_type| is set, wait for the
95 // extension to kick in, detect the feed and redirect to a feed preview page.
96 // |sniff_xml_type| is generally set to true if the feed is sniffable and false
97 // for invalid feeds.
98 void NavigateToFeedAndValidate(net::SpawnedTestServer* server,
99                                const std::string& url,
100                                Browser* browser,
101                                std::string extension_id,
102                                bool sniff_xml_type,
103                                const std::string& expected_feed_title,
104                                const std::string& expected_item_title,
105                                const std::string& expected_item_desc,
106                                const std::string& expected_error) {
107   if (sniff_xml_type) {
108     // TODO(finnur): Implement this is a non-flaky way.
109   }
110
111   // Navigate to the subscribe page directly.
112   ui_test_utils::NavigateToURL(browser,
113                                GetFeedUrl(server, url, true, extension_id));
114
115   WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
116   ASSERT_TRUE(ValidatePageElement(
117       tab, std::string(), kScriptFeedTitle, expected_feed_title));
118   ASSERT_TRUE(ValidatePageElement(tab,
119                                   "//html/body/div/iframe[1]",
120                                   kScriptAnchor,
121                                   expected_item_title));
122   ASSERT_TRUE(ValidatePageElement(tab,
123                                   "//html/body/div/iframe[1]",
124                                   kScriptDesc,
125                                   expected_item_desc));
126   ASSERT_TRUE(ValidatePageElement(tab,
127                                   "//html/body/div/iframe[1]",
128                                   kScriptError,
129                                   expected_error));
130 }
131
132 } // namespace
133
134 // Makes sure that the RSS detects RSS feed links, even when rel tag contains
135 // more than just "alternate".
136 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSMultiRelLink) {
137   ASSERT_TRUE(test_server()->Start());
138
139   ASSERT_TRUE(LoadExtension(
140     test_data_dir_.AppendASCII("subscribe_page_action")));
141
142   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
143
144   // Navigate to the feed page.
145   GURL feed_url = test_server()->GetURL(kFeedPageMultiRel);
146   ui_test_utils::NavigateToURL(browser(), feed_url);
147   // We should now have one page action ready to go in the LocationBar.
148   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
149 }
150
151 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed1) {
152   ASSERT_TRUE(test_server()->Start());
153
154   const Extension* extension = LoadExtension(
155       test_data_dir_.AppendASCII("subscribe_page_action"));
156   ASSERT_TRUE(extension);
157   std::string id = extension->id();
158
159   NavigateToFeedAndValidate(test_server(), kValidFeed1, browser(), id, true,
160                             "Feed for MyFeedTitle",
161                             "Title 1",
162                             "Desc",
163                             "No error");
164 }
165
166 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed2) {
167   ASSERT_TRUE(test_server()->Start());
168
169   const Extension* extension = LoadExtension(
170       test_data_dir_.AppendASCII("subscribe_page_action"));
171   ASSERT_TRUE(extension);
172   std::string id = extension->id();
173
174   NavigateToFeedAndValidate(test_server(), kValidFeed2, browser(), id, true,
175                             "Feed for MyFeed2",
176                             "My item title1",
177                             "This is a summary.",
178                             "No error");
179 }
180
181 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed3) {
182   ASSERT_TRUE(test_server()->Start());
183
184   const Extension* extension = LoadExtension(
185       test_data_dir_.AppendASCII("subscribe_page_action"));
186   ASSERT_TRUE(extension);
187   std::string id = extension->id();
188
189   NavigateToFeedAndValidate(test_server(), kValidFeed3, browser(), id, true,
190                             "Feed for Google Code buglist rss feed",
191                             "My dear title",
192                             "My dear content",
193                             "No error");
194 }
195
196 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed4) {
197   ASSERT_TRUE(test_server()->Start());
198
199   const Extension* extension = LoadExtension(
200       test_data_dir_.AppendASCII("subscribe_page_action"));
201   ASSERT_TRUE(extension);
202   std::string id = extension->id();
203
204   NavigateToFeedAndValidate(test_server(), kValidFeed4, browser(), id, true,
205                             "Feed for Title chars <script> %23 stop",
206                             "Title chars  %23 stop",
207                             "My dear content %23 stop",
208                             "No error");
209 }
210
211 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed0) {
212   ASSERT_TRUE(test_server()->Start());
213
214   const Extension* extension = LoadExtension(
215       test_data_dir_.AppendASCII("subscribe_page_action"));
216   ASSERT_TRUE(extension);
217   std::string id = extension->id();
218
219   // Try a feed with a link with an onclick handler (before r27440 this would
220   // trigger a NOTREACHED).
221   NavigateToFeedAndValidate(test_server(), kValidFeed0, browser(), id, true,
222                             "Feed for MyFeedTitle",
223                             "Title 1",
224                             "Desc VIDEO",
225                             "No error");
226 }
227
228 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed5) {
229   ASSERT_TRUE(test_server()->Start());
230
231   const Extension* extension = LoadExtension(
232       test_data_dir_.AppendASCII("subscribe_page_action"));
233   ASSERT_TRUE(extension);
234   std::string id = extension->id();
235
236   // Feed with valid but mostly empty xml.
237   NavigateToFeedAndValidate(test_server(), kValidFeed5, browser(), id, true,
238                             "Feed for Unknown feed name",
239                             "element 'anchor_0' not found",
240                             "element 'desc_0' not found",
241                             "This feed contains no entries.");
242 }
243
244 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeed6) {
245   ASSERT_TRUE(test_server()->Start());
246
247   const Extension* extension = LoadExtension(
248       test_data_dir_.AppendASCII("subscribe_page_action"));
249   ASSERT_TRUE(extension);
250   std::string id = extension->id();
251
252   // Feed that is technically invalid but still parseable.
253   NavigateToFeedAndValidate(test_server(), kValidFeed6, browser(), id, true,
254                             "Feed for MyFeedTitle",
255                             "Title 1",
256                             "Desc",
257                             "No error");
258 }
259
260 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed1) {
261   ASSERT_TRUE(test_server()->Start());
262
263   const Extension* extension = LoadExtension(
264       test_data_dir_.AppendASCII("subscribe_page_action"));
265   ASSERT_TRUE(extension);
266   std::string id = extension->id();
267
268   // Try an empty feed.
269   NavigateToFeedAndValidate(test_server(), kInvalidFeed1, browser(), id, false,
270                             "Feed for Unknown feed name",
271                             "element 'anchor_0' not found",
272                             "element 'desc_0' not found",
273                             "This feed contains no entries.");
274 }
275
276 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed2) {
277   ASSERT_TRUE(test_server()->Start());
278
279   const Extension* extension = LoadExtension(
280       test_data_dir_.AppendASCII("subscribe_page_action"));
281   ASSERT_TRUE(extension);
282   std::string id = extension->id();
283
284   // Try a garbage feed.
285   NavigateToFeedAndValidate(test_server(), kInvalidFeed2, browser(), id, false,
286                             "Feed for Unknown feed name",
287                             "element 'anchor_0' not found",
288                             "element 'desc_0' not found",
289                             "This feed contains no entries.");
290 }
291
292 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed3) {
293   ASSERT_TRUE(test_server()->Start());
294
295   const Extension* extension = LoadExtension(
296       test_data_dir_.AppendASCII("subscribe_page_action"));
297   ASSERT_TRUE(extension);
298   std::string id = extension->id();
299
300   // Try a feed that doesn't exist.
301   NavigateToFeedAndValidate(test_server(), "foo.xml", browser(), id, false,
302                             "Feed for Unknown feed name",
303                             "element 'anchor_0' not found",
304                             "element 'desc_0' not found",
305                             "This feed contains no entries.");
306 }
307
308 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedInvalidFeed4) {
309   ASSERT_TRUE(test_server()->Start());
310
311   const Extension* extension = LoadExtension(
312       test_data_dir_.AppendASCII("subscribe_page_action"));
313   ASSERT_TRUE(extension);
314   std::string id = extension->id();
315
316   // subscribe.js shouldn't double-decode the URL passed in. Otherwise feed
317   // links such as http://search.twitter.com/search.atom?lang=en&q=%23chrome
318   // will result in no feed being downloaded because %23 gets decoded to # and
319   // therefore #chrome is not treated as part of the Twitter query. This test
320   // uses an underscore instead of a hash, but the principle is the same. If
321   // we start erroneously double decoding again, the path (and the feed) will
322   // become valid resulting in a failure for this test.
323   NavigateToFeedAndValidate(
324       test_server(), kFeedTripleEncoded, browser(), id, true,
325       "Feed for Unknown feed name",
326       "element 'anchor_0' not found",
327       "element 'desc_0' not found",
328       "This feed contains no entries.");
329 }
330
331 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, ParseFeedValidFeedNoLinks) {
332   ASSERT_TRUE(test_server()->Start());
333
334   const Extension* extension = LoadExtension(
335       test_data_dir_.AppendASCII("subscribe_page_action"));
336   ASSERT_TRUE(extension);
337   std::string id = extension->id();
338
339   // Valid feed but containing no links.
340   NavigateToFeedAndValidate(
341       test_server(), kValidFeedNoLinks, browser(), id, true,
342       "Feed for MyFeedTitle",
343       "Title with no link",
344       "Desc",
345       "No error");
346 }