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 "chrome/browser/ui/webui/chromeos/login/l10n_util.h" 6 7#include "base/at_exit.h" 8#include "base/basictypes.h" 9#include "base/compiler_specific.h" 10#include "base/macros.h" 11#include "base/memory/singleton.h" 12#include "base/message_loop/message_loop.h" 13#include "base/values.h" 14#include "chrome/browser/chromeos/customization_document.h" 15#include "chrome/browser/chromeos/input_method/input_method_configuration.h" 16#include "chrome/browser/ui/webui/chromeos/login/l10n_util_test_util.h" 17#include "chromeos/ime/component_extension_ime_manager.h" 18#include "chromeos/system/statistics_provider.h" 19#include "testing/gtest/include/gtest/gtest.h" 20 21namespace chromeos { 22 23namespace { 24 25class MachineStatisticsInitializer { 26 public: 27 MachineStatisticsInitializer(); 28 29 static MachineStatisticsInitializer* GetInstance(); 30 31 private: 32 DISALLOW_COPY_AND_ASSIGN(MachineStatisticsInitializer); 33}; 34 35MachineStatisticsInitializer::MachineStatisticsInitializer() { 36 base::MessageLoop loop; 37 chromeos::system::StatisticsProvider::GetInstance()-> 38 StartLoadingMachineStatistics(loop.message_loop_proxy(), false); 39 loop.RunUntilIdle(); 40} 41 42// static 43MachineStatisticsInitializer* MachineStatisticsInitializer::GetInstance() { 44 return Singleton<MachineStatisticsInitializer>::get(); 45} 46 47void VerifyOnlyUILanguages(const base::ListValue& list) { 48 for (size_t i = 0; i < list.GetSize(); ++i) { 49 const base::DictionaryValue* dict; 50 ASSERT_TRUE(list.GetDictionary(i, &dict)); 51 std::string code; 52 ASSERT_TRUE(dict->GetString("code", &code)); 53 EXPECT_NE("is", code) 54 << "Icelandic is an example language which has input method " 55 << "but can't use it as UI language."; 56 } 57} 58 59void VerifyLanguageCode(const base::ListValue& list, 60 size_t index, 61 const std::string& expected_code) { 62 const base::DictionaryValue* dict; 63 ASSERT_TRUE(list.GetDictionary(index, &dict)); 64 std::string actual_code; 65 ASSERT_TRUE(dict->GetString("code", &actual_code)); 66 EXPECT_EQ(expected_code, actual_code) 67 << "Wrong language code at index " << index << "."; 68} 69 70} // namespace 71 72class L10nUtilTest : public testing::Test { 73 public: 74 L10nUtilTest(); 75 virtual ~L10nUtilTest(); 76 77 // testing::Test: 78 virtual void SetUp() OVERRIDE; 79 virtual void TearDown() OVERRIDE; 80 81 void SetInputMethods1(); 82 void SetInputMethods2(); 83 84 private: 85 base::ShadowingAtExitManager at_exit_manager_; 86 87 MockInputMethodManagerWithInputMethods* input_manager_; 88}; 89 90L10nUtilTest::L10nUtilTest() 91 : input_manager_(new MockInputMethodManagerWithInputMethods) { 92} 93 94L10nUtilTest::~L10nUtilTest() { 95} 96 97void L10nUtilTest::SetUp() { 98 chromeos::input_method::InitializeForTesting(input_manager_); 99 input_manager_->SetComponentExtensionIMEManager( 100 make_scoped_ptr(new ComponentExtensionIMEManager)); 101 MachineStatisticsInitializer::GetInstance(); // Ignore result. 102} 103 104void L10nUtilTest::TearDown() { 105 chromeos::input_method::Shutdown(); 106} 107 108void L10nUtilTest::SetInputMethods1() { 109 input_manager_->AddInputMethod("xkb:us::eng", "us", "en-US"); 110 input_manager_->AddInputMethod("xkb:fr::fra", "fr", "fr"); 111 input_manager_->AddInputMethod("xkb:be::fra", "be", "fr"); 112 input_manager_->AddInputMethod("xkb:is::ice", "is", "is"); 113} 114 115void L10nUtilTest::SetInputMethods2() { 116 input_manager_->AddInputMethod("xkb:us::eng", "us", "en-US"); 117 input_manager_->AddInputMethod("xkb:ch:fr:fra", "ch(fr)", "fr"); 118 input_manager_->AddInputMethod("xkb:ch::ger", "ch", "de"); 119 input_manager_->AddInputMethod("xkb:it::ita", "it", "it"); 120 input_manager_->AddInputMethod("xkb:is::ice", "is", "is"); 121} 122 123TEST_F(L10nUtilTest, GetUILanguageList) { 124 SetInputMethods1(); 125 126 // This requires initialized StatisticsProvider (see L10nUtilTest()). 127 scoped_ptr<base::ListValue> list(GetUILanguageList(NULL, std::string())); 128 129 VerifyOnlyUILanguages(*list); 130} 131 132TEST_F(L10nUtilTest, FindMostRelevantLocale) { 133 base::ListValue available_locales; 134 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue); 135 dict->SetString("value", "de"); 136 available_locales.Append(dict.release()); 137 dict.reset(new base::DictionaryValue); 138 dict->SetString("value", "fr"); 139 available_locales.Append(dict.release()); 140 dict.reset(new base::DictionaryValue); 141 dict->SetString("value", "en-GB"); 142 available_locales.Append(dict.release()); 143 144 std::vector<std::string> most_relevant_language_codes; 145 EXPECT_EQ("en-US", FindMostRelevantLocale(most_relevant_language_codes, 146 available_locales, 147 "en-US")); 148 149 most_relevant_language_codes.push_back("xx"); 150 EXPECT_EQ("en-US", FindMostRelevantLocale(most_relevant_language_codes, 151 available_locales, 152 "en-US")); 153 154 most_relevant_language_codes.push_back("fr"); 155 EXPECT_EQ("fr", FindMostRelevantLocale(most_relevant_language_codes, 156 available_locales, 157 "en-US")); 158 159 most_relevant_language_codes.push_back("de"); 160 EXPECT_EQ("fr", FindMostRelevantLocale(most_relevant_language_codes, 161 available_locales, 162 "en-US")); 163} 164 165void InitStartupCustomizationDocumentForTesting(const std::string& manifest) { 166 StartupCustomizationDocument::GetInstance()->LoadManifestFromString(manifest); 167 StartupCustomizationDocument::GetInstance()->Init( 168 chromeos::system::StatisticsProvider::GetInstance()); 169} 170 171const char kStartupManifest[] = 172 "{\n" 173 " \"version\": \"1.0\",\n" 174 " \"initial_locale\" : \"fr,en-US,de,is,it\",\n" 175 " \"initial_timezone\" : \"Europe/Zurich\",\n" 176 " \"keyboard_layout\" : \"xkb:ch:fr:fra\",\n" 177 " \"registration_url\" : \"http://www.google.com\",\n" 178 " \"setup_content\" : {\n" 179 " \"default\" : {\n" 180 " \"help_page\" : \"file:///opt/oem/help/en-US/help.html\",\n" 181 " \"eula_page\" : \"file:///opt/oem/eula/en-US/eula.html\",\n" 182 " },\n" 183 " }," 184 "}"; 185 186TEST_F(L10nUtilTest, GetUILanguageListMulti) { 187 InitStartupCustomizationDocumentForTesting(kStartupManifest); 188 SetInputMethods2(); 189 190 // This requires initialized StatisticsProvider (see L10nUtilTest()). 191 scoped_ptr<base::ListValue> list(GetUILanguageList(NULL, std::string())); 192 193 VerifyOnlyUILanguages(*list); 194 195 // (4 languages (except Icelandic) + divider) = 5 + all other languages 196 ASSERT_LE(5u, list->GetSize()); 197 198 VerifyLanguageCode(*list, 0, "fr"); 199 VerifyLanguageCode(*list, 1, "en-US"); 200 VerifyLanguageCode(*list, 2, "de"); 201 VerifyLanguageCode(*list, 3, "it"); 202 VerifyLanguageCode(*list, 4, kMostRelevantLanguagesDivider); 203} 204 205TEST_F(L10nUtilTest, GetUILanguageListWithMostRelevant) { 206 std::vector<std::string> most_relevant_language_codes; 207 most_relevant_language_codes.push_back("it"); 208 most_relevant_language_codes.push_back("de"); 209 most_relevant_language_codes.push_back("nonexistent"); 210 211 // This requires initialized StatisticsProvider (see L10nUtilTest()). 212 scoped_ptr<base::ListValue> 213 list(GetUILanguageList(&most_relevant_language_codes, std::string())); 214 215 VerifyOnlyUILanguages(*list); 216 217 ASSERT_LE(3u, list->GetSize()); 218 219 VerifyLanguageCode(*list, 0, "it"); 220 VerifyLanguageCode(*list, 1, "de"); 221 VerifyLanguageCode(*list, 2, kMostRelevantLanguagesDivider); 222} 223 224} // namespace chromeos 225