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.
6 #include "base/command_line.h"
7 #include "base/strings/string_split.h"
8 #include "base/strings/string_util.h"
9 #include "base/threading/thread_restrictions.h"
10 #include "chrome/browser/chromeos/base/locale_util.h"
11 #include "chrome/browser/chromeos/customization/customization_document.h"
12 #include "chrome/browser/profiles/profile_manager.h"
13 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chromeos/system/fake_statistics_provider.h"
16 #include "chromeos/system/statistics_provider.h"
17 #include "content/public/test/test_utils.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "ui/base/l10n/l10n_util.h"
21 using chromeos::locale_util::SwitchLanguageCallback
;
22 using chromeos::locale_util::LanguageSwitchResult
;
28 class LanguageSwitchedWaiter
{
30 explicit LanguageSwitchedWaiter(SwitchLanguageCallback callback
)
31 : callback_(callback
),
33 runner_(new content::MessageLoopRunner
) {}
35 void ExitMessageLoop(const LanguageSwitchResult
& result
) {
38 callback_
.Run(result
);
47 SwitchLanguageCallback
Callback() {
48 return SwitchLanguageCallback(base::Bind(
49 &LanguageSwitchedWaiter::ExitMessageLoop
, base::Unretained(this)));
53 SwitchLanguageCallback callback_
;
55 scoped_refptr
<content::MessageLoopRunner
> runner_
;
56 DISALLOW_COPY_AND_ASSIGN(LanguageSwitchedWaiter
);
60 const char* locale_alias
;
61 const char* locale_name
;
62 } locale_aliases
[] = {{"en-AU", "en-GB"},
70 // Several language IDs are actually aliases to another IDs, so real language
71 // ID is reported as "loaded" when alias is requested.
72 std::string
GetExpectedLanguage(const std::string
& required
) {
73 std::string expected
= required
;
75 for (size_t i
= 0; i
< arraysize(locale_aliases
); ++i
) {
76 if (required
!= locale_aliases
[i
].locale_alias
)
79 expected
= locale_aliases
[i
].locale_name
;
86 void VerifyLanguageSwitched(const LanguageSwitchResult
& result
) {
87 EXPECT_TRUE(result
.success
) << "SwitchLanguage failed: required='"
88 << result
.requested_locale
<< "', actual='"
89 << result
.loaded_locale
90 << "', success=" << result
.success
;
91 EXPECT_EQ(GetExpectedLanguage(result
.requested_locale
), result
.loaded_locale
)
92 << "SwitchLanguage failed: required='" << result
.requested_locale
93 << "', actual='" << result
.loaded_locale
94 << "', success=" << result
.success
;
97 std::string
Print(const std::vector
<std::string
>& locales
) {
98 std::string
result("{");
99 for (size_t i
= 0; i
< locales
.size(); ++i
) {
104 result
+= locales
[i
];
111 const char* kVPDInitialLocales
[] = {
116 "ar,bg,bn,ca,cs,da,de,el,en-AU,en-CA,en-GB,en-NZ,en-US,en-ZA,es,es-419,et,"
117 "fa,fi,fil,fr,fr-CA,gu,he,hi,hr,hu,id,it,ja,kn,ko,lt,lv,ml,mr,ms,nl,nb,pl,"
118 "pt-BR,pt-PT,ro,ru,sk,sl,sr,sv,ta,te,th,tr,vi,zh-CN,zh-TW",
121 const std::vector
<std::string
> languages_available
= {
179 } // anonymous namespace
181 typedef InProcessBrowserTest CustomizationLocaleTest
;
183 IN_PROC_BROWSER_TEST_F(CustomizationLocaleTest
, CheckAvailableLocales
) {
184 for (size_t i
= 0; i
< languages_available
.size(); ++i
) {
185 LanguageSwitchedWaiter
waiter(base::Bind(&VerifyLanguageSwitched
));
186 locale_util::SwitchLanguage(languages_available
[i
], true, true,
188 ProfileManager::GetActiveUserProfile());
191 std::string resolved_locale
;
192 base::ThreadRestrictions::ScopedAllowIO allow_io
;
193 l10n_util::CheckAndResolveLocale(languages_available
[i
],
195 EXPECT_EQ(GetExpectedLanguage(languages_available
[i
]), resolved_locale
)
196 << "CheckAndResolveLocale() failed for language='"
197 << languages_available
[i
] << "'";
202 class CustomizationVPDTest
: public InProcessBrowserTest
,
203 public testing::WithParamInterface
<const char*> {
205 CustomizationVPDTest()
206 : statistics_provider_(new system::FakeStatisticsProvider()) {
207 // Set the instance returned by GetInstance() for testing.
208 system::StatisticsProvider::SetTestProvider(statistics_provider_
.get());
209 statistics_provider_
->SetMachineStatistic("initial_locale", GetParam());
210 statistics_provider_
->SetMachineStatistic("keyboard_layout", "");
214 scoped_ptr
<system::FakeStatisticsProvider
> statistics_provider_
;
217 IN_PROC_BROWSER_TEST_P(CustomizationVPDTest
, GetUILanguageList
) {
218 std::vector
<std::string
> locales
= base::SplitString(
219 GetParam(), ",", base::TRIM_WHITESPACE
, base::SPLIT_WANT_ALL
);
221 for (std::string
& l
: locales
) {
222 base::TrimString(l
, " ", &l
);
225 StartupCustomizationDocument::GetInstance()->configured_locales())
226 << "Test failed for initial_locale='" << GetParam()
227 << "', locales=" << Print(locales
);
229 scoped_ptr
<base::ListValue
> ui_language_list
= GetUILanguageList(NULL
, "");
230 EXPECT_GE(ui_language_list
->GetSize(), locales
.size())
231 << "Test failed for initial_locale='" << GetParam() << "'";
233 for (size_t i
= 0; i
< ui_language_list
->GetSize(); ++i
) {
234 base::DictionaryValue
* language_info
= NULL
;
235 ASSERT_TRUE(ui_language_list
->GetDictionary(i
, &language_info
))
236 << "Test failed for initial_locale='" << GetParam() << "', i=" << i
;
239 ASSERT_TRUE(language_info
->GetString("value", &value
))
240 << "Test failed for initial_locale='" << GetParam() << "', i=" << i
;
242 if (i
< locales
.size()) {
243 EXPECT_EQ(locales
[i
], value
) << "Test failed for initial_locale='"
244 << GetParam() << "', i=" << i
;
246 EXPECT_EQ(kMostRelevantLanguagesDivider
, value
)
247 << "Test failed for initial_locale='" << GetParam() << "', i=" << i
;
253 INSTANTIATE_TEST_CASE_P(StringSequence
,
254 CustomizationVPDTest
,
255 testing::ValuesIn(kVPDInitialLocales
));
257 } // namespace chromeos