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