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 "chrome/browser/ui/webui/options/language_options_handler.h" 6 7 #include <string> 8 9 #include "base/memory/singleton.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/values.h" 12 #include "chrome/browser/chromeos/customization_document.h" 13 #include "chrome/browser/chromeos/input_method/input_method_configuration.h" 14 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" 15 #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" 16 #include "chromeos/ime/input_method_descriptor.h" 17 #include "chromeos/system/statistics_provider.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 using chromeos::input_method::InputMethodDescriptor; 21 using chromeos::input_method::InputMethodDescriptors; 22 using chromeos::input_method::MockInputMethodManager; 23 24 namespace { 25 26 class MachineStatisticsInitializer { 27 public: 28 MachineStatisticsInitializer() { 29 base::MessageLoop tmp_loop(base::MessageLoop::TYPE_DEFAULT); 30 chromeos::system::StatisticsProvider::GetInstance() 31 ->StartLoadingMachineStatistics(tmp_loop.message_loop_proxy(), false); 32 tmp_loop.RunUntilIdle(); 33 } 34 static MachineStatisticsInitializer* GetInstance(); 35 }; 36 37 MachineStatisticsInitializer* MachineStatisticsInitializer::GetInstance() { 38 return Singleton<MachineStatisticsInitializer>::get(); 39 } 40 41 class CrosLanguageOptionsHandlerTest : public testing::Test { 42 public: 43 CrosLanguageOptionsHandlerTest() { 44 chromeos::input_method::InitializeForTesting(new MockInputMethodManager); 45 MachineStatisticsInitializer::GetInstance(); // Ignore result 46 } 47 virtual ~CrosLanguageOptionsHandlerTest() { 48 chromeos::input_method::Shutdown(); 49 } 50 51 protected: 52 InputMethodDescriptors CreateInputMethodDescriptors1() { 53 InputMethodDescriptors descriptors; 54 descriptors.push_back(GetDesc("xkb:us::eng", "us", "en-US")); 55 descriptors.push_back(GetDesc("xkb:fr::fra", "fr", "fr")); 56 descriptors.push_back(GetDesc("xkb:be::fra", "be", "fr")); 57 descriptors.push_back(GetDesc("xkb:is::ice", "is", "is")); 58 return descriptors; 59 } 60 61 InputMethodDescriptors CreateInputMethodDescriptors2() { 62 InputMethodDescriptors descriptors; 63 descriptors.push_back(GetDesc("xkb:us::eng", "us", "en-US")); 64 descriptors.push_back(GetDesc("xkb:ch:fr:fra", "ch(fr)", "fr")); 65 descriptors.push_back(GetDesc("xkb:ch::ger", "ch", "de")); 66 descriptors.push_back(GetDesc("xkb:it::ita", "it", "it")); 67 descriptors.push_back(GetDesc("xkb:is::ice", "is", "is")); 68 return descriptors; 69 } 70 71 private: 72 InputMethodDescriptor GetDesc(const std::string& id, 73 const std::string& raw_layout, 74 const std::string& language_code) { 75 std::vector<std::string> layouts; 76 layouts.push_back(raw_layout); 77 std::vector<std::string> languages; 78 languages.push_back(language_code); 79 return InputMethodDescriptor( 80 id, std::string(), std::string(), layouts, languages, true, 81 GURL(), GURL()); 82 } 83 84 base::ShadowingAtExitManager at_exit_manager_; 85 }; 86 87 } // namespace 88 89 void Test__InitStartupCustomizationDocument(const std::string& manifest) { 90 chromeos::StartupCustomizationDocument::GetInstance()->LoadManifestFromString( 91 manifest); 92 chromeos::StartupCustomizationDocument::GetInstance()->Init( 93 chromeos::system::StatisticsProvider::GetInstance()); 94 } 95 96 TEST_F(CrosLanguageOptionsHandlerTest, GetInputMethodList) { 97 InputMethodDescriptors descriptors = CreateInputMethodDescriptors1(); 98 scoped_ptr<base::ListValue> list( 99 chromeos::options::CrosLanguageOptionsHandler::GetInputMethodList( 100 descriptors)); 101 ASSERT_EQ(4U, list->GetSize()); 102 103 base::DictionaryValue* entry = NULL; 104 base::DictionaryValue *language_code_set = NULL; 105 std::string input_method_id; 106 std::string display_name; 107 std::string language_code; 108 109 // As shown below, the list should be input method ids should appear in 110 // the same order of the descriptors. 111 ASSERT_TRUE(list->GetDictionary(0, &entry)); 112 ASSERT_TRUE(entry->GetString("id", &input_method_id)); 113 ASSERT_TRUE(entry->GetString("displayName", &display_name)); 114 ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); 115 EXPECT_EQ("xkb:us::eng", input_method_id); 116 // Commented out as it depends on translation in generated_resources.grd 117 // (i.e. makes the test fragile). 118 // EXPECT_EQ("English (USA) keyboard layout", display_name); 119 ASSERT_TRUE(language_code_set->HasKey("en-US")); 120 121 ASSERT_TRUE(list->GetDictionary(1, &entry)); 122 ASSERT_TRUE(entry->GetString("id", &input_method_id)); 123 ASSERT_TRUE(entry->GetString("displayName", &display_name)); 124 ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); 125 EXPECT_EQ("xkb:fr::fra", input_method_id); 126 // Commented out. See above. 127 // EXPECT_EQ("French keyboard layout", display_name); 128 ASSERT_TRUE(language_code_set->HasKey("fr")); 129 130 ASSERT_TRUE(list->GetDictionary(2, &entry)); 131 ASSERT_TRUE(entry->GetString("id", &input_method_id)); 132 ASSERT_TRUE(entry->GetString("displayName", &display_name)); 133 ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); 134 EXPECT_EQ("xkb:be::fra", input_method_id); 135 // Commented out. See above. 136 // EXPECT_EQ("Belgian keyboard layout", display_name); 137 ASSERT_TRUE(language_code_set->HasKey("fr")); 138 139 ASSERT_TRUE(list->GetDictionary(3, &entry)); 140 ASSERT_TRUE(entry->GetString("id", &input_method_id)); 141 ASSERT_TRUE(entry->GetString("displayName", &display_name)); 142 ASSERT_TRUE(entry->GetDictionary("languageCodeSet", &language_code_set)); 143 EXPECT_EQ("xkb:is::ice", input_method_id); 144 // Commented out. See above. 145 // EXPECT_EQ("Japanese input method (for US keyboard)", display_name); 146 ASSERT_TRUE(language_code_set->HasKey("is")); 147 } 148 149 TEST_F(CrosLanguageOptionsHandlerTest, GetUILanguageList) { 150 // This requires initialized StatisticsProvider. 151 // (see CrosLanguageOptionsHandlerTest() ) 152 InputMethodDescriptors descriptors = CreateInputMethodDescriptors1(); 153 scoped_ptr<base::ListValue> list( 154 chromeos::options::CrosLanguageOptionsHandler::GetUILanguageList( 155 descriptors)); 156 157 for (size_t i = 0; i < list->GetSize(); ++i) { 158 base::DictionaryValue* dict; 159 ASSERT_TRUE(list->GetDictionary(i, &dict)); 160 std::string code; 161 ASSERT_TRUE(dict->GetString("code", &code)); 162 EXPECT_NE("is", code) 163 << "Icelandic is an example language which has input method " 164 << "but can't use it as UI language."; 165 } 166 } 167 168 const char kStartupManifest1[] = 169 "{\n" 170 " \"version\": \"1.0\",\n" 171 " \"initial_locale\" : \"fr,en-US,de,is,it\",\n" 172 " \"initial_timezone\" : \"Europe/Zurich\",\n" 173 " \"keyboard_layout\" : \"xkb:ch:fr:fra\",\n" 174 " \"registration_url\" : \"http://www.google.com\",\n" 175 " \"setup_content\" : {\n" 176 " \"default\" : {\n" 177 " \"help_page\" : \"file:///opt/oem/help/en-US/help.html\",\n" 178 " \"eula_page\" : \"file:///opt/oem/eula/en-US/eula.html\",\n" 179 " },\n" 180 " }," 181 "}"; 182 183 #define EXPECT_LANGUAGE_CODE_AT(i, value) \ 184 if (list->GetSize() > i) { \ 185 ASSERT_TRUE(list->GetDictionary(i, &dict)); \ 186 ASSERT_TRUE(dict->GetString("code", &code)); \ 187 EXPECT_EQ(value, code) << "Wrong language code at index " << i << "."; \ 188 } 189 190 TEST_F(CrosLanguageOptionsHandlerTest, GetUILanguageListMulti) { 191 Test__InitStartupCustomizationDocument(kStartupManifest1); 192 193 // This requires initialized StatisticsProvider. 194 // (see CrosLanguageOptionsHandlerTest() ) 195 InputMethodDescriptors descriptors = CreateInputMethodDescriptors2(); 196 scoped_ptr<base::ListValue> list( 197 chromeos::options::CrosLanguageOptionsHandler::GetUILanguageList( 198 descriptors)); 199 200 base::DictionaryValue* dict; 201 std::string code; 202 203 for (size_t i = 0; i < list->GetSize(); ++i) { 204 ASSERT_TRUE(list->GetDictionary(i, &dict)); 205 ASSERT_TRUE(dict->GetString("code", &code)); 206 EXPECT_NE("is", code) 207 << "Icelandic is an example language which has input method " 208 << "but can't use it as UI language."; 209 } 210 211 // (4 languages (except islandic) + divider)=5 + all other languages 212 EXPECT_GT(list->GetSize(), 5u); 213 214 EXPECT_LANGUAGE_CODE_AT(0, "fr") 215 EXPECT_LANGUAGE_CODE_AT(1, "en-US") 216 EXPECT_LANGUAGE_CODE_AT(2, "de") 217 EXPECT_LANGUAGE_CODE_AT(3, "it") 218 EXPECT_LANGUAGE_CODE_AT(4, 219 chromeos::options::kVendorOtherLanguagesListDivider); 220 } 221