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