Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / extension_l10n_util_unittest.cc
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(base::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                   base::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(base::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(base::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(base::WriteFile(locale_1.Append(kMessagesFilename),
223                               data.c_str(), data.length()));
224
225   base::FilePath locale_2 = src_path.AppendASCII("sr");
226   ASSERT_TRUE(base::CreateDirectory(locale_2));
227
228   ASSERT_TRUE(base::WriteFile(locale_2.Append(kMessagesFilename),
229                               data.c_str(), data.length()));
230
231   std::set<std::string> valid_locales;
232   valid_locales.insert("sr");
233   valid_locales.insert("en");
234   std::string error;
235   // JSON parser hides duplicates. We are going to get only one key/value
236   // pair at the end.
237   scoped_ptr<MessageBundle> message_bundle(
238       extension_l10n_util::LoadMessageCatalogs(src_path,
239                                                "en",
240                                                "sr",
241                                                valid_locales,
242                                                &error));
243   EXPECT_TRUE(NULL != message_bundle.get());
244   EXPECT_TRUE(error.empty());
245 }
246
247 // Caller owns the returned object.
248 MessageBundle* CreateManifestBundle() {
249   linked_ptr<base::DictionaryValue> catalog(new base::DictionaryValue);
250
251   base::DictionaryValue* name_tree = new base::DictionaryValue();
252   name_tree->SetString("message", "name");
253   catalog->Set("name", name_tree);
254
255   base::DictionaryValue* short_name_tree = new base::DictionaryValue();
256   short_name_tree->SetString("message", "short_name");
257   catalog->Set("short_name", short_name_tree);
258
259   base::DictionaryValue* description_tree = new base::DictionaryValue();
260   description_tree->SetString("message", "description");
261   catalog->Set("description", description_tree);
262
263   base::DictionaryValue* action_title_tree = new base::DictionaryValue();
264   action_title_tree->SetString("message", "action title");
265   catalog->Set("title", action_title_tree);
266
267   base::DictionaryValue* omnibox_keyword_tree = new base::DictionaryValue();
268   omnibox_keyword_tree->SetString("message", "omnibox keyword");
269   catalog->Set("omnibox_keyword", omnibox_keyword_tree);
270
271   base::DictionaryValue* file_handler_title_tree = new base::DictionaryValue();
272   file_handler_title_tree->SetString("message", "file handler title");
273   catalog->Set("file_handler_title", file_handler_title_tree);
274
275   base::DictionaryValue* launch_local_path_tree = new base::DictionaryValue();
276   launch_local_path_tree->SetString("message", "main.html");
277   catalog->Set("launch_local_path", launch_local_path_tree);
278
279   base::DictionaryValue* launch_web_url_tree = new base::DictionaryValue();
280   launch_web_url_tree->SetString("message", "http://www.google.com/");
281   catalog->Set("launch_web_url", launch_web_url_tree);
282
283   base::DictionaryValue* first_command_description_tree =
284       new base::DictionaryValue();
285   first_command_description_tree->SetString("message", "first command");
286   catalog->Set("first_command_description", first_command_description_tree);
287
288   base::DictionaryValue* second_command_description_tree =
289       new base::DictionaryValue();
290   second_command_description_tree->SetString("message", "second command");
291   catalog->Set("second_command_description", second_command_description_tree);
292
293   base::DictionaryValue* url_country_tree = new base::DictionaryValue();
294   url_country_tree->SetString("message", "de");
295   catalog->Set("country", url_country_tree);
296
297   std::vector<linked_ptr<base::DictionaryValue> > catalogs;
298   catalogs.push_back(catalog);
299
300   std::string error;
301   MessageBundle* bundle = MessageBundle::Create(catalogs, &error);
302   EXPECT_TRUE(bundle);
303   EXPECT_TRUE(error.empty());
304
305   return bundle;
306 }
307
308 TEST(ExtensionL10nUtil, LocalizeEmptyManifest) {
309   base::DictionaryValue manifest;
310   std::string error;
311   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
312
313   EXPECT_FALSE(
314       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
315   EXPECT_EQ(std::string(errors::kInvalidName), error);
316 }
317
318 TEST(ExtensionL10nUtil, LocalizeManifestWithoutNameMsgAndEmptyDescription) {
319   base::DictionaryValue manifest;
320   manifest.SetString(keys::kName, "no __MSG");
321   std::string error;
322   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
323
324   EXPECT_TRUE(
325       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
326
327   std::string result;
328   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
329   EXPECT_EQ("no __MSG", result);
330
331   EXPECT_FALSE(manifest.HasKey(keys::kDescription));
332
333   EXPECT_TRUE(error.empty());
334 }
335
336 TEST(ExtensionL10nUtil, LocalizeManifestWithNameMsgAndEmptyDescription) {
337   base::DictionaryValue manifest;
338   manifest.SetString(keys::kName, "__MSG_name__");
339   std::string error;
340   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
341
342   EXPECT_TRUE(
343       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
344
345   std::string result;
346   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
347   EXPECT_EQ("name", result);
348
349   EXPECT_FALSE(manifest.HasKey(keys::kDescription));
350
351   EXPECT_TRUE(error.empty());
352 }
353
354 TEST(ExtensionL10nUtil, LocalizeManifestWithLocalLaunchURL) {
355   base::DictionaryValue manifest;
356   manifest.SetString(keys::kName, "name");
357   manifest.SetString(keys::kLaunchLocalPath, "__MSG_launch_local_path__");
358   std::string error;
359   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
360
361   EXPECT_TRUE(
362       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
363
364   std::string result;
365   ASSERT_TRUE(manifest.GetString(keys::kLaunchLocalPath, &result));
366   EXPECT_EQ("main.html", result);
367
368   EXPECT_TRUE(error.empty());
369 }
370
371 TEST(ExtensionL10nUtil, LocalizeManifestWithHostedLaunchURL) {
372   base::DictionaryValue manifest;
373   manifest.SetString(keys::kName, "name");
374   manifest.SetString(keys::kLaunchWebURL, "__MSG_launch_web_url__");
375   std::string error;
376   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
377
378   EXPECT_TRUE(
379       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
380
381   std::string result;
382   ASSERT_TRUE(manifest.GetString(keys::kLaunchWebURL, &result));
383   EXPECT_EQ("http://www.google.com/", result);
384
385   EXPECT_TRUE(error.empty());
386 }
387
388 TEST(ExtensionL10nUtil, LocalizeManifestWithBadNameMsg) {
389   base::DictionaryValue manifest;
390   manifest.SetString(keys::kName, "__MSG_name_is_bad__");
391   manifest.SetString(keys::kDescription, "__MSG_description__");
392   std::string error;
393   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
394
395   EXPECT_FALSE(
396       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
397
398   std::string result;
399   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
400   EXPECT_EQ("__MSG_name_is_bad__", result);
401
402   ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
403   EXPECT_EQ("__MSG_description__", result);
404
405   EXPECT_EQ("Variable __MSG_name_is_bad__ used but not defined.", error);
406 }
407
408 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionDefaultTitleMsgs) {
409   base::DictionaryValue manifest;
410   manifest.SetString(keys::kName, "__MSG_name__");
411   manifest.SetString(keys::kDescription, "__MSG_description__");
412   std::string action_title(keys::kBrowserAction);
413   action_title.append(".");
414   action_title.append(keys::kPageActionDefaultTitle);
415   manifest.SetString(action_title, "__MSG_title__");
416
417   std::string error;
418   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
419
420   EXPECT_TRUE(
421       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
422
423   std::string result;
424   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
425   EXPECT_EQ("name", result);
426
427   ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
428   EXPECT_EQ("description", result);
429
430   ASSERT_TRUE(manifest.GetString(action_title, &result));
431   EXPECT_EQ("action title", result);
432
433   EXPECT_TRUE(error.empty());
434 }
435
436 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionOmniboxMsgs) {
437   base::DictionaryValue manifest;
438   manifest.SetString(keys::kName, "__MSG_name__");
439   manifest.SetString(keys::kDescription, "__MSG_description__");
440   manifest.SetString(keys::kOmniboxKeyword, "__MSG_omnibox_keyword__");
441
442   std::string error;
443   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
444
445   EXPECT_TRUE(
446       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
447
448   std::string result;
449   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
450   EXPECT_EQ("name", result);
451
452   ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
453   EXPECT_EQ("description", result);
454
455   ASSERT_TRUE(manifest.GetString(keys::kOmniboxKeyword, &result));
456   EXPECT_EQ("omnibox keyword", result);
457
458   EXPECT_TRUE(error.empty());
459 }
460
461 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionFileHandlerTitle) {
462   base::DictionaryValue manifest;
463   manifest.SetString(keys::kName, "__MSG_name__");
464   manifest.SetString(keys::kDescription, "__MSG_description__");
465   base::ListValue* handlers = new base::ListValue();
466   manifest.Set(keys::kFileBrowserHandlers, handlers);
467   base::DictionaryValue* handler = new base::DictionaryValue();
468   handlers->Append(handler);
469   handler->SetString(keys::kPageActionDefaultTitle,
470                      "__MSG_file_handler_title__");
471
472   std::string error;
473   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
474
475   EXPECT_TRUE(
476       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
477
478   std::string result;
479   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
480   EXPECT_EQ("name", result);
481
482   ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
483   EXPECT_EQ("description", result);
484
485   ASSERT_TRUE(handler->GetString(keys::kPageActionDefaultTitle, &result));
486   EXPECT_EQ("file handler title", result);
487
488   EXPECT_TRUE(error.empty());
489 }
490
491 TEST(ExtensionL10nUtil, LocalizeManifestWithNameDescriptionCommandDescription) {
492   base::DictionaryValue manifest;
493   manifest.SetString(keys::kName, "__MSG_name__");
494   manifest.SetString(keys::kDescription, "__MSG_description__");
495   base::DictionaryValue* commands = new base::DictionaryValue();
496   std::string commands_title(keys::kCommands);
497   manifest.Set(commands_title, commands);
498
499   base::DictionaryValue* first_command = new base::DictionaryValue();
500   commands->Set("first_command", first_command);
501   first_command->SetString(keys::kDescription,
502                            "__MSG_first_command_description__");
503
504   base::DictionaryValue* second_command = new base::DictionaryValue();
505   commands->Set("second_command", second_command);
506   second_command->SetString(keys::kDescription,
507                             "__MSG_second_command_description__");
508
509   std::string error;
510   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
511
512   EXPECT_TRUE(
513       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
514
515   std::string result;
516   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
517   EXPECT_EQ("name", result);
518
519   ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
520   EXPECT_EQ("description", result);
521
522   ASSERT_TRUE(manifest.GetString("commands.first_command.description",
523                                  &result));
524   EXPECT_EQ("first command", result);
525
526   ASSERT_TRUE(manifest.GetString("commands.second_command.description",
527                                  &result));
528   EXPECT_EQ("second command", result);
529
530   EXPECT_TRUE(error.empty());
531 }
532
533 TEST(ExtensionL10nUtil, LocalizeManifestWithShortName) {
534   base::DictionaryValue manifest;
535   manifest.SetString(keys::kName, "extension name");
536   manifest.SetString(keys::kShortName, "__MSG_short_name__");
537
538   std::string error;
539   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
540
541   EXPECT_TRUE(
542       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
543   EXPECT_TRUE(error.empty());
544
545   std::string result;
546   ASSERT_TRUE(manifest.GetString(keys::kShortName, &result));
547   EXPECT_EQ("short_name", result);
548 }
549
550 TEST(ExtensionL10nUtil, LocalizeManifestWithBadShortName) {
551   base::DictionaryValue manifest;
552   manifest.SetString(keys::kName, "extension name");
553   manifest.SetString(keys::kShortName, "__MSG_short_name_bad__");
554
555   std::string error;
556   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
557
558   EXPECT_FALSE(
559       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
560   EXPECT_FALSE(error.empty());
561
562   std::string result;
563   ASSERT_TRUE(manifest.GetString(keys::kShortName, &result));
564   EXPECT_EQ("__MSG_short_name_bad__", result);
565 }
566
567 TEST(ExtensionL10nUtil, LocalizeManifestWithSearchProviderMsgs) {
568   base::DictionaryValue manifest;
569   manifest.SetString(keys::kName, "__MSG_name__");
570   manifest.SetString(keys::kDescription, "__MSG_description__");
571
572   base::DictionaryValue* search_provider = new base::DictionaryValue;
573   search_provider->SetString("name", "__MSG_country__");
574   search_provider->SetString("keyword", "__MSG_omnibox_keyword__");
575   search_provider->SetString("search_url", "http://www.foo.__MSG_country__");
576   search_provider->SetString("favicon_url", "http://www.foo.__MSG_country__");
577   search_provider->SetString("suggest_url", "http://www.foo.__MSG_country__");
578   manifest.Set(keys::kOverrideSearchProvider, search_provider);
579
580   manifest.SetString(keys::kOverrideHomepage, "http://www.foo.__MSG_country__");
581
582   base::ListValue* startup_pages = new base::ListValue;
583   startup_pages->AppendString("http://www.foo.__MSG_country__");
584   manifest.Set(keys::kOverrideStartupPage, startup_pages);
585
586   std::string error;
587   scoped_ptr<MessageBundle> messages(CreateManifestBundle());
588
589   EXPECT_TRUE(
590       extension_l10n_util::LocalizeManifest(*messages, &manifest, &error));
591
592   std::string result;
593   ASSERT_TRUE(manifest.GetString(keys::kName, &result));
594   EXPECT_EQ("name", result);
595
596   ASSERT_TRUE(manifest.GetString(keys::kDescription, &result));
597   EXPECT_EQ("description", result);
598
599   std::string key_prefix(keys::kOverrideSearchProvider);
600   key_prefix += '.';
601   ASSERT_TRUE(manifest.GetString(key_prefix + "name", &result));
602   EXPECT_EQ("de", result);
603
604   ASSERT_TRUE(manifest.GetString(key_prefix + "keyword", &result));
605   EXPECT_EQ("omnibox keyword", result);
606
607   ASSERT_TRUE(manifest.GetString(key_prefix + "search_url", &result));
608   EXPECT_EQ("http://www.foo.de", result);
609
610   ASSERT_TRUE(manifest.GetString(key_prefix + "favicon_url", &result));
611   EXPECT_EQ("http://www.foo.de", result);
612
613   ASSERT_TRUE(manifest.GetString(key_prefix + "suggest_url", &result));
614   EXPECT_EQ("http://www.foo.de", result);
615
616   ASSERT_TRUE(manifest.GetString(keys::kOverrideHomepage, &result));
617   EXPECT_EQ("http://www.foo.de", result);
618
619   ASSERT_TRUE(manifest.GetList(keys::kOverrideStartupPage, &startup_pages));
620   ASSERT_TRUE(startup_pages->GetString(0, &result));
621   EXPECT_EQ("http://www.foo.de", result);
622
623   EXPECT_TRUE(error.empty());
624 }
625
626 // Try with NULL manifest.
627 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithNullManifest) {
628   EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(NULL));
629 }
630
631 // Try with default and current locales missing.
632 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestEmptyManifest) {
633   base::DictionaryValue manifest;
634   EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
635 }
636
637 // Try with missing current_locale.
638 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithDefaultLocale) {
639   base::DictionaryValue manifest;
640   manifest.SetString(keys::kDefaultLocale, "en_US");
641   EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
642 }
643
644 // Try with missing default_locale.
645 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestWithCurrentLocale) {
646   base::DictionaryValue manifest;
647   manifest.SetString(keys::kCurrentLocale,
648                      extension_l10n_util::CurrentLocaleOrDefault());
649   EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
650 }
651
652 // Try with all data present, but with same current_locale as system locale.
653 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestSameCurrentLocale) {
654   base::DictionaryValue manifest;
655   manifest.SetString(keys::kDefaultLocale, "en_US");
656   manifest.SetString(keys::kCurrentLocale,
657                      extension_l10n_util::CurrentLocaleOrDefault());
658   EXPECT_FALSE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
659 }
660
661 // Try with all data present, but with different current_locale.
662 TEST(ExtensionL10nUtil, ShouldRelocalizeManifestDifferentCurrentLocale) {
663   base::DictionaryValue manifest;
664   manifest.SetString(keys::kDefaultLocale, "en_US");
665   manifest.SetString(keys::kCurrentLocale, "sr");
666   EXPECT_TRUE(extension_l10n_util::ShouldRelocalizeManifest(&manifest));
667 }
668
669 TEST(ExtensionL10nUtil, GetAllFallbackLocales) {
670   std::vector<std::string> fallback_locales;
671   extension_l10n_util::GetAllFallbackLocales("en_US", "all", &fallback_locales);
672   ASSERT_EQ(3U, fallback_locales.size());
673
674   CHECK_EQ("en_US", fallback_locales[0]);
675   CHECK_EQ("en", fallback_locales[1]);
676   CHECK_EQ("all", fallback_locales[2]);
677 }
678
679 }  // namespace