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 "base/file_util.h"
6 #include "base/files/file_path.h"
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/memory/linked_ptr.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/common/extensions/extension_l10n_util.h"
15 #include "chrome/common/extensions/message_bundle.h"
16 #include "extensions/common/constants.h"
17 #include "extensions/common/error_utils.h"
18 #include "extensions/common/manifest_constants.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/base/l10n/l10n_util.h"
22
23 using extensions::kLocaleFolder;
24 using extensions::kMessagesFilename;
25 using extensions::MessageBundle;
26
27 namespace errors = extensions::manifest_errors;
28 namespace keys = extensions::manifest_keys;
29
30 namespace {
31
TEST(ExtensionL10nUtil,ValidateLocalesWithBadLocale)32 TEST(ExtensionL10nUtil, ValidateLocalesWithBadLocale) {
33 base::ScopedTempDir temp;
34 ASSERT_TRUE(temp.CreateUniqueTempDir());
35
36 base::FilePath src_path = temp.path().Append(kLocaleFolder);
37 base::FilePath locale = src_path.AppendASCII("ms");
38 ASSERT_TRUE(base::CreateDirectory(locale));
39
40 base::FilePath messages_file = locale.Append(kMessagesFilename);
41 std::string data = "{ \"name\":";
42 ASSERT_TRUE(file_util::WriteFile(messages_file, data.c_str(), data.length()));
43
44 base::DictionaryValue manifest;
45 manifest.SetString(keys::kDefaultLocale, "en");
46 std::string error;
47 EXPECT_FALSE(extension_l10n_util::ValidateExtensionLocales(
48 temp.path(), &manifest, &error));
49 EXPECT_THAT(error,
50 testing::HasSubstr(
51 UTF16ToUTF8(messages_file.LossyDisplayName())));
52 }
53
TEST(ExtensionL10nUtil,GetValidLocalesEmptyLocaleFolder)54 TEST(ExtensionL10nUtil, GetValidLocalesEmptyLocaleFolder) {
55 base::ScopedTempDir temp;
56 ASSERT_TRUE(temp.CreateUniqueTempDir());
57
58 base::FilePath src_path = temp.path().Append(kLocaleFolder);
59 ASSERT_TRUE(base::CreateDirectory(src_path));
60
61 std::string error;
62 std::set<std::string> locales;
63 EXPECT_FALSE(extension_l10n_util::GetValidLocales(src_path,
64 &locales,
65 &error));
66
67 EXPECT_TRUE(locales.empty());
68 }
69
TEST(ExtensionL10nUtil,GetValidLocalesWithValidLocaleNoMessagesFile)70 TEST(ExtensionL10nUtil, GetValidLocalesWithValidLocaleNoMessagesFile) {
71 base::ScopedTempDir temp;
72 ASSERT_TRUE(temp.CreateUniqueTempDir());
73
74 base::FilePath src_path = temp.path().Append(kLocaleFolder);
75 ASSERT_TRUE(base::CreateDirectory(src_path));
76 ASSERT_TRUE(base::CreateDirectory(src_path.AppendASCII("sr")));
77
78 std::string error;
79 std::set<std::string> locales;
80 EXPECT_FALSE(extension_l10n_util::GetValidLocales(src_path,
81 &locales,
82 &error));
83
84 EXPECT_TRUE(locales.empty());
85 }
86
TEST(ExtensionL10nUtil,GetValidLocalesWithUnsupportedLocale)87 TEST(ExtensionL10nUtil, GetValidLocalesWithUnsupportedLocale) {
88 base::ScopedTempDir temp;
89 ASSERT_TRUE(temp.CreateUniqueTempDir());
90
91 base::FilePath src_path = temp.path().Append(kLocaleFolder);
92 ASSERT_TRUE(base::CreateDirectory(src_path));
93 // Supported locale.
94 base::FilePath locale_1 = src_path.AppendASCII("sr");
95 ASSERT_TRUE(base::CreateDirectory(locale_1));
96 std::string data("whatever");
97 ASSERT_TRUE(file_util::WriteFile(
98 locale_1.Append(kMessagesFilename),
99 data.c_str(), data.length()));
100 // Unsupported locale.
101 ASSERT_TRUE(base::CreateDirectory(src_path.AppendASCII("xxx_yyy")));
102
103 std::string error;
104 std::set<std::string> locales;
105 EXPECT_TRUE(extension_l10n_util::GetValidLocales(src_path,
106 &locales,
107 &error));
108
109 EXPECT_FALSE(locales.empty());
110 EXPECT_TRUE(locales.find("sr") != locales.end());
111 EXPECT_FALSE(locales.find("xxx_yyy") != locales.end());
112 }
113
TEST(ExtensionL10nUtil,GetValidLocalesWithValidLocalesAndMessagesFile)114 TEST(ExtensionL10nUtil, GetValidLocalesWithValidLocalesAndMessagesFile) {
115 base::FilePath install_dir;
116 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
117 install_dir = install_dir.AppendASCII("extensions")
118 .AppendASCII("good")
119 .AppendASCII("Extensions")
120 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
121 .AppendASCII("1.0.0.0")
122 .Append(kLocaleFolder);
123
124 std::string error;
125 std::set<std::string> locales;
126 EXPECT_TRUE(extension_l10n_util::GetValidLocales(install_dir,
127 &locales,
128 &error));
129 EXPECT_EQ(3U, locales.size());
130 EXPECT_TRUE(locales.find("sr") != locales.end());
131 EXPECT_TRUE(locales.find("en") != locales.end());
132 EXPECT_TRUE(locales.find("en_US") != locales.end());
133 }
134
TEST(ExtensionL10nUtil,LoadMessageCatalogsValidFallback)135 TEST(ExtensionL10nUtil, LoadMessageCatalogsValidFallback) {
136 base::FilePath install_dir;
137 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &install_dir));
138 install_dir = install_dir.AppendASCII("extensions")
139 .AppendASCII("good")
140 .AppendASCII("Extensions")
141 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
142 .AppendASCII("1.0.0.0")
143 .Append(kLocaleFolder);
144
145 std::string error;
146 std::set<std::string> locales;
147 EXPECT_TRUE(extension_l10n_util::GetValidLocales(install_dir,
148 &locales,
149 &error));
150
151 scoped_ptr<MessageBundle> bundle(extension_l10n_util::LoadMessageCatalogs(
152 install_dir, "sr", "en_US", locales, &error));
153 ASSERT_FALSE(NULL == bundle.get());
154 EXPECT_TRUE(error.empty());
155 EXPECT_EQ("Color", bundle->GetL10nMessage("color"));
156 EXPECT_EQ("Not in the US or GB.", bundle->GetL10nMessage("not_in_US_or_GB"));
157 }
158
TEST(ExtensionL10nUtil,LoadMessageCatalogsMissingFiles)159 TEST(ExtensionL10nUtil, LoadMessageCatalogsMissingFiles) {
160 base::ScopedTempDir temp;
161 ASSERT_TRUE(temp.CreateUniqueTempDir());
162
163 base::FilePath src_path = temp.path().Append(kLocaleFolder);
164 ASSERT_TRUE(base::CreateDirectory(src_path));
165
166 std::set<std::string> valid_locales;
167 valid_locales.insert("sr");
168 valid_locales.insert("en");
169 std::string error;
170 EXPECT_TRUE(NULL == extension_l10n_util::LoadMessageCatalogs(src_path,
171 "en",
172 "sr",
173 valid_locales,
174 &error));
175 EXPECT_FALSE(error.empty());
176 }
177
TEST(ExtensionL10nUtil,LoadMessageCatalogsBadJSONFormat)178 TEST(ExtensionL10nUtil, LoadMessageCatalogsBadJSONFormat) {
179 base::ScopedTempDir temp;
180 ASSERT_TRUE(temp.CreateUniqueTempDir());
181
182 base::FilePath src_path = temp.path().Append(kLocaleFolder);
183 ASSERT_TRUE(base::CreateDirectory(src_path));
184
185 base::FilePath locale = src_path.AppendASCII("sr");
186 ASSERT_TRUE(base::CreateDirectory(locale));
187
188 std::string data = "{ \"name\":";
189 base::FilePath messages_file = locale.Append(kMessagesFilename);
190 ASSERT_TRUE(file_util::WriteFile(messages_file, data.c_str(), data.length()));
191
192 std::set<std::string> valid_locales;
193 valid_locales.insert("sr");
194 valid_locales.insert("en_US");
195 std::string error;
196 EXPECT_TRUE(NULL == extension_l10n_util::LoadMessageCatalogs(src_path,
197 "en_US",
198 "sr",
199 valid_locales,
200 &error));
201 EXPECT_EQ(
202 extensions::ErrorUtils::FormatErrorMessage(
203 errors::kLocalesInvalidLocale,
204 base::UTF16ToUTF8(messages_file.LossyDisplayName()),
205 "Line: 1, column: 10, Unexpected token."),
206 error);
207 }
208
TEST(ExtensionL10nUtil,LoadMessageCatalogsDuplicateKeys)209 TEST(ExtensionL10nUtil, LoadMessageCatalogsDuplicateKeys) {
210 base::ScopedTempDir temp;
211 ASSERT_TRUE(temp.CreateUniqueTempDir());
212
213 base::FilePath src_path = temp.path().Append(kLocaleFolder);
214 ASSERT_TRUE(base::CreateDirectory(src_path));
215
216 base::FilePath locale_1 = src_path.AppendASCII("en");
217 ASSERT_TRUE(base::CreateDirectory(locale_1));
218
219 std::string data =
220 "{ \"name\": { \"message\": \"something\" }, "
221 "\"name\": { \"message\": \"something else\" } }";
222 ASSERT_TRUE(
223 file_util::WriteFile(locale_1.Append(kMessagesFilename),
224 data.c_str(), data.length()));
225
226 base::FilePath locale_2 = src_path.AppendASCII("sr");
227 ASSERT_TRUE(base::CreateDirectory(locale_2));
228
229 ASSERT_TRUE(
230 file_util::WriteFile(locale_2.Append(kMessagesFilename),
231 data.c_str(), data.length()));
232
233 std::set<std::string> valid_locales;
234 valid_locales.insert("sr");
235 valid_locales.insert("en");
236 std::string error;
237 // JSON parser hides duplicates. We are going to get only one key/value
238 // pair at the end.
239 scoped_ptr<MessageBundle> message_bundle(
240 extension_l10n_util::LoadMessageCatalogs(src_path,
241 "en",
242 "sr",
243 valid_locales,
244 &error));
245 EXPECT_TRUE(NULL != message_bundle.get());
246 EXPECT_TRUE(error.empty());
247 }
248
249 // Caller owns the returned object.
CreateManifestBundle()250 MessageBundle* CreateManifestBundle() {
251 linked_ptr<base::DictionaryValue> catalog(new base::DictionaryValue);
252
253 base::DictionaryValue* name_tree = new base::DictionaryValue();
254 name_tree->SetString("message", "name");
255 catalog->Set("name", name_tree);
256
257 base::DictionaryValue* short_name_tree = new base::DictionaryValue();
258 short_name_tree->SetString("message", "short_name");
259 catalog->Set("short_name", short_name_tree);
260
261 base::DictionaryValue* description_tree = new base::DictionaryValue();
262 description_tree->SetString("message", "description");
263 catalog->Set("description", description_tree);
264
265 base::DictionaryValue* action_title_tree = new base::DictionaryValue();
266 action_title_tree->SetString("message", "action title");
267 catalog->Set("title", action_title_tree);
268
269 base::DictionaryValue* omnibox_keyword_tree = new base::DictionaryValue();
270 omnibox_keyword_tree->SetString("message", "omnibox keyword");
271 catalog->Set("omnibox_keyword", omnibox_keyword_tree);
272
273 base::DictionaryValue* file_handler_title_tree = new base::DictionaryValue();
274 file_handler_title_tree->SetString("message", "file handler title");
275 catalog->Set("file_handler_title", file_handler_title_tree);
276
277 base::DictionaryValue* launch_local_path_tree = new base::DictionaryValue();
278 launch_local_path_tree->SetString("message", "main.html");
279 catalog->Set("launch_local_path", launch_local_path_tree);
280
281 base::DictionaryValue* launch_web_url_tree = new base::DictionaryValue();
282 launch_web_url_tree->SetString("message", "http://www.google.com/");
283 catalog->Set("launch_web_url", launch_web_url_tree);
284
285 base::DictionaryValue* first_command_description_tree =
286 new base::DictionaryValue();
287 first_command_description_tree->SetString("message", "first command");
288 catalog->Set("first_command_description", first_command_description_tree);
289
290 base::DictionaryValue* second_command_description_tree =
291 new base::DictionaryValue();
292 second_command_description_tree->SetString("message", "second command");
293 catalog->Set("second_command_description", second_command_description_tree);
294
295 base::DictionaryValue* url_country_tree = new base::DictionaryValue();
296 url_country_tree->SetString("message", "de");
297 catalog->Set("country", url_country_tree);
298
299 std::vector<linked_ptr<base::DictionaryValue> > catalogs;
300 catalogs.push_back(catalog);
301
302 std::string error;
303 MessageBundle* bundle = MessageBundle::Create(catalogs, &error);
304 EXPECT_TRUE(bundle);
305 EXPECT_TRUE(error.empty());
306
307 return bundle;
308 }
309
TEST(ExtensionL10nUtil,LocalizeEmptyManifest)310 TEST(ExtensionL10nUtil, LocalizeEmptyManifest) {
311 base::DictionaryValue manifest;
312 std::string error;
313 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
314
315 EXPECT_FALSE(
316 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
317 EXPECT_EQ(std::string(errors::kInvalidName), error);
318 }
319
TEST(ExtensionL10nUtil,LocalizeManifestWithoutNameMsgAndEmptyDescription)320 TEST(ExtensionL10nUtil, LocalizeManifestWithoutNameMsgAndEmptyDescription) {
321 base::DictionaryValue manifest;
322 manifest.SetString(keys::kName, "no __MSG");
323 std::string error;
324 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
325
326 EXPECT_TRUE(
327 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
328
329 std::string result;
330 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
331 EXPECT_EQ("no __MSG", result);
332
333 EXPECT_FALSE(manifest.HasKey(keys::kDescription));
334
335 EXPECT_TRUE(error.empty());
336 }
337
TEST(ExtensionL10nUtil,LocalizeManifestWithNameMsgAndEmptyDescription)338 TEST(ExtensionL10nUtil, LocalizeManifestWithNameMsgAndEmptyDescription) {
339 base::DictionaryValue manifest;
340 manifest.SetString(keys::kName, "__MSG_name__");
341 std::string error;
342 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
343
344 EXPECT_TRUE(
345 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
346
347 std::string result;
348 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
349 EXPECT_EQ("name", result);
350
351 EXPECT_FALSE(manifest.HasKey(keys::kDescription));
352
353 EXPECT_TRUE(error.empty());
354 }
355
TEST(ExtensionL10nUtil,LocalizeManifestWithLocalLaunchURL)356 TEST(ExtensionL10nUtil, LocalizeManifestWithLocalLaunchURL) {
357 base::DictionaryValue manifest;
358 manifest.SetString(keys::kName, "name");
359 manifest.SetString(keys::kLaunchLocalPath, "__MSG_launch_local_path__");
360 std::string error;
361 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
362
363 EXPECT_TRUE(
364 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
365
366 std::string result;
367 ASSERT_TRUE(manifest.GetString(keys::kLaunchLocalPath, &result));
368 EXPECT_EQ("main.html", result);
369
370 EXPECT_TRUE(error.empty());
371 }
372
TEST(ExtensionL10nUtil,LocalizeManifestWithHostedLaunchURL)373 TEST(ExtensionL10nUtil, LocalizeManifestWithHostedLaunchURL) {
374 base::DictionaryValue manifest;
375 manifest.SetString(keys::kName, "name");
376 manifest.SetString(keys::kLaunchWebURL, "__MSG_launch_web_url__");
377 std::string error;
378 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
379
380 EXPECT_TRUE(
381 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
382
383 std::string result;
384 ASSERT_TRUE(manifest.GetString(keys::kLaunchWebURL, &result));
385 EXPECT_EQ("http://www.google.com/", result);
386
387 EXPECT_TRUE(error.empty());
388 }
389
TEST(ExtensionL10nUtil,LocalizeManifestWithBadNameMsg)390 TEST(ExtensionL10nUtil, LocalizeManifestWithBadNameMsg) {
391 base::DictionaryValue manifest;
392 manifest.SetString(keys::kName, "__MSG_name_is_bad__");
393 manifest.SetString(keys::kDescription, "__MSG_description__");
394 std::string error;
395 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
396
397 EXPECT_FALSE(
398 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
399
400 std::string result;
401 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
402 EXPECT_EQ("__MSG_name_is_bad__", result);
403
404 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
405 EXPECT_EQ("__MSG_description__", result);
406
407 EXPECT_EQ("Variable __MSG_name_is_bad__ used but not defined.", error);
408 }
409
TEST(ExtensionL10nUtil,LocalizeManifestWithNameDescriptionDefaultTitleMsgs)410 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionDefaultTitleMsgs) {
411 base::DictionaryValue manifest;
412 manifest.SetString(keys::kName, "__MSG_name__");
413 manifest.SetString(keys::kDescription, "__MSG_description__");
414 std::string action_title(keys::kBrowserAction);
415 action_title.append(".");
416 action_title.append(keys::kPageActionDefaultTitle);
417 manifest.SetString(action_title, "__MSG_title__");
418
419 std::string error;
420 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
421
422 EXPECT_TRUE(
423 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
424
425 std::string result;
426 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
427 EXPECT_EQ("name", result);
428
429 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
430 EXPECT_EQ("description", result);
431
432 ASSERT_TRUE(manifest.GetString(action_title, &result));
433 EXPECT_EQ("action title", result);
434
435 EXPECT_TRUE(error.empty());
436 }
437
TEST(ExtensionL10nUtil,LocalizeManifestWithNameDescriptionOmniboxMsgs)438 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionOmniboxMsgs) {
439 base::DictionaryValue manifest;
440 manifest.SetString(keys::kName, "__MSG_name__");
441 manifest.SetString(keys::kDescription, "__MSG_description__");
442 manifest.SetString(keys::kOmniboxKeyword, "__MSG_omnibox_keyword__");
443
444 std::string error;
445 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
446
447 EXPECT_TRUE(
448 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
449
450 std::string result;
451 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
452 EXPECT_EQ("name", result);
453
454 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
455 EXPECT_EQ("description", result);
456
457 ASSERT_TRUE(manifest.GetString(keys::kOmniboxKeyword, &result));
458 EXPECT_EQ("omnibox keyword", result);
459
460 EXPECT_TRUE(error.empty());
461 }
462
TEST(ExtensionL10nUtil,LocalizeManifestWithNameDescriptionFileHandlerTitle)463 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionFileHandlerTitle) {
464 base::DictionaryValue manifest;
465 manifest.SetString(keys::kName, "__MSG_name__");
466 manifest.SetString(keys::kDescription, "__MSG_description__");
467 base::ListValue* handlers = new base::ListValue();
468 manifest.Set(keys::kFileBrowserHandlers, handlers);
469 base::DictionaryValue* handler = new base::DictionaryValue();
470 handlers->Append(handler);
471 handler->SetString(keys::kPageActionDefaultTitle,
472 "__MSG_file_handler_title__");
473
474 std::string error;
475 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
476
477 EXPECT_TRUE(
478 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
479
480 std::string result;
481 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
482 EXPECT_EQ("name", result);
483
484 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
485 EXPECT_EQ("description", result);
486
487 ASSERT_TRUE(handler->GetString(keys::kPageActionDefaultTitle, &result));
488 EXPECT_EQ("file handler title", result);
489
490 EXPECT_TRUE(error.empty());
491 }
492
TEST(ExtensionL10nUtil,LocalizeManifestWithNameDescriptionCommandDescription)493 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionCommandDescription) {
494 base::DictionaryValue manifest;
495 manifest.SetString(keys::kName, "__MSG_name__");
496 manifest.SetString(keys::kDescription, "__MSG_description__");
497 base::DictionaryValue* commands = new DictionaryValue();
498 std::string commands_title(keys::kCommands);
499 manifest.Set(commands_title, commands);
500
501 base::DictionaryValue* first_command = new DictionaryValue();
502 commands->Set("first_command", first_command);
503 first_command->SetString(keys::kDescription,
504 "__MSG_first_command_description__");
505
506 base::DictionaryValue* second_command = new DictionaryValue();
507 commands->Set("second_command", second_command);
508 second_command->SetString(keys::kDescription,
509 "__MSG_second_command_description__");
510
511 std::string error;
512 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
513
514 EXPECT_TRUE(
515 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
516
517 std::string result;
518 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
519 EXPECT_EQ("name", result);
520
521 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
522 EXPECT_EQ("description", result);
523
524 ASSERT_TRUE(manifest.GetString("commands.first_command.description",
525 &result));
526 EXPECT_EQ("first command", result);
527
528 ASSERT_TRUE(manifest.GetString("commands.second_command.description",
529 &result));
530 EXPECT_EQ("second command", result);
531
532 EXPECT_TRUE(error.empty());
533 }
534
TEST(ExtensionL10nUtil,LocalizeManifestWithShortName)535 TEST(ExtensionL10nUtil, LocalizeManifestWithShortName) {
536 base::DictionaryValue manifest;
537 manifest.SetString(keys::kName, "extension name");
538 manifest.SetString(keys::kShortName, "__MSG_short_name__");
539
540 std::string error;
541 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
542
543 EXPECT_TRUE(
544 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
545 EXPECT_TRUE(error.empty());
546
547 std::string result;
548 ASSERT_TRUE(manifest.GetString(keys::kShortName, &result));
549 EXPECT_EQ("short_name", result);
550 }
551
TEST(ExtensionL10nUtil,LocalizeManifestWithBadShortName)552 TEST(ExtensionL10nUtil, LocalizeManifestWithBadShortName) {
553 base::DictionaryValue manifest;
554 manifest.SetString(keys::kName, "extension name");
555 manifest.SetString(keys::kShortName, "__MSG_short_name_bad__");
556
557 std::string error;
558 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
559
560 EXPECT_FALSE(
561 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
562 EXPECT_FALSE(error.empty());
563
564 std::string result;
565 ASSERT_TRUE(manifest.GetString(keys::kShortName, &result));
566 EXPECT_EQ("__MSG_short_name_bad__", result);
567 }
568
TEST(ExtensionL10nUtil,LocalizeManifestWithSearchProviderMsgs)569 TEST(ExtensionL10nUtil, LocalizeManifestWithSearchProviderMsgs) {
570 base::DictionaryValue manifest;
571 manifest.SetString(keys::kName, "__MSG_name__");
572 manifest.SetString(keys::kDescription, "__MSG_description__");
573
574 base::DictionaryValue* search_provider = new base::DictionaryValue;
575 search_provider->SetString("name", "__MSG_country__");
576 search_provider->SetString("keyword", "__MSG_omnibox_keyword__");
577 search_provider->SetString("search_url", "http://www.foo.__MSG_country__");
578 search_provider->SetString("favicon_url", "http://www.foo.__MSG_country__");
579 search_provider->SetString("suggest_url", "http://www.foo.__MSG_country__");
580 manifest.Set(keys::kSearchProvider, search_provider);
581
582 std::string error;
583 scoped_ptr<MessageBundle> messages(CreateManifestBundle());
584
585 EXPECT_TRUE(
586 extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
587
588 std::string result;
589 ASSERT_TRUE(manifest.GetString(keys::kName, &result));
590 EXPECT_EQ("name", result);
591
592 ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
593 EXPECT_EQ("description", result);
594
595 std::string key_prefix(keys::kSearchProvider);
596 key_prefix += '.';
597 ASSERT_TRUE(manifest.GetString(key_prefix + "name", &result));
598 EXPECT_EQ("de", result);
599
600 ASSERT_TRUE(manifest.GetString(key_prefix + "keyword", &result));
601 EXPECT_EQ("omnibox keyword", result);
602
603 ASSERT_TRUE(manifest.GetString(key_prefix + "search_url", &result));
604 EXPECT_EQ("http://www.foo.de", result);
605
606 ASSERT_TRUE(manifest.GetString(key_prefix + "favicon_url", &result));
607 EXPECT_EQ("http://www.foo.de", result);
608
609 ASSERT_TRUE(manifest.GetString(key_prefix + "suggest_url", &result));
610 EXPECT_EQ("http://www.foo.de", result);
611
612 EXPECT_TRUE(error.empty());
613 }
614
615 // Try with NULL manifest.
TEST(ExtensionL10nUtil,ShouldRelocalizeManifestWithNullManifest)616 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithNullManifest) {
617 EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(NULL));
618 }
619
620 // Try with default and current locales missing.
TEST(ExtensionL10nUtil,ShouldRelocalizeManifestEmptyManifest)621 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestEmptyManifest) {
622 base::DictionaryValue manifest;
623 EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
624 }
625
626 // Try with missing current_locale.
TEST(ExtensionL10nUtil,ShouldRelocalizeManifestWithDefaultLocale)627 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithDefaultLocale) {
628 base::DictionaryValue manifest;
629 manifest.SetString(keys::kDefaultLocale, "en_US");
630 EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
631 }
632
633 // Try with missing default_locale.
TEST(ExtensionL10nUtil,ShouldRelocalizeManifestWithCurrentLocale)634 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithCurrentLocale) {
635 base::DictionaryValue manifest;
636 manifest.SetString(keys::kCurrentLocale,
637 extension_l10n_util::CurrentLocaleOrDefault());
638 EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
639 }
640
641 // Try with all data present, but with same current_locale as system locale.
TEST(ExtensionL10nUtil,ShouldRelocalizeManifestSameCurrentLocale)642 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestSameCurrentLocale) {
643 base::DictionaryValue manifest;
644 manifest.SetString(keys::kDefaultLocale, "en_US");
645 manifest.SetString(keys::kCurrentLocale,
646 extension_l10n_util::CurrentLocaleOrDefault());
647 EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
648 }
649
650 // Try with all data present, but with different current_locale.
TEST(ExtensionL10nUtil,ShouldRelocalizeManifestDifferentCurrentLocale)651 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestDifferentCurrentLocale) {
652 base::DictionaryValue manifest;
653 manifest.SetString(keys::kDefaultLocale, "en_US");
654 manifest.SetString(keys::kCurrentLocale, "sr");
655 EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
656 }
657
TEST(ExtensionL10nUtil,GetAllFallbackLocales)658 TEST(ExtensionL10nUtil, GetAllFallbackLocales) {
659 std::vector<std::string> fallback_locales;
660 extension_l10n_util::GetAllFallbackLocales("en_US", "all", &fallback_locales);
661 ASSERT_EQ(3U, fallback_locales.size());
662
663 CHECK_EQ("en_US", fallback_locales[0]);
664 CHECK_EQ("en", fallback_locales[1]);
665 CHECK_EQ("all", fallback_locales[2]);
666 }
667
668 } // namespace
669