| OLD | NEW |
| (Empty) |
| 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/intents/cws_intents_registry.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/bind_helpers.h" | |
| 9 #include "base/message_loop.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "chrome/common/extensions/extension_l10n_util.h" | |
| 12 #include "net/url_request/test_url_fetcher_factory.h" | |
| 13 #include "net/url_request/url_request_test_util.h" | |
| 14 #include "testing/gtest/include/gtest/gtest.h" | |
| 15 | |
| 16 // Create a CWSIntentsRegistry proxy for testing purposes. | |
| 17 // Needs to be non-anonymous so it can be friended. | |
| 18 class CWSIntentsRegistryForTest { | |
| 19 public: | |
| 20 CWSIntentsRegistryForTest() : registry_(NULL) {} | |
| 21 ~CWSIntentsRegistryForTest() { delete registry_; } | |
| 22 | |
| 23 void reset(net::URLRequestContextGetter* context) { | |
| 24 delete registry_; | |
| 25 registry_ = new CWSIntentsRegistry(context); | |
| 26 } | |
| 27 | |
| 28 CWSIntentsRegistry* operator->() { return registry_; } | |
| 29 | |
| 30 private: | |
| 31 CWSIntentsRegistry* registry_; | |
| 32 }; | |
| 33 | |
| 34 namespace { | |
| 35 | |
| 36 const char kCWSResponseInvalid[] = | |
| 37 "{\"error\":{" | |
| 38 "\"errors\":[{" | |
| 39 "\"domain\":\"global\"," | |
| 40 "\"reason\":\"invalid\"," | |
| 41 "\"message\":\"Invalid mimetype:foo\"}]," | |
| 42 "\"code\":400," | |
| 43 "\"message\":\"Invalid mimetype:foo\"}}\""; | |
| 44 | |
| 45 const char kCWSResponseValid[] = | |
| 46 "{\"kind\":\"chromewebstore#itemList\"," | |
| 47 " \"total_items\":1," | |
| 48 " \"start_index\":0," | |
| 49 " \"items\":[ " | |
| 50 " {\"kind\":\"chromewebstore#item\"," | |
| 51 " \"id\":\"nhkckhebbbncbkefhcpcgepcgfaclehe\"," | |
| 52 " \"type\":\"APPLICATION\"," | |
| 53 " \"num_ratings\":0," | |
| 54 " \"average_rating\":0.0," | |
| 55 " \"manifest\":\"{\\n\\\"update_url\\\":\\" | |
| 56 "\"http://0.tbhome_staging.dserver.download-qa.td.borg.google.com/" | |
| 57 "service/update2/crx\\\",\\n \\\"name\\\": \\\"Sidd's Intent App\\\"" | |
| 58 ",\\n \\\"description\\\": \\\"Do stuff\\\",\\n \\\"version\\\": " | |
| 59 "\\\"1.2.19\\\",\\n \\\"app\\\": {\\n \\\"urls\\\": [ \\n ]," | |
| 60 "\\n \\\"launch\\\": {\\n \\\"web_url\\\": \\" | |
| 61 "\"http://siddharthasaha.net/\\\"\\n }\\n },\\n \\\"icons\\\": " | |
| 62 "{\\n \\\"128\\\": \\\"icon128.png\\\"\\n },\\n \\\"permissions\\\":" | |
| 63 " [\\n \\\"unlimitedStorage\\\",\\n \\\"notifications\\\"\\n ],\\n" | |
| 64 " \\\"intents\\\": {\\n \\\"http://webintents.org/edit\\\" : {\\n " | |
| 65 "\\\"type\\\" : [\\\"image/png\\\", \\\"image/jpg\\\"],\\n \\\"path\\" | |
| 66 "\" : \\\"//services/edit\\\",\\n \\\"title\\\" : " | |
| 67 "\\\"Sample Editing Intent\\\",\\n \\\"disposition\\\" : \\\"inline\\" | |
| 68 "\"\\n },\\n \\\"http://webintents.org/share\\\" : " | |
| 69 "{\\n \\\"type\\\" : [\\\"text/plain\\\", \\\"image/jpg\\\"]," | |
| 70 "\\n \\\"path\\\" : \\\"//services/share\\\",\\n \\\"title\\\" : " | |
| 71 "\\\"Sample sharing Intent\\\",\\n \\\"disposition\\\" : " | |
| 72 "\\\"inline\\\"\\n }\\n }\\n}\\n\"," | |
| 73 " \"family_safe\":true," | |
| 74 " \"icon_url\":\"http://qa-lighthouse.sandbox.google.com/image/" | |
| 75 "QzPnRCYCBbBGI99ZkGxkp-NNJ488IkkiTyCgynFEeDTJHcw4tHl3csmjTQ\"}]}"; | |
| 76 | |
| 77 const char kCWSResponseValidL10n[] = | |
| 78 "{\"kind\":\"chromewebstore#itemList\"," | |
| 79 " \"total_items\":1," | |
| 80 " \"start_index\":0," | |
| 81 " \"items\":[ " | |
| 82 " {\"kind\":\"chromewebstore#item\"," | |
| 83 " \"id\":\"nhkckhebbbncbkefhcpcgepcgfaclehe\"," | |
| 84 " \"type\":\"APPLICATION\"," | |
| 85 " \"num_ratings\":0," | |
| 86 " \"average_rating\":0.0," | |
| 87 " \"manifest\":\"{\\n\\\"update_url\\\":\\" | |
| 88 "\"http://0.tbhome_staging.dserver.download-qa.td.borg.google.com/" | |
| 89 "service/update2/crx\\\",\\n \\\"name\\\": \\\"__MSG_name__\\\"" | |
| 90 ",\\n \\\"description\\\": \\\"Do stuff\\\",\\n \\\"version\\\": " | |
| 91 "\\\"1.2.19\\\",\\n \\\"app\\\": {\\n \\\"urls\\\": [ \\n ]," | |
| 92 "\\n \\\"launch\\\": {\\n \\\"web_url\\\": \\" | |
| 93 "\"http://siddharthasaha.net/\\\"\\n }\\n },\\n \\\"icons\\\": " | |
| 94 "{\\n \\\"128\\\": \\\"icon128.png\\\"\\n },\\n \\\"permissions\\\":" | |
| 95 " [\\n \\\"unlimitedStorage\\\",\\n \\\"notifications\\\"\\n ],\\n" | |
| 96 " \\\"intents\\\": {\\n \\\"http://webintents.org/edit\\\" : {\\n " | |
| 97 "\\\"type\\\" : [\\\"image/png\\\", \\\"image/jpg\\\"],\\n \\\"path\\" | |
| 98 "\" : \\\"//services/edit\\\",\\n \\\"title\\\" : " | |
| 99 "\\\"Sample Editing Intent\\\",\\n \\\"disposition\\\" : \\\"inline\\" | |
| 100 "\"\\n },\\n \\\"http://webintents.org/share\\\" : " | |
| 101 "{\\n \\\"type\\\" : [\\\"text/plain\\\", \\\"image/jpg\\\"]," | |
| 102 "\\n \\\"path\\\" : \\\"//services/share\\\",\\n \\\"title\\\" : " | |
| 103 "\\\"Sample sharing Intent\\\",\\n \\\"disposition\\\" : " | |
| 104 "\\\"inline\\\"\\n }\\n }\\n}\\n\"," | |
| 105 " \"family_safe\":true," | |
| 106 " \"icon_url\":\"http://qa-lighthouse.sandbox.google.com/image/" | |
| 107 "QzPnRCYCBbBGI99ZkGxkp-NNJ488IkkiTyCgynFEeDTJHcw4tHl3csmjTQ\"," | |
| 108 "\"locale_data\": ["; | |
| 109 | |
| 110 const char kCWSResponseValidL10nPostfix[] = | |
| 111 "]}]}"; | |
| 112 | |
| 113 const char kLocaleDataEn[] = | |
| 114 "{" | |
| 115 " \"locale_string\": \"en\"," | |
| 116 " \"title\": \"Localized EN\"" | |
| 117 "}"; | |
| 118 | |
| 119 const char kLocaleDataDe[] = | |
| 120 "{" | |
| 121 " \"locale_string\": \"de\"," | |
| 122 " \"title\": \"Localized DE\"" | |
| 123 "}"; | |
| 124 | |
| 125 const char kLocaleDataAll[] = | |
| 126 "{" | |
| 127 " \"locale_string\": \"all\"," | |
| 128 " \"title\": \"Localized ALL\"" | |
| 129 "}"; | |
| 130 | |
| 131 const char kValidIconURL[] = | |
| 132 "http://qa-lighthouse.sandbox.google.com/image/" | |
| 133 "QzPnRCYCBbBGI99ZkGxkp-NNJ488IkkiTyCgynFEeDTJHcw4tHl3csmjTQ"; | |
| 134 | |
| 135 const char kValidManifest[] = | |
| 136 "{\n\"update_url\":\"http://0.tbhome_staging.dserver.download-qa.td.borg." | |
| 137 "google.com/service/update2/crx\",\n \"name\": \"Sidd's Intent App\",\n" | |
| 138 " \"description\": \"Do stuff\",\n \"version\": \"1.2.19\",\n \"app\":" | |
| 139 " {\n \"urls\": [ \n ],\n \"launch\": {\n \"web_url\":" | |
| 140 " \"http://siddharthasaha.net/\"\n }\n },\n \"icons\": {\n " | |
| 141 "\"128\": \"icon128.png\"\n },\n \"permissions\": [\n " | |
| 142 "\"unlimitedStorage\",\n \"notifications\"\n ],\n \"intents\": " | |
| 143 "{\n \"http://webintents.org/edit\" : {\n \"type\" : [" | |
| 144 "\"image/png\", \"image/jpg\"],\n \"path\" : \"//services/edit\",\n" | |
| 145 " \"title\" : \"Sample Editing Intent\",\n \"disposition\" : " | |
| 146 "\"inline\"\n },\n \"http://webintents.org/share\" : {\n " | |
| 147 "\"type\" : [\"text/plain\", \"image/jpg\"],\n \"path\" : " | |
| 148 "\"//services/share\",\n \"title\" : \"Sample sharing Intent\",\n" | |
| 149 " \"disposition\" : \"inline\"\n }\n }\n}\n"; | |
| 150 | |
| 151 const char kEditAction[] = "http://webintents.org/edit"; | |
| 152 const char kImagePngType[] = "image/png"; | |
| 153 | |
| 154 class CWSIntentsRegistryTest : public testing::Test { | |
| 155 public: | |
| 156 virtual void SetUp() { | |
| 157 scoped_refptr<net::TestURLRequestContextGetter> context_getter( | |
| 158 new net::TestURLRequestContextGetter(ui_loop_.message_loop_proxy())); | |
| 159 registry_.reset(context_getter); | |
| 160 } | |
| 161 | |
| 162 virtual void TearDown() { | |
| 163 // Pump messages posted by the main thread. | |
| 164 ui_loop_.RunUntilIdle(); | |
| 165 } | |
| 166 | |
| 167 CWSIntentsRegistry::IntentExtensionList WaitForResults() { | |
| 168 ui_loop_.RunUntilIdle(); | |
| 169 return extensions_; | |
| 170 } | |
| 171 | |
| 172 void Callback(const CWSIntentsRegistry::IntentExtensionList& extensions) { | |
| 173 extensions_ = extensions; | |
| 174 } | |
| 175 | |
| 176 void RunRequest(const std::string& action, const std::string& mime, | |
| 177 const std::string& response) { | |
| 178 extensions_.clear(); | |
| 179 | |
| 180 net::FakeURLFetcherFactory test_factory; | |
| 181 test_factory.SetFakeResponse( | |
| 182 CWSIntentsRegistry::BuildQueryURL( | |
| 183 ASCIIToUTF16(action),ASCIIToUTF16(mime)).spec(), | |
| 184 response, true); | |
| 185 | |
| 186 registry_->GetIntentServices(ASCIIToUTF16(action), | |
| 187 ASCIIToUTF16(mime), | |
| 188 base::Bind(&CWSIntentsRegistryTest::Callback, | |
| 189 base::Unretained(this))); | |
| 190 WaitForResults(); | |
| 191 } | |
| 192 | |
| 193 | |
| 194 protected: | |
| 195 // UI loop MUST be declared first, (and thus destroyed last) to allow posted | |
| 196 // DeleteSoon() for e.g.TestURLRequestContextGetter. | |
| 197 MessageLoop ui_loop_; | |
| 198 CWSIntentsRegistryForTest registry_; | |
| 199 CWSIntentsRegistry::IntentExtensionList extensions_; | |
| 200 }; | |
| 201 | |
| 202 } // namespace | |
| 203 | |
| 204 TEST_F(CWSIntentsRegistryTest, ValidQuery) { | |
| 205 RunRequest(kEditAction, kImagePngType,kCWSResponseValid); | |
| 206 ASSERT_EQ(1UL, extensions_.size()); | |
| 207 | |
| 208 EXPECT_EQ(0, extensions_[0].num_ratings); | |
| 209 EXPECT_EQ(0.0, extensions_[0].average_rating); | |
| 210 EXPECT_EQ(std::string(kValidManifest), UTF16ToUTF8(extensions_[0].manifest)); | |
| 211 EXPECT_EQ(std::string("nhkckhebbbncbkefhcpcgepcgfaclehe"), extensions_[0].id); | |
| 212 EXPECT_EQ(std::string("Sidd's Intent App"), | |
| 213 UTF16ToUTF8(extensions_[0].name)); | |
| 214 EXPECT_EQ(std::string(kValidIconURL), extensions_[0].icon_url.spec()); | |
| 215 } | |
| 216 | |
| 217 TEST_F(CWSIntentsRegistryTest, InvalidQuery) { | |
| 218 RunRequest("foo", "foo",kCWSResponseInvalid); | |
| 219 EXPECT_EQ(0UL, extensions_.size()); | |
| 220 } | |
| 221 | |
| 222 TEST_F(CWSIntentsRegistryTest, BuildQueryURL) { | |
| 223 const std::string kExpectedURL = "https://www.googleapis.com" | |
| 224 "/chromewebstore/v1.1b/items/intent" | |
| 225 "?intent=action&mime_types=mime%2Ftype&start_index=0&num_results=15"; | |
| 226 GURL url = CWSIntentsRegistry::BuildQueryURL(ASCIIToUTF16("action"), | |
| 227 ASCIIToUTF16("mime/type")); | |
| 228 | |
| 229 EXPECT_EQ(kExpectedURL, url.spec().substr(0, kExpectedURL.size())); | |
| 230 } | |
| 231 | |
| 232 // Test for match to the application locale - i.e. if running in "en", | |
| 233 // registry will use locale_data for "en" key, with or without "all" | |
| 234 // locale_data present. | |
| 235 TEST_F(CWSIntentsRegistryTest, LocalizeMatchingLocale) { | |
| 236 extension_l10n_util::ScopedLocaleForTest restoreLocaleOnExit; | |
| 237 | |
| 238 std::string response = kCWSResponseValidL10n; | |
| 239 response += kLocaleDataEn + std::string(","); | |
| 240 response += kLocaleDataAll + std::string(","); | |
| 241 response += kLocaleDataDe; | |
| 242 response += kCWSResponseValidL10nPostfix; | |
| 243 | |
| 244 // Picks the proper locale_data based on application locale. | |
| 245 extension_l10n_util::SetProcessLocale("en"); | |
| 246 RunRequest(kEditAction, kImagePngType, response); | |
| 247 ASSERT_EQ(1UL, extensions_.size()); | |
| 248 EXPECT_EQ(std::string("Localized EN"), | |
| 249 UTF16ToUTF8(extensions_[0].name)); | |
| 250 | |
| 251 extension_l10n_util::SetProcessLocale("de"); | |
| 252 RunRequest(kEditAction, kImagePngType, response); | |
| 253 ASSERT_EQ(1UL, extensions_.size()); | |
| 254 EXPECT_EQ(std::string("Localized DE"), | |
| 255 UTF16ToUTF8(extensions_[0].name)); | |
| 256 | |
| 257 // Falls back to locale_data for "All" if unknown application locale. | |
| 258 extension_l10n_util::SetProcessLocale("fr"); | |
| 259 RunRequest(kEditAction, kImagePngType, std::string(kCWSResponseValidL10n) + | |
| 260 kLocaleDataAll + kCWSResponseValidL10nPostfix); | |
| 261 ASSERT_EQ(1UL, extensions_.size()); | |
| 262 EXPECT_EQ(std::string("Localized ALL"), | |
| 263 UTF16ToUTF8(extensions_[0].name)); | |
| 264 | |
| 265 // Keeps original content if unknown application locale and no "all" | |
| 266 // localization data exists. | |
| 267 response = kCWSResponseValidL10n; | |
| 268 response += kLocaleDataEn; | |
| 269 response += kCWSResponseValidL10nPostfix; | |
| 270 extension_l10n_util::SetProcessLocale("de"); | |
| 271 RunRequest(kEditAction, kImagePngType, response); | |
| 272 ASSERT_EQ(1UL, extensions_.size()); | |
| 273 EXPECT_EQ(std::string("__MSG_name__"), | |
| 274 UTF16ToUTF8(extensions_[0].name)); | |
| 275 } | |
| OLD | NEW |