Upstream version 11.40.277.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         url::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(content::RenderFrameHost* frame,
80                          const std::string& javascript,
81                          const std::string& expected_value) {
82   std::string returned_value;
83
84   if (!content::ExecuteScriptAndExtractString(frame,
85                                               javascript,
86                                               &returned_value))
87     return false;
88
89   EXPECT_STREQ(expected_value.c_str(), returned_value.c_str());
90   return expected_value == returned_value;
91 }
92
93 // Navigates to a feed page and, if |sniff_xml_type| is set, wait for the
94 // extension to kick in, detect the feed and redirect to a feed preview page.
95 // |sniff_xml_type| is generally set to true if the feed is sniffable and false
96 // for invalid feeds.
97 void NavigateToFeedAndValidate(net::SpawnedTestServer* server,
98                                const std::string& url,
99                                Browser* browser,
100                                std::string extension_id,
101                                bool sniff_xml_type,
102                                const std::string& expected_feed_title,
103                                const std::string& expected_item_title,
104                                const std::string& expected_item_desc,
105                                const std::string& expected_error) {
106   if (sniff_xml_type) {
107     // TODO(finnur): Implement this is a non-flaky way.
108   }
109
110   // Navigate to the subscribe page directly.
111   ui_test_utils::NavigateToURL(browser,
112                                GetFeedUrl(server, url, true, extension_id));
113
114   WebContents* tab = browser->tab_strip_model()->GetActiveWebContents();
115   content::RenderFrameHost* frame = content::FrameMatchingPredicate(
116       tab, base::Bind(&content::FrameIsChildOfMainFrame));
117   ASSERT_TRUE(ValidatePageElement(
118       tab->GetMainFrame(), kScriptFeedTitle, expected_feed_title));
119   ASSERT_TRUE(ValidatePageElement(frame, kScriptAnchor, expected_item_title));
120   ASSERT_TRUE(ValidatePageElement(frame, kScriptDesc, expected_item_desc));
121   ASSERT_TRUE(ValidatePageElement(frame, kScriptError, expected_error));
122 }
123
124 } // namespace
125
126 // Makes sure that the RSS detects RSS feed links, even when rel tag contains
127 // more than just "alternate".
128 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSMultiRelLink) {
129   ASSERT_TRUE(test_server()->Start());
130
131   ASSERT_TRUE(LoadExtension(
132     test_data_dir_.AppendASCII("subscribe_page_action")));
133
134   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(0));
135
136   // Navigate to the feed page.
137   GURL feed_url = test_server()->GetURL(kFeedPageMultiRel);
138   ui_test_utils::NavigateToURL(browser(), feed_url);
139   // We should now have one page action ready to go in the LocationBar.
140   ASSERT_TRUE(WaitForPageActionVisibilityChangeTo(1));
141 }
142
143 // This test is flaky on all platforms; see http://crbug.com/340354
144 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, DISABLED_RSSParseFeedValidFeed1) {
145   ASSERT_TRUE(test_server()->Start());
146
147   const Extension* extension = LoadExtension(
148       test_data_dir_.AppendASCII("subscribe_page_action"));
149   ASSERT_TRUE(extension);
150   std::string id = extension->id();
151
152   NavigateToFeedAndValidate(test_server(), kValidFeed1, browser(), id, true,
153                             "Feed for MyFeedTitle",
154                             "Title 1",
155                             "Desc",
156                             "No error");
157 }
158
159 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed2) {
160   ASSERT_TRUE(test_server()->Start());
161
162   const Extension* extension = LoadExtension(
163       test_data_dir_.AppendASCII("subscribe_page_action"));
164   ASSERT_TRUE(extension);
165   std::string id = extension->id();
166
167   NavigateToFeedAndValidate(test_server(), kValidFeed2, browser(), id, true,
168                             "Feed for MyFeed2",
169                             "My item title1",
170                             "This is a summary.",
171                             "No error");
172 }
173
174 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed3) {
175   ASSERT_TRUE(test_server()->Start());
176
177   const Extension* extension = LoadExtension(
178       test_data_dir_.AppendASCII("subscribe_page_action"));
179   ASSERT_TRUE(extension);
180   std::string id = extension->id();
181
182   NavigateToFeedAndValidate(test_server(), kValidFeed3, browser(), id, true,
183                             "Feed for Google Code buglist rss feed",
184                             "My dear title",
185                             "My dear content",
186                             "No error");
187 }
188
189 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed4) {
190   ASSERT_TRUE(test_server()->Start());
191
192   const Extension* extension = LoadExtension(
193       test_data_dir_.AppendASCII("subscribe_page_action"));
194   ASSERT_TRUE(extension);
195   std::string id = extension->id();
196
197   NavigateToFeedAndValidate(test_server(), kValidFeed4, browser(), id, true,
198                             "Feed for Title chars <script> %23 stop",
199                             "Title chars  %23 stop",
200                             "My dear content %23 stop",
201                             "No error");
202 }
203
204 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed0) {
205   ASSERT_TRUE(test_server()->Start());
206
207   const Extension* extension = LoadExtension(
208       test_data_dir_.AppendASCII("subscribe_page_action"));
209   ASSERT_TRUE(extension);
210   std::string id = extension->id();
211
212   // Try a feed with a link with an onclick handler (before r27440 this would
213   // trigger a NOTREACHED).
214   NavigateToFeedAndValidate(test_server(), kValidFeed0, browser(), id, true,
215                             "Feed for MyFeedTitle",
216                             "Title 1",
217                             "Desc VIDEO",
218                             "No error");
219 }
220
221 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed5) {
222   ASSERT_TRUE(test_server()->Start());
223
224   const Extension* extension = LoadExtension(
225       test_data_dir_.AppendASCII("subscribe_page_action"));
226   ASSERT_TRUE(extension);
227   std::string id = extension->id();
228
229   // Feed with valid but mostly empty xml.
230   NavigateToFeedAndValidate(test_server(), kValidFeed5, browser(), id, true,
231                             "Feed for Unknown feed name",
232                             "element 'anchor_0' not found",
233                             "element 'desc_0' not found",
234                             "This feed contains no entries.");
235 }
236
237 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeed6) {
238   ASSERT_TRUE(test_server()->Start());
239
240   const Extension* extension = LoadExtension(
241       test_data_dir_.AppendASCII("subscribe_page_action"));
242   ASSERT_TRUE(extension);
243   std::string id = extension->id();
244
245   // Feed that is technically invalid but still parseable.
246   NavigateToFeedAndValidate(test_server(), kValidFeed6, browser(), id, true,
247                             "Feed for MyFeedTitle",
248                             "Title 1",
249                             "Desc",
250                             "No error");
251 }
252
253 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed1) {
254   ASSERT_TRUE(test_server()->Start());
255
256   const Extension* extension = LoadExtension(
257       test_data_dir_.AppendASCII("subscribe_page_action"));
258   ASSERT_TRUE(extension);
259   std::string id = extension->id();
260
261   // Try an empty feed.
262   NavigateToFeedAndValidate(test_server(), kInvalidFeed1, browser(), id, false,
263                             "Feed for Unknown feed name",
264                             "element 'anchor_0' not found",
265                             "element 'desc_0' not found",
266                             "This feed contains no entries.");
267 }
268
269 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed2) {
270   ASSERT_TRUE(test_server()->Start());
271
272   const Extension* extension = LoadExtension(
273       test_data_dir_.AppendASCII("subscribe_page_action"));
274   ASSERT_TRUE(extension);
275   std::string id = extension->id();
276
277   // Try a garbage feed.
278   NavigateToFeedAndValidate(test_server(), kInvalidFeed2, browser(), id, false,
279                             "Feed for Unknown feed name",
280                             "element 'anchor_0' not found",
281                             "element 'desc_0' not found",
282                             "This feed contains no entries.");
283 }
284
285 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed3) {
286   ASSERT_TRUE(test_server()->Start());
287
288   const Extension* extension = LoadExtension(
289       test_data_dir_.AppendASCII("subscribe_page_action"));
290   ASSERT_TRUE(extension);
291   std::string id = extension->id();
292
293   // Try a feed that doesn't exist.
294   NavigateToFeedAndValidate(test_server(), "foo.xml", browser(), id, false,
295                             "Feed for Unknown feed name",
296                             "element 'anchor_0' not found",
297                             "element 'desc_0' not found",
298                             "This feed contains no entries.");
299 }
300
301 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedInvalidFeed4) {
302   ASSERT_TRUE(test_server()->Start());
303
304   const Extension* extension = LoadExtension(
305       test_data_dir_.AppendASCII("subscribe_page_action"));
306   ASSERT_TRUE(extension);
307   std::string id = extension->id();
308
309   // subscribe.js shouldn't double-decode the URL passed in. Otherwise feed
310   // links such as http://search.twitter.com/search.atom?lang=en&q=%23chrome
311   // will result in no feed being downloaded because %23 gets decoded to # and
312   // therefore #chrome is not treated as part of the Twitter query. This test
313   // uses an underscore instead of a hash, but the principle is the same. If
314   // we start erroneously double decoding again, the path (and the feed) will
315   // become valid resulting in a failure for this test.
316   NavigateToFeedAndValidate(
317       test_server(), kFeedTripleEncoded, browser(), id, true,
318       "Feed for Unknown feed name",
319       "element 'anchor_0' not found",
320       "element 'desc_0' not found",
321       "This feed contains no entries.");
322 }
323
324 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, RSSParseFeedValidFeedNoLinks) {
325   ASSERT_TRUE(test_server()->Start());
326
327   const Extension* extension = LoadExtension(
328       test_data_dir_.AppendASCII("subscribe_page_action"));
329   ASSERT_TRUE(extension);
330   std::string id = extension->id();
331
332   // Valid feed but containing no links.
333   NavigateToFeedAndValidate(
334       test_server(), kValidFeedNoLinks, browser(), id, true,
335       "Feed for MyFeedTitle",
336       "Title with no link",
337       "Desc",
338       "No error");
339 }