Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1358)

Side by Side Diff: chrome/browser/chromeos/preferences_unittest.cc

Issue 312023002: Sync starting language and input method preferences (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refactored for xkb refactor Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/preferences.h" 5 #include "chrome/browser/chromeos/preferences.h"
6 6
7 #include "base/json/json_string_value_serializer.h"
7 #include "base/prefs/pref_member.h" 8 #include "base/prefs/pref_member.h"
9 #include "base/strings/string_split.h"
10 #include "base/strings/string_util.h"
11 #include "chrome/browser/chromeos/input_method/input_method_configuration.h"
8 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h" 12 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
13 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
9 #include "chrome/browser/chromeos/login/users/fake_user_manager.h" 14 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
10 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" 15 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
11 #include "chrome/browser/download/download_prefs.h" 16 #include "chrome/browser/chromeos/system/fake_input_device_settings.h"
17 #include "chrome/common/chrome_constants.h"
12 #include "chrome/common/pref_names.h" 18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_browser_process.h"
13 #include "chrome/test/base/testing_pref_service_syncable.h" 20 #include "chrome/test/base/testing_pref_service_syncable.h"
14 #include "components/pref_registry/pref_registry_syncable.h" 21 #include "chrome/test/base/testing_profile.h"
22 #include "chrome/test/base/testing_profile_manager.h"
23 #include "chromeos/ime/extension_ime_util.h"
24 #include "chromeos/ime/input_method_whitelist.h"
25 #include "chromeos/ime/mock_component_extension_ime_manager_delegate.h"
26 #include "content/public/test/test_browser_thread_bundle.h"
27 #include "content/public/test/test_utils.h"
28 #include "sync/api/attachments/attachment_id.h"
29 #include "sync/api/fake_sync_change_processor.h"
30 #include "sync/api/sync_change.h"
31 #include "sync/api/sync_data.h"
32 #include "sync/api/sync_error_factory.h"
33 #include "sync/api/sync_error_factory_mock.h"
34 #include "sync/api/syncable_service.h"
35 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test .h"
36 #include "sync/protocol/preference_specifics.pb.h"
37 #include "sync/protocol/sync.pb.h"
15 #include "testing/gtest/include/gtest/gtest.h" 38 #include "testing/gtest/include/gtest/gtest.h"
39 #include "url/gurl.h"
16 40
17 namespace chromeos { 41 namespace chromeos {
18 namespace { 42 namespace {
19 43
20 class MyMockInputMethodManager : public input_method::MockInputMethodManager { 44 const char kIdentityIMEID[] =
45 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpIdentityIME";
46 const char kToUpperIMEID[] =
47 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpToUpperIME";
48 const char kAPIArgumentIMEID[] =
49 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpAPIArgumentIME";
50 const char kUnknownIMEID[] =
51 "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpUnknownIME";
52
53 syncer::SyncData
54 CreatePrefSyncData(const std::string& name, const base::Value& value) {
55 std::string serialized;
56 JSONStringValueSerializer json(&serialized);
57 json.Serialize(value);
58 sync_pb::EntitySpecifics specifics;
59 sync_pb::PreferenceSpecifics* pref = specifics.mutable_preference();
60 pref->set_name(name);
61 pref->set_value(serialized);
62 return syncer::SyncData::CreateRemoteData(
63 1,
64 specifics,
65 base::Time(),
66 syncer::AttachmentIdList(),
67 syncer::AttachmentServiceProxyForTest::Create());
68 }
69
70 } // anonymous namespace
71
72 namespace input_method {
73 namespace {
74
75 class MyMockInputMethodManager : public MockInputMethodManager {
21 public: 76 public:
22 class State : public MockInputMethodManager::State { 77 class State : public MockInputMethodManager::State {
23 public: 78 public:
24 explicit State(MyMockInputMethodManager* manager) 79 explicit State(MyMockInputMethodManager* manager)
25 : MockInputMethodManager::State(manager), manager_(manager) {}; 80 : MockInputMethodManager::State(manager), manager_(manager) {
81 input_method_extensions_.reset(new InputMethodDescriptors);
82 }
26 83
27 virtual void ChangeInputMethod(const std::string& input_method_id, 84 virtual void ChangeInputMethod(const std::string& input_method_id,
28 bool show_message) override { 85 bool show_message) override {
29 manager_->last_input_method_id_ = input_method_id; 86 manager_->last_input_method_id_ = input_method_id;
30 // Do the same thing as BrowserStateMonitor::UpdateUserPreferences. 87 // Do the same thing as BrowserStateMonitor::UpdateUserPreferences.
31 const std::string current_input_method_on_pref = 88 const std::string current_input_method_on_pref =
32 manager_->current_->GetValue(); 89 manager_->current_->GetValue();
33 if (current_input_method_on_pref == input_method_id) 90 if (current_input_method_on_pref == input_method_id)
34 return; 91 return;
35 manager_->previous_->SetValue(current_input_method_on_pref); 92 manager_->previous_->SetValue(current_input_method_on_pref);
36 manager_->current_->SetValue(input_method_id); 93 manager_->current_->SetValue(input_method_id);
37 } 94 }
38 95
96 virtual void
97 GetInputMethodExtensions(InputMethodDescriptors* result) override {
98 *result = *input_method_extensions_;
99 }
100
101 virtual void AddInputMethodExtension(
102 const std::string& id,
103 const InputMethodDescriptors& descriptors,
104 InputMethodEngineInterface* instance) override {
105 InputMethodDescriptor descriptor(
106 id, std::string(), std::string(), std::vector<std::string>(),
107 std::vector<std::string>(), false, GURL(), GURL());
108 input_method_extensions_->push_back(descriptor);
109 }
110
39 protected: 111 protected:
40 virtual ~State() {}; 112 virtual ~State() {};
41 113
42 private: 114 private:
43 MyMockInputMethodManager* const manager_; 115 MyMockInputMethodManager* const manager_;
116 scoped_ptr<InputMethodDescriptors> input_method_extensions_;
44 }; 117 };
45 118
46 MyMockInputMethodManager(StringPrefMember* previous, 119 MyMockInputMethodManager(StringPrefMember* previous,
47 StringPrefMember* current) 120 StringPrefMember* current)
48 : previous_(previous), 121 : previous_(previous),
49 current_(current) { 122 current_(current) {
50 state_ = new State(this); 123 state_ = new State(this);
51 } 124 }
52 125
53 virtual ~MyMockInputMethodManager() {} 126 virtual ~MyMockInputMethodManager() {}
54 127
128 virtual scoped_ptr<InputMethodDescriptors>
129 GetSupportedInputMethods() const override {
130 return whitelist_.GetSupportedInputMethods().Pass();
131 }
132
55 std::string last_input_method_id_; 133 std::string last_input_method_id_;
56 134
57 private: 135 private:
58 StringPrefMember* previous_; 136 StringPrefMember* previous_;
59 StringPrefMember* current_; 137 StringPrefMember* current_;
138 InputMethodWhitelist whitelist_;
60 }; 139 };
61 140
62 } // anonymous namespace 141 } // anonymous namespace
63 142 } // namespace input_method
64 TEST(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) { 143
65 chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); 144 class PreferencesTest : public testing::Test {
66 chromeos::ScopedUserManagerEnabler user_manager_enabler(user_manager); 145 public:
67 const char test_user_email[] = "test_user@example.com"; 146 PreferencesTest() {}
68 const user_manager::User* test_user = user_manager->AddUser(test_user_email); 147 virtual ~PreferencesTest() {}
69 user_manager->LoginUser(test_user_email); 148
70 149 virtual void SetUp() override {
71 TestingPrefServiceSyncable prefs; 150 profile_manager_.reset(
72 Preferences::RegisterProfilePrefs(prefs.registry()); 151 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
73 DownloadPrefs::RegisterProfilePrefs(prefs.registry()); 152 ASSERT_TRUE(profile_manager_->SetUp());
74 // kSelectFileLastDirectory is registered for Profile. Here we register it for 153
75 // testing. 154 chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager();
76 prefs.registry()->RegisterStringPref( 155 user_manager_enabler_.reset(
77 prefs::kSelectFileLastDirectory, 156 new chromeos::ScopedUserManagerEnabler(user_manager));
78 std::string(), 157
79 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 158 const char test_user_email[] = "test_user@example.com";
80 159 test_user_ = user_manager->AddUser(test_user_email);
81 StringPrefMember previous; 160 user_manager->LoginUser(test_user_email);
82 previous.Init(prefs::kLanguagePreviousInputMethod, &prefs); 161 user_manager->SwitchActiveUser(test_user_email);
83 previous.SetValue("KeyboardA"); 162
84 StringPrefMember current; 163 test_profile_ = profile_manager_->CreateTestingProfile(
85 current.Init(prefs::kLanguageCurrentInputMethod, &prefs); 164 chrome::kInitialProfile);
86 current.SetValue("KeyboardB"); 165 pref_service_ = test_profile_->GetTestingPrefService();
87 166
88 MyMockInputMethodManager mock_manager(&previous, &current); 167 previous_input_method_.Init(
89 Preferences testee(&mock_manager); 168 prefs::kLanguagePreviousInputMethod, pref_service_);
90 testee.InitUserPrefsForTesting( 169 previous_input_method_.SetValue("KeyboardA");
91 &prefs, test_user, mock_manager.GetActiveIMEState()); 170 current_input_method_.Init(
92 testee.SetInputMethodListForTesting(); 171 prefs::kLanguageCurrentInputMethod, pref_service_);
93 172 current_input_method_.SetValue("KeyboardB");
94 // Confirm they're unchanged. 173
95 EXPECT_EQ("KeyboardA", previous.GetValue()); 174 mock_manager_ = new input_method::MyMockInputMethodManager(
96 EXPECT_EQ("KeyboardB", current.GetValue()); 175 &previous_input_method_, &current_input_method_);
97 EXPECT_EQ("KeyboardB", mock_manager.last_input_method_id_); 176 input_method::InitializeForTesting(mock_manager_);
177 system::InputDeviceSettings::SetSettingsForTesting(
178 new system::FakeInputDeviceSettings());
179
180 prefs_.reset(new Preferences(mock_manager_));
181 }
182
183 virtual void TearDown() override {
184 input_method::Shutdown();
185 // UserSessionManager doesn't listen to profile destruction, so make sure
186 // the default IME state isn't still cached in case test_profile_ is
187 // given the same address in the next test.
188 UserSessionManager::GetInstance()->RemoveProfileForTesting(test_profile_);
189 }
190
191 scoped_ptr<TestingProfileManager> profile_manager_;
192 scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
193 scoped_ptr<Preferences> prefs_;
194 StringPrefMember previous_input_method_;
195 StringPrefMember current_input_method_;
196
197 // Not owned.
198 const user_manager::User* test_user_;
199 TestingProfile* test_profile_;
200 TestingPrefServiceSyncable* pref_service_;
201 input_method::MyMockInputMethodManager* mock_manager_;
202
203 private:
204 DISALLOW_COPY_AND_ASSIGN(PreferencesTest);
205 };
206
207 TEST_F(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) {
208 prefs_->Init(test_profile_, test_user_);
209
210 // Confirm the current and previous input methods are unchanged.
211 EXPECT_EQ("KeyboardA", previous_input_method_.GetValue());
212 EXPECT_EQ("KeyboardB", current_input_method_.GetValue());
213 EXPECT_EQ("KeyboardB", mock_manager_->last_input_method_id_);
214 }
215
216 class InputMethodPreferencesTest : public PreferencesTest {
217 public:
218 InputMethodPreferencesTest() {}
219 virtual ~InputMethodPreferencesTest() {}
220
221 virtual void SetUp() override {
222 PreferencesTest::SetUp();
223
224 // Initialize pref members.
225 preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
226 pref_service_);
227 preferred_languages_syncable_.Init(
228 prefs::kLanguagePreferredLanguagesSyncable,
229 pref_service_);
230 preload_engines_.Init(prefs::kLanguagePreloadEngines, pref_service_);
231 preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable,
232 pref_service_);
233 enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes,
234 pref_service_);
235 enabled_extension_imes_syncable_.Init(
236 prefs::kLanguageEnabledExtensionImesSyncable, pref_service_);
237
238 // Initialize component and 3rd-party input method extensions.
239 InitComponentExtensionIMEManager();
240 input_method::InputMethodDescriptors descriptors;
241 mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
242 kIdentityIMEID,
243 descriptors,
244 NULL);
245 mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
246 kToUpperIMEID,
247 descriptors,
248 NULL);
249 mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
250 kAPIArgumentIMEID,
251 descriptors,
252 NULL);
253 }
254
255 void InitComponentExtensionIMEManager() {
256 // Set our custom IME list on the mock delegate.
257 input_method::MockComponentExtIMEManagerDelegate* mock_delegate =
258 new input_method::MockComponentExtIMEManagerDelegate();
259 mock_delegate->set_ime_list(CreateImeList());
260
261 // Pass the mock delegate to a new ComponentExtensionIMEManager.
262 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(mock_delegate);
263 scoped_ptr<ComponentExtensionIMEManager> component_extension_ime_manager(
264 new ComponentExtensionIMEManager);
265 component_extension_ime_manager->Initialize(delegate.Pass());
266
267 // Add the ComponentExtensionIMEManager to the mock InputMethodManager.
268 mock_manager_->SetComponentExtensionIMEManager(
269 component_extension_ime_manager.Pass());
270 }
271
272 std::vector<ComponentExtensionIME> CreateImeList() {
273 std::vector<ComponentExtensionIME> ime_list;
274
275 ComponentExtensionIME ext;
276 ext.id = extension_ime_util::kMozcExtensionId;
277 ext.description = "ext_description";
278 ext.path = base::FilePath("ext_file_path");
279
280 ComponentExtensionEngine ext_engine1;
281 ext_engine1.engine_id = "nacl_mozc_us";
282 ext_engine1.display_name = "ext_engine_1_display_name";
283 ext_engine1.language_codes.push_back("ja");
284 ext_engine1.layouts.push_back("us");
285 ext.engines.push_back(ext_engine1);
286
287 ComponentExtensionEngine ext_engine2;
288 ext_engine2.engine_id = "nacl_mozc_jp";
289 ext_engine2.display_name = "ext_engine_2_display_name";
290 ext_engine2.language_codes.push_back("ja");
291 ext_engine2.layouts.push_back("jp");
292 ext.engines.push_back(ext_engine2);
293
294 ime_list.push_back(ext);
295 return ime_list;
296 }
297
298 // Helper function to set local language and input values.
299 void SetLocalValues(const std::string& preferred_languages,
300 const std::string& preload_engines,
301 const std::string& enabled_extension_imes) {
302 preferred_languages_.SetValue(preferred_languages);
303 preload_engines_.SetValue(preload_engines);
304 enabled_extension_imes_.SetValue(enabled_extension_imes);
305 }
306
307 // Helper function to set global language and input values.
308 void SetGlobalValues(const std::string& preferred_languages,
309 const std::string& preload_engines,
310 const std::string& enabled_extension_imes) {
311 preferred_languages_syncable_.SetValue(preferred_languages);
312 preload_engines_syncable_.SetValue(preload_engines);
313 enabled_extension_imes_syncable_.SetValue(enabled_extension_imes);
314 }
315
316 // Helper function to check local language and input values.
317 void ExpectLocalValues(const std::string& preferred_languages,
318 const std::string& preload_engines,
319 const std::string& enabled_extension_imes) {
320 EXPECT_EQ(preferred_languages, preferred_languages_.GetValue());
321 EXPECT_EQ(preload_engines, preload_engines_.GetValue());
322 EXPECT_EQ(enabled_extension_imes, enabled_extension_imes_.GetValue());
323 }
324
325 // Helper function to check global language and input values.
326 void ExpectGlobalValues(const std::string& preferred_languages,
327 const std::string& preload_engines,
328 const std::string& enabled_extension_imes) {
329 EXPECT_EQ(preferred_languages, preferred_languages_syncable_.GetValue());
330 EXPECT_EQ(preload_engines, preload_engines_syncable_.GetValue());
331 EXPECT_EQ(enabled_extension_imes,
332 enabled_extension_imes_syncable_.GetValue());
333 }
334
335 // Translates engine IDs in a CSV string to input method IDs.
336 std::string ToInputMethodIds(std::string value) {
337 std::vector<std::string> tokens;
338 base::SplitString(value, ',', &tokens);
339 std::transform(tokens.begin(), tokens.end(), tokens.begin(),
340 &extension_ime_util::GetInputMethodIDByEngineID);
341 return JoinString(tokens, ',');
342 }
343
344 StringPrefMember preferred_languages_;
345 StringPrefMember preferred_languages_syncable_;
346 StringPrefMember preload_engines_;
347 StringPrefMember preload_engines_syncable_;
348 StringPrefMember enabled_extension_imes_;
349 StringPrefMember enabled_extension_imes_syncable_;
350 content::TestBrowserThreadBundle thread_bundle_;
351
352 private:
353 DISALLOW_COPY_AND_ASSIGN(InputMethodPreferencesTest);
354 };
355
356 // Tests that the server values are added to the values chosen at OOBE.
357 TEST_F(InputMethodPreferencesTest, TestOobeAndSync) {
358 // Choose options at OOBE.
359 pref_service_->SetBoolean(
360 prefs::kLanguageShouldMergeInputMethods, true);
361 SetLocalValues("es",
362 ToInputMethodIds("xkb:us:altgr-intl:eng"),
363 std::string());
364
365 // Initialize preferences.
366 prefs_->Init(test_profile_, test_user_);
367
368 // Suppose we add an input method before syncing starts.
369 preload_engines_.SetValue(
370 ToInputMethodIds("xkb:us:altgr-intl:eng,xkb:us:intl:eng"));
371
372 // Create some values to come from the server.
373 syncer::SyncDataList sync_data_list;
374 sync_data_list.push_back(CreatePrefSyncData(
375 prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
376 sync_data_list.push_back(CreatePrefSyncData(
377 prefs::kLanguagePreloadEnginesSyncable,
378 base::StringValue("xkb:se::swe")));
379 sync_data_list.push_back(CreatePrefSyncData(
380 prefs::kLanguageEnabledExtensionImesSyncable,
381 base::StringValue(kIdentityIMEID)));
382
383 // Sync for the first time.
384 syncer::SyncableService* sync =
385 pref_service_->GetSyncableService(
386 syncer::PREFERENCES);
387 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
388 sync_data_list,
389 scoped_ptr<syncer::SyncChangeProcessor>(
390 new syncer::FakeSyncChangeProcessor),
391 scoped_ptr<syncer::SyncErrorFactory>(
392 new syncer::SyncErrorFactoryMock));
393 content::RunAllPendingInMessageLoop();
394
395 // Note that we expect the preload_engines to have been translated to input
396 // method IDs during the merge.
397 std::string expected_languages("es,ru,fi");
398 std::string expected_preload_engines(
399 "xkb:us:altgr-intl:eng,xkb:us:intl:eng,xkb:se::swe");
400 std::string expected_extensions(kIdentityIMEID);
401 {
402 SCOPED_TRACE("Server values should have merged into local values.");
403 ExpectLocalValues(
404 expected_languages,
405 ToInputMethodIds(expected_preload_engines),
406 expected_extensions);
407 }
408 {
409 SCOPED_TRACE("Server values should have been updated to local values.");
410 ExpectGlobalValues(
411 expected_languages, expected_preload_engines, expected_extensions);
412 }
413
414 // Update the global values from the server again.
415 syncer::SyncChangeList change_list;
416 change_list.push_back(syncer::SyncChange(
417 FROM_HERE,
418 syncer::SyncChange::ACTION_UPDATE,
419 CreatePrefSyncData(
420 prefs::kLanguagePreferredLanguagesSyncable,
421 base::StringValue("de"))));
422 change_list.push_back(syncer::SyncChange(
423 FROM_HERE,
424 syncer::SyncChange::ACTION_UPDATE,
425 CreatePrefSyncData(
426 prefs::kLanguagePreloadEnginesSyncable,
427 base::StringValue(ToInputMethodIds("xkb:de::ger")))));
428 change_list.push_back(syncer::SyncChange(
429 FROM_HERE,
430 syncer::SyncChange::ACTION_UPDATE,
431 CreatePrefSyncData(
432 prefs::kLanguageEnabledExtensionImesSyncable,
433 base::StringValue(kToUpperIMEID))));
434 sync->ProcessSyncChanges(FROM_HERE, change_list);
435 content::RunAllPendingInMessageLoop();
436
437 {
438 SCOPED_TRACE("Local preferences should have remained the same.");
439 ExpectLocalValues(
440 expected_languages,
441 ToInputMethodIds(expected_preload_engines),
442 expected_extensions);
443 }
444 // Change local preferences.
445 SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), "ime2");
446 {
447 SCOPED_TRACE("Global preferences should have been updated.");
448 ExpectGlobalValues("ja", "xkb:jp::jpn", "ime2");
449 }
450 content::RunAllPendingInMessageLoop();
451 }
452
453 // Tests that logging in after sync has completed changes nothing.
454 TEST_F(InputMethodPreferencesTest, TestLogIn) {
455 // Set up existing preference values.
456 std::string languages("es");
457 std::string preload_engines(ToInputMethodIds("xkb:es::spa"));
458 std::string extensions(kIdentityIMEID);
459
460 SetLocalValues(languages, preload_engines, extensions);
461 SetGlobalValues(languages, preload_engines, extensions);
462 pref_service_->SetBoolean(
463 prefs::kLanguageShouldMergeInputMethods, false);
464
465 // Initialize preferences.
466 prefs_->Init(test_profile_, test_user_);
467
468 // Create some values to come from the server.
469 syncer::SyncDataList sync_data_list;
470 sync_data_list.push_back(CreatePrefSyncData(
471 prefs::kLanguagePreferredLanguages, base::StringValue("ru,fi")));
472 sync_data_list.push_back(CreatePrefSyncData(
473 prefs::kLanguagePreloadEngines,
474 base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
475 sync_data_list.push_back(CreatePrefSyncData(
476 prefs::kLanguageEnabledExtensionImes, base::StringValue(kIdentityIMEID)));
477
478 // Sync.
479 syncer::SyncableService* sync =
480 pref_service_->GetSyncableService(
481 syncer::PREFERENCES);
482 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
483 sync_data_list,
484 scoped_ptr<syncer::SyncChangeProcessor>(
485 new syncer::FakeSyncChangeProcessor),
486 scoped_ptr<syncer::SyncErrorFactory>(
487 new syncer::SyncErrorFactoryMock));
488 content::RunAllPendingInMessageLoop();
489 {
490 SCOPED_TRACE("Local preferences should have remained the same.");
491 ExpectLocalValues(languages, preload_engines, extensions);
492 }
493 // Change local preferences.
494 SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), kToUpperIMEID);
495 content::RunAllPendingInMessageLoop();
496 {
497 SCOPED_TRACE("Global preferences should have been updated.");
498 ExpectGlobalValues("ja", "xkb:jp::jpn", kToUpperIMEID);
499 }
500 }
501
502 // Tests that logging in with preferences from before a) XKB component
503 // extensions and b) the IME syncing logic doesn't overwrite settings.
504 TEST_F(InputMethodPreferencesTest, TestLogInLegacy) {
505 // Simulate existing local preferences from M-36.
506 SetLocalValues("es", "xkb:es::spa", kIdentityIMEID);
507
508 // Initialize preferences.
509 prefs_->Init(test_profile_, test_user_);
510
511 // Sync. Since this is an existing profile, the local values shouldn't change.
512 syncer::SyncDataList sync_data_list;
513 sync_data_list.push_back(CreatePrefSyncData(
514 prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
515 sync_data_list.push_back(CreatePrefSyncData(
516 prefs::kLanguagePreloadEnginesSyncable,
517 base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
518 sync_data_list.push_back(CreatePrefSyncData(
519 prefs::kLanguageEnabledExtensionImesSyncable,
520 base::StringValue(kToUpperIMEID)));
521
522 syncer::SyncableService* sync =
523 pref_service_->GetSyncableService(
524 syncer::PREFERENCES);
525 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
526 sync_data_list,
527 scoped_ptr<syncer::SyncChangeProcessor>(
528 new syncer::FakeSyncChangeProcessor),
529 scoped_ptr<syncer::SyncErrorFactory>(
530 new syncer::SyncErrorFactoryMock));
531 content::RunAllPendingInMessageLoop();
532 {
533 SCOPED_TRACE("Local preferences should have remained the same.");
534 ExpectLocalValues("es", "xkb:es::spa", kIdentityIMEID);
535 }
536 {
537 SCOPED_TRACE("Global preferences should have remained the same.");
538 ExpectGlobalValues("ru,fi", ToInputMethodIds("xkb:ru::rus"), kToUpperIMEID);
539 }
540 // Change local preferences.
541 SetLocalValues("ja", ToInputMethodIds("xkb:jp::jp"), kAPIArgumentIMEID);
542 {
543 SCOPED_TRACE("Global preferences should have been updated.");
544 ExpectGlobalValues("ja", "xkb:jp::jp", kAPIArgumentIMEID);
545 }
546 }
547
548 // Tests some edge cases: empty strings, lots of values, duplicates.
549 TEST_F(InputMethodPreferencesTest, MergeStressTest) {
550 SetLocalValues("hr,lv,lt,es-419,he,el,da,ca,es,cs,bg",
551 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
552 std::string());
553 pref_service_->SetBoolean(
554 prefs::kLanguageShouldMergeInputMethods, true);
555
556 // Initialize preferences.
557 prefs_->Init(test_profile_, test_user_);
558
559 // Change input methods and languages before syncing starts.
560 std::string local_extensions =
561 kToUpperIMEID + std::string(",") +
562 kAPIArgumentIMEID + std::string(",") +
563 kIdentityIMEID;
564 SetLocalValues(
565 "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar",
566 ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr"),
567 local_extensions);
568
569 // Create some tricky values to come from the server.
570 syncer::SyncDataList sync_data_list;
571 sync_data_list.push_back(CreatePrefSyncData(
572 prefs::kLanguagePreferredLanguagesSyncable,
573 base::StringValue("ar,fi,es,de,ar")));
574 sync_data_list.push_back(CreatePrefSyncData(
575 prefs::kLanguagePreloadEnginesSyncable,
576 base::StringValue(
577 "nacl_mozc_us,xkb:ru::rus,xkb:ru::rus,xkb:es::spa,xkb:es::spa")));
578 sync_data_list.push_back(CreatePrefSyncData(
579 prefs::kLanguageEnabledExtensionImesSyncable,
580 base::StringValue(std::string())));
581
582 // Sync for the first time.
583 syncer::SyncableService* sync =
584 pref_service_->GetSyncableService(
585 syncer::PREFERENCES);
586 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
587 sync_data_list,
588 scoped_ptr<syncer::SyncChangeProcessor>(
589 new syncer::FakeSyncChangeProcessor),
590 scoped_ptr<syncer::SyncErrorFactory>(
591 new syncer::SyncErrorFactoryMock));
592 content::RunAllPendingInMessageLoop();
593 {
594 SCOPED_TRACE("Server values should have merged into local values.");
595 ExpectLocalValues(
596 "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
597 ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,"
598 "nacl_mozc_us,xkb:ru::rus"),
599 local_extensions);
600 }
601 {
602 SCOPED_TRACE("Server values should have incorporated local values.");
603 ExpectGlobalValues(
604 "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
605 "xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,nacl_mozc_us,xkb:ru::rus",
606 local_extensions);
607 }
608 }
609
610 // Tests non-existent IDs.
611 TEST_F(InputMethodPreferencesTest, MergeInvalidValues) {
612 SetLocalValues("es",
613 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
614 kIdentityIMEID);
615 pref_service_->SetBoolean(
616 prefs::kLanguageShouldMergeInputMethods, true);
617
618 // Initialize preferences.
619 prefs_->Init(test_profile_, test_user_);
620
621 // Create some valid and some non-existent IDs from the server.
622 std::string preload_engines(
623 "xkb:ru::rus,xkb:xy::xyz,"
624 "_comp_ime_nothisisnotactuallyanextensionidxkb:es::spa," +
625 ToInputMethodIds("xkb:jp::jpn"));
626 syncer::SyncDataList sync_data_list;
627 sync_data_list.push_back(CreatePrefSyncData(
628 prefs::kLanguagePreferredLanguagesSyncable,
629 base::StringValue("klingon,en-US")));
630 sync_data_list.push_back(CreatePrefSyncData(
631 prefs::kLanguagePreloadEnginesSyncable,
632 base::StringValue(preload_engines)));
633 sync_data_list.push_back(CreatePrefSyncData(
634 prefs::kLanguageEnabledExtensionImesSyncable,
635 base::StringValue(kUnknownIMEID)));
636
637 // Sync for the first time.
638 syncer::SyncableService* sync =
639 pref_service_->GetSyncableService(
640 syncer::PREFERENCES);
641 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
642 sync_data_list,
643 scoped_ptr<syncer::SyncChangeProcessor>(
644 new syncer::FakeSyncChangeProcessor),
645 scoped_ptr<syncer::SyncErrorFactory>(
646 new syncer::SyncErrorFactoryMock));
647 content::RunAllPendingInMessageLoop();
648 {
649 SCOPED_TRACE("Only valid server values should have been merged in.");
650 ExpectLocalValues(
651 "es,en-US",
652 ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
653 kIdentityIMEID);
654 }
655 }
656
657 // Tests that we merge input methods even if syncing has started before
658 // initialization of Preferences.
659 TEST_F(InputMethodPreferencesTest, MergeAfterSyncing) {
660 SetLocalValues("es",
661 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
662 kIdentityIMEID);
663 pref_service_->SetBoolean(
664 prefs::kLanguageShouldMergeInputMethods, true);
665
666 // Create some valid and some non-existent IDs from the server.
667 std::string preload_engines(
668 "xkb:ru::rus,xkb:xy::xyz," + ToInputMethodIds("xkb:jp::jpn"));
669 syncer::SyncDataList sync_data_list;
670 sync_data_list.push_back(CreatePrefSyncData(
671 prefs::kLanguagePreferredLanguagesSyncable,
672 base::StringValue("en-US")));
673 sync_data_list.push_back(CreatePrefSyncData(
674 prefs::kLanguagePreloadEnginesSyncable,
675 base::StringValue(preload_engines)));
676 sync_data_list.push_back(CreatePrefSyncData(
677 prefs::kLanguageEnabledExtensionImesSyncable,
678 base::StringValue(kUnknownIMEID)));
679
680 // Sync for the first time.
681 syncer::SyncableService* sync =
682 pref_service_->GetSyncableService(
683 syncer::PREFERENCES);
684 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
685 sync_data_list,
686 scoped_ptr<syncer::SyncChangeProcessor>(
687 new syncer::FakeSyncChangeProcessor),
688 scoped_ptr<syncer::SyncErrorFactory>(
689 new syncer::SyncErrorFactoryMock));
690 content::RunAllPendingInMessageLoop();
691
692 // Initialize preferences.
693 prefs_->Init(test_profile_, test_user_);
694 content::RunAllPendingInMessageLoop();
695 {
696 SCOPED_TRACE("Local values should have been merged on initialization.");
697 ExpectLocalValues(
698 "es,en-US",
699 ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
700 kIdentityIMEID);
701 }
702 {
703 SCOPED_TRACE(
704 "Syncable values should have added local values on initialization.");
705 ExpectGlobalValues(
706 "es,en-US",
707 "xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:xy::xyz," +
708 ToInputMethodIds("xkb:jp::jpn"),
709 std::string(kIdentityIMEID) + "," + kUnknownIMEID);
710 }
98 } 711 }
99 712
100 } // namespace chromeos 713 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698