Upstream version 5.34.104.0
[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/url_constants.h"
9 #include "chrome/test/base/ui_test_utils.h"
10 #include "content/public/browser/web_contents.h"
11 #include "content/public/test/browser_test_utils.h"
12 #include "extensions/common/constants.h"
13 #include "extensions/common/extension.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 // This test is flaky on all platforms; see http://crbug.com/340354
152 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, DISABLED_RSSParseFeedValidFeed1) {
153   ASSERT_TRUE(test_server()->Start());
154
155   const Extension* extension = LoadExtension(
156       test_data_dir_.AppendASCII("subscribe_page_action"));
157   ASSERT_TRUE(extension);
158   std::string id = extension->id();
159
160   NavigateToFeedAndValidate(test_server(), kValidFeed1, browser(), id, true,
161                             "Feed for MyFeedTitle",
162                             "Title 1",
163                             "Desc",
164                             "No error");
165 }
166
167 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed2) {
168   ASSERT_TRUE(test_server()->Start());
169
170   const Extension* extension = LoadExtension(
171       test_data_dir_.AppendASCII("subscribe_page_action"));
172   ASSERT_TRUE(extension);
173   std::string id = extension->id();
174
175   NavigateToFeedAndValidate(test_server(), kValidFeed2, browser(), id, true,
176                             "Feed for MyFeed2",
177                             "My item title1",
178                             "This is a summary.",
179                             "No error");
180 }
181
182 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed3) {
183   ASSERT_TRUE(test_server()->Start());
184
185   const Extension* extension = LoadExtension(
186       test_data_dir_.AppendASCII("subscribe_page_action"));
187   ASSERT_TRUE(extension);
188   std::string id = extension->id();
189
190   NavigateToFeedAndValidate(test_server(), kValidFeed3, browser(), id, true,
191                             "Feed for Google Code buglist rss feed",
192                             "My dear title",
193                             "My dear content",
194                             "No error");
195 }
196
197 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed4) {
198   ASSERT_TRUE(test_server()->Start());
199
200   const Extension* extension = LoadExtension(
201       test_data_dir_.AppendASCII("subscribe_page_action"));
202   ASSERT_TRUE(extension);
203   std::string id = extension->id();
204
205   NavigateToFeedAndValidate(test_server(), kValidFeed4, browser(), id, true,
206                             "Feed for Title chars <script> %23 stop",
207                             "Title chars  %23 stop",
208                             "My dear content %23 stop",
209                             "No error");
210 }
211
212 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed0) {
213   ASSERT_TRUE(test_server()->Start());
214
215   const Extension* extension = LoadExtension(
216       test_data_dir_.AppendASCII("subscribe_page_action"));
217   ASSERT_TRUE(extension);
218   std::string id = extension->id();
219
220   // Try a feed with a link with an onclick handler (before r27440 this would
221   // trigger a NOTREACHED).
222   NavigateToFeedAndValidate(test_server(), kValidFeed0, browser(), id, true,
223                             "Feed for MyFeedTitle",
224                             "Title 1",
225                             "Desc VIDEO",
226                             "No error");
227 }
228
229 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed5) {
230   ASSERT_TRUE(test_server()->Start());
231
232   const Extension* extension = LoadExtension(
233       test_data_dir_.AppendASCII("subscribe_page_action"));
234   ASSERT_TRUE(extension);
235   std::string id = extension->id();
236
237   // Feed with valid but mostly empty xml.
238   NavigateToFeedAndValidate(test_server(), kValidFeed5, browser(), id, true,
239                             "Feed for Unknown feed name",
240                             "element 'anchor_0' not found",
241                             "element 'desc_0' not found",
242                             "This feed contains no entries.");
243 }
244
245 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed6) {
246   ASSERT_TRUE(test_server()->Start());
247
248   const Extension* extension = LoadExtension(
249       test_data_dir_.AppendASCII("subscribe_page_action"));
250   ASSERT_TRUE(extension);
251   std::string id = extension->id();
252
253   // Feed that is technically invalid but still parseable.
254   NavigateToFeedAndValidate(test_server(), kValidFeed6, browser(), id, true,
255                             "Feed for MyFeedTitle",
256                             "Title 1",
257                             "Desc",
258                             "No error");
259 }
260
261 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed1) {
262   ASSERT_TRUE(test_server()->Start());
263
264   const Extension* extension = LoadExtension(
265       test_data_dir_.AppendASCII("subscribe_page_action"));
266   ASSERT_TRUE(extension);
267   std::string id = extension->id();
268
269   // Try an empty feed.
270   NavigateToFeedAndValidate(test_server(), kInvalidFeed1, browser(), id, false,
271                             "Feed for Unknown feed name",
272                             "element 'anchor_0' not found",
273                             "element 'desc_0' not found",
274                             "This feed contains no entries.");
275 }
276
277 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed2) {
278   ASSERT_TRUE(test_server()->Start());
279
280   const Extension* extension = LoadExtension(
281       test_data_dir_.AppendASCII("subscribe_page_action"));
282   ASSERT_TRUE(extension);
283   std::string id = extension->id();
284
285   // Try a garbage feed.
286   NavigateToFeedAndValidate(test_server(), kInvalidFeed2, browser(), id, false,
287                             "Feed for Unknown feed name",
288                             "element 'anchor_0' not found",
289                             "element 'desc_0' not found",
290                             "This feed contains no entries.");
291 }
292
293 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed3) {
294   ASSERT_TRUE(test_server()->Start());
295
296   const Extension* extension = LoadExtension(
297       test_data_dir_.AppendASCII("subscribe_page_action"));
298   ASSERT_TRUE(extension);
299   std::string id = extension->id();
300
301   // Try a feed that doesn't exist.
302   NavigateToFeedAndValidate(test_server(), "foo.xml", browser(), id, false,
303                             "Feed for Unknown feed name",
304                             "element 'anchor_0' not found",
305                             "element 'desc_0' not found",
306                             "This feed contains no entries.");
307 }
308
309 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed4) {
310   ASSERT_TRUE(test_server()->Start());
311
312   const Extension* extension = LoadExtension(
313       test_data_dir_.AppendASCII("subscribe_page_action"));
314   ASSERT_TRUE(extension);
315   std::string id = extension->id();
316
317   // subscribe.js shouldn't double-decode the URL passed in. Otherwise feed
318   // links such as http://search.twitter.com/search.atom?lang=en&q=%23chrome
319   // will result in no feed being downloaded because %23 gets decoded to # and
320   // therefore #chrome is not treated as part of the Twitter query. This test
321   // uses an underscore instead of a hash, but the principle is the same. If
322   // we start erroneously double decoding again, the path (and the feed) will
323   // become valid resulting in a failure for this test.
324   NavigateToFeedAndValidate(
325       test_server(), kFeedTripleEncoded, browser(), id, true,
326       "Feed for Unknown feed name",
327       "element 'anchor_0' not found",
328       "element 'desc_0' not found",
329       "This feed contains no entries.");
330 }
331
332 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeedNoLinks) {
333   ASSERT_TRUE(test_server()->Start());
334
335   const Extension* extension = LoadExtension(
336       test_data_dir_.AppendASCII("subscribe_page_action"));
337   ASSERT_TRUE(extension);
338   std::string id = extension->id();
339
340   // Valid feed but containing no links.
341   NavigateToFeedAndValidate(
342       test_server(), kValidFeedNoLinks, browser(), id, true,
343       "Feed for MyFeedTitle",
344       "Title with no link",
345       "Desc",
346       "No error");
347 }