1 // Copyright (c) 2011 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/file_util.h" 6 #include "base/logging.h" 7 #include "base/path_service.h" 8 #include "base/utf_string_conversions.h" 9 #include "chrome/browser/search_engines/template_url.h" 10 #include "chrome/browser/search_engines/template_url_parser.h" 11 #include "chrome/common/chrome_paths.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 class TemplateURLParserTest : public testing::Test { 15 public: 16 TemplateURLParserTest() : parse_result_(true) { 17 } 18 19 virtual void SetUp() { 20 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &full_path_)); 21 full_path_ = full_path_.AppendASCII("osdd"); 22 if (!file_util::PathExists(full_path_)) { 23 LOG(ERROR) << 24 L"This test can't be run without some non-redistributable data"; 25 full_path_ = FilePath(); 26 } 27 } 28 29 bool IsDisabled() { 30 return full_path_.empty(); 31 } 32 33 // Parses the OpenSearch description document at file_name (relative to 34 // the data dir). The TemplateURL is placed in template_url_. 35 // The result of Parse is stored in the field parse_result_ (this doesn't 36 // use a return value due to internally using ASSERT_). 37 void ParseFile(const std::string& file_name, 38 TemplateURLParser::ParameterFilter* filter) { 39 FilePath full_path; 40 parse_result_ = false; 41 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &full_path)); 42 full_path = full_path.AppendASCII("osdd"); 43 full_path = full_path.AppendASCII(file_name); 44 ASSERT_TRUE(file_util::PathExists(full_path)); 45 46 std::string contents; 47 ASSERT_TRUE(file_util::ReadFileToString(full_path, &contents)); 48 parse_result_ = TemplateURLParser::Parse( 49 reinterpret_cast<const unsigned char*>(contents.c_str()), 50 contents.length(), filter, &template_url_); 51 } 52 53 // ParseFile parses the results into this template_url. 54 TemplateURL template_url_; 55 56 FilePath full_path_; 57 58 // Result of the parse. 59 bool parse_result_; 60 }; 61 62 TEST_F(TemplateURLParserTest, FailOnBogusURL) { 63 if (IsDisabled()) 64 return; 65 ParseFile("bogus.xml", NULL); 66 EXPECT_FALSE(parse_result_); 67 } 68 69 TEST_F(TemplateURLParserTest, PassOnHTTPS) { 70 if (IsDisabled()) 71 return; 72 ParseFile("https.xml", NULL); 73 EXPECT_TRUE(parse_result_); 74 } 75 76 TEST_F(TemplateURLParserTest, FailOnPost) { 77 if (IsDisabled()) 78 return; 79 ParseFile("post.xml", NULL); 80 EXPECT_FALSE(parse_result_); 81 } 82 83 TEST_F(TemplateURLParserTest, TestDictionary) { 84 if (IsDisabled()) 85 return; 86 ParseFile("dictionary.xml", NULL); 87 ASSERT_TRUE(parse_result_); 88 EXPECT_EQ(ASCIIToUTF16("Dictionary.com"), template_url_.short_name()); 89 EXPECT_TRUE(template_url_.GetFaviconURL() == 90 GURL("http://cache.lexico.com/g/d/favicon.ico")); 91 EXPECT_TRUE(template_url_.url() != NULL); 92 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 93 EXPECT_EQ(template_url_.url()->url(), 94 "http://dictionary.reference.com/browse/{searchTerms}?r=75"); 95 } 96 97 TEST_F(TemplateURLParserTest, TestMSDN) { 98 if (IsDisabled()) 99 return; 100 ParseFile("msdn.xml", NULL); 101 ASSERT_TRUE(parse_result_); 102 EXPECT_EQ(ASCIIToUTF16("Search \" MSDN"), template_url_.short_name()); 103 EXPECT_TRUE(template_url_.GetFaviconURL() == 104 GURL("http://search.msdn.microsoft.com/search/favicon.ico")); 105 EXPECT_TRUE(template_url_.url() != NULL); 106 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 107 EXPECT_EQ(template_url_.url()->url(), 108 "http://search.msdn.microsoft.com/search/default.aspx?Query={searchTerms}&brand=msdn&locale=en-US"); 109 } 110 111 TEST_F(TemplateURLParserTest, TestWikipedia) { 112 if (IsDisabled()) 113 return; 114 ParseFile("wikipedia.xml", NULL); 115 ASSERT_TRUE(parse_result_); 116 EXPECT_EQ(ASCIIToUTF16("Wikipedia (English)"), template_url_.short_name()); 117 EXPECT_TRUE(template_url_.GetFaviconURL() == 118 GURL("http://en.wikipedia.org/favicon.ico")); 119 EXPECT_TRUE(template_url_.url() != NULL); 120 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 121 EXPECT_EQ(template_url_.url()->url(), 122 "http://en.wikipedia.org/w/index.php?title=Special:Search&search={searchTerms}"); 123 EXPECT_TRUE(template_url_.suggestions_url() != NULL); 124 EXPECT_TRUE(template_url_.suggestions_url()->SupportsReplacement()); 125 EXPECT_EQ(template_url_.suggestions_url()->url(), 126 "http://en.wikipedia.org/w/api.php?action=opensearch&search={searchTerms}"); 127 ASSERT_EQ(2U, template_url_.input_encodings().size()); 128 EXPECT_EQ("UTF-8", template_url_.input_encodings()[0]); 129 EXPECT_EQ("Shift_JIS", template_url_.input_encodings()[1]); 130 } 131 132 TEST_F(TemplateURLParserTest, NoCrashOnEmptyAttributes) { 133 if (IsDisabled()) 134 return; 135 ParseFile("url_with_no_attributes.xml", NULL); 136 } 137 138 // Filters any param which as an occurrence of name_str_ in its name or an 139 // occurrence of value_str_ in its value. 140 class ParamFilterImpl : public TemplateURLParser::ParameterFilter { 141 public: 142 ParamFilterImpl(std::string name_str, std::string value_str) 143 : name_str_(name_str), 144 value_str_(value_str) { 145 } 146 147 bool KeepParameter(const std::string& key, const std::string& value) { 148 return (name_str_.empty() || key.find(name_str_) == std::string::npos) && 149 (value_str_.empty() || value.find(value_str_) == std::string::npos); 150 } 151 152 private: 153 std::string name_str_; 154 std::string value_str_; 155 156 DISALLOW_COPY_AND_ASSIGN(ParamFilterImpl); 157 }; 158 159 TEST_F(TemplateURLParserTest, TestFirefoxEbay) { 160 if (IsDisabled()) 161 return; 162 // This file uses the Parameter extension 163 // (see http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0) 164 ParamFilterImpl filter("ebay", "ebay"); 165 ParseFile("firefox_ebay.xml", &filter); 166 ASSERT_TRUE(parse_result_); 167 EXPECT_EQ(ASCIIToUTF16("eBay"), template_url_.short_name()); 168 EXPECT_TRUE(template_url_.url() != NULL); 169 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 170 std::string exp_url = 171 "http://search.ebay.com/search/search.dll?query={searchTerms}&" 172 "MfcISAPICommand=GetResult&ht=1&srchdesc=n&maxRecordsReturned=300&" 173 "maxRecordsPerPage=50&SortProperty=MetaEndSort"; 174 EXPECT_EQ(exp_url, template_url_.url()->url()); 175 ASSERT_EQ(1U, template_url_.input_encodings().size()); 176 EXPECT_EQ("ISO-8859-1", template_url_.input_encodings()[0]); 177 EXPECT_EQ(GURL("http://search.ebay.com/favicon.ico"), 178 template_url_.GetFaviconURL()); 179 } 180 181 TEST_F(TemplateURLParserTest, TestFirefoxWebster) { 182 if (IsDisabled()) 183 return; 184 // This XML file uses a namespace. 185 ParamFilterImpl filter("", "Mozilla"); 186 ParseFile("firefox_webster.xml", &filter); 187 ASSERT_TRUE(parse_result_); 188 EXPECT_EQ(ASCIIToUTF16("Webster"), template_url_.short_name()); 189 EXPECT_TRUE(template_url_.url() != NULL); 190 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 191 EXPECT_EQ("http://www.webster.com/cgi-bin/dictionary?va={searchTerms}", 192 template_url_.url()->url()); 193 ASSERT_EQ(1U, template_url_.input_encodings().size()); 194 EXPECT_EQ("ISO-8859-1", template_url_.input_encodings()[0]); 195 EXPECT_EQ(GURL("http://www.webster.com/favicon.ico"), 196 template_url_.GetFaviconURL()); 197 } 198 199 TEST_F(TemplateURLParserTest, TestFirefoxYahoo) { 200 if (IsDisabled()) 201 return; 202 // This XML file uses a namespace. 203 ParamFilterImpl filter("", "Mozilla"); 204 ParseFile("firefox_yahoo.xml", &filter); 205 ASSERT_TRUE(parse_result_); 206 EXPECT_EQ(ASCIIToUTF16("Yahoo"), template_url_.short_name()); 207 EXPECT_TRUE(template_url_.url() != NULL); 208 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 209 EXPECT_EQ("http://ff.search.yahoo.com/gossip?" 210 "output=fxjson&command={searchTerms}", 211 template_url_.suggestions_url()->url()); 212 EXPECT_EQ("http://search.yahoo.com/search?p={searchTerms}&ei=UTF-8", 213 template_url_.url()->url()); 214 ASSERT_EQ(1U, template_url_.input_encodings().size()); 215 EXPECT_EQ("UTF-8", template_url_.input_encodings()[0]); 216 EXPECT_EQ(GURL("http://search.yahoo.com/favicon.ico"), 217 template_url_.GetFaviconURL()); 218 } 219 220 // Make sure we ignore POST suggestions (this is the same XML file as 221 // firefox_yahoo.xml, the suggestion method was just changed to POST). 222 TEST_F(TemplateURLParserTest, TestPostSuggestion) { 223 if (IsDisabled()) 224 return; 225 // This XML file uses a namespace. 226 ParamFilterImpl filter("", "Mozilla"); 227 ParseFile("post_suggestion.xml", &filter); 228 ASSERT_TRUE(parse_result_); 229 EXPECT_EQ(ASCIIToUTF16("Yahoo"), template_url_.short_name()); 230 EXPECT_TRUE(template_url_.url() != NULL); 231 EXPECT_TRUE(template_url_.url()->SupportsReplacement()); 232 EXPECT_TRUE(template_url_.suggestions_url() == NULL); 233 EXPECT_EQ("http://search.yahoo.com/search?p={searchTerms}&ei=UTF-8", 234 template_url_.url()->url()); 235 ASSERT_EQ(1U, template_url_.input_encodings().size()); 236 EXPECT_EQ("UTF-8", template_url_.input_encodings()[0]); 237 EXPECT_EQ(GURL("http://search.yahoo.com/favicon.ico"), 238 template_url_.GetFaviconURL()); 239 } 240