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 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 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 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 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 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 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 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 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 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. 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 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 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 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 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 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 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 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 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 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 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 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 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 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. 616 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithNullManifest) { 617 EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(NULL)); 618 } 619 620 // Try with default and current locales missing. 621 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestEmptyManifest) { 622 base::DictionaryValue manifest; 623 EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest)); 624 } 625 626 // Try with missing current_locale. 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. 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. 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. 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 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