Switch global error menu icon to vectorized MD asset
[chromium-blink-merge.git] / chrome / browser / chromeos / preferences_unittest.cc
blob3d391efc3c4e12538e1cc3bb77472f1927720a37
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.
5 #include "chrome/browser/chromeos/preferences.h"
7 #include "base/json/json_string_value_serializer.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"
12 #include "chrome/browser/chromeos/input_method/mock_input_method_manager.h"
13 #include "chrome/browser/chromeos/login/session/user_session_manager.h"
14 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
15 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
16 #include "chrome/browser/chromeos/system/fake_input_device_settings.h"
17 #include "chrome/common/chrome_constants.h"
18 #include "chrome/common/pref_names.h"
19 #include "chrome/test/base/testing_browser_process.h"
20 #include "chrome/test/base/testing_pref_service_syncable.h"
21 #include "chrome/test/base/testing_profile.h"
22 #include "chrome/test/base/testing_profile_manager.h"
23 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "content/public/test/test_utils.h"
25 #include "sync/api/attachments/attachment_id.h"
26 #include "sync/api/fake_sync_change_processor.h"
27 #include "sync/api/sync_change.h"
28 #include "sync/api/sync_data.h"
29 #include "sync/api/sync_error_factory.h"
30 #include "sync/api/sync_error_factory_mock.h"
31 #include "sync/api/syncable_service.h"
32 #include "sync/internal_api/public/attachments/attachment_service_proxy_for_test.h"
33 #include "sync/protocol/preference_specifics.pb.h"
34 #include "sync/protocol/sync.pb.h"
35 #include "testing/gtest/include/gtest/gtest.h"
36 #include "ui/base/ime/chromeos/extension_ime_util.h"
37 #include "ui/base/ime/chromeos/input_method_whitelist.h"
38 #include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h"
39 #include "url/gurl.h"
41 namespace chromeos {
42 namespace {
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";
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(
64 specifics,
65 base::Time(),
66 syncer::AttachmentIdList(),
67 syncer::AttachmentServiceProxyForTest::Create());
70 } // anonymous namespace
72 namespace input_method {
73 namespace {
75 class MyMockInputMethodManager : public MockInputMethodManager {
76 public:
77 class State : public MockInputMethodManager::State {
78 public:
79 explicit State(MyMockInputMethodManager* manager)
80 : MockInputMethodManager::State(manager), manager_(manager) {
81 input_method_extensions_.reset(new InputMethodDescriptors);
84 void ChangeInputMethod(const std::string& input_method_id,
85 bool show_message) override {
86 manager_->last_input_method_id_ = input_method_id;
87 // Do the same thing as BrowserStateMonitor::UpdateUserPreferences.
88 const std::string current_input_method_on_pref =
89 manager_->current_->GetValue();
90 if (current_input_method_on_pref == input_method_id)
91 return;
92 manager_->previous_->SetValue(current_input_method_on_pref);
93 manager_->current_->SetValue(input_method_id);
96 void GetInputMethodExtensions(InputMethodDescriptors* result) override {
97 *result = *input_method_extensions_;
100 void AddInputMethodExtension(
101 const std::string& id,
102 const InputMethodDescriptors& descriptors,
103 InputMethodEngineInterface* instance) override {
104 InputMethodDescriptor descriptor(
105 id, std::string(), std::string(), std::vector<std::string>(),
106 std::vector<std::string>(), false, GURL(), GURL());
107 input_method_extensions_->push_back(descriptor);
110 protected:
111 ~State() override{};
113 private:
114 MyMockInputMethodManager* const manager_;
115 scoped_ptr<InputMethodDescriptors> input_method_extensions_;
118 MyMockInputMethodManager(StringPrefMember* previous,
119 StringPrefMember* current)
120 : previous_(previous),
121 current_(current) {
122 state_ = new State(this);
125 ~MyMockInputMethodManager() override {}
127 scoped_ptr<InputMethodDescriptors> GetSupportedInputMethods() const override {
128 return whitelist_.GetSupportedInputMethods().Pass();
131 std::string last_input_method_id_;
133 private:
134 StringPrefMember* previous_;
135 StringPrefMember* current_;
136 InputMethodWhitelist whitelist_;
139 } // anonymous namespace
140 } // namespace input_method
142 class PreferencesTest : public testing::Test {
143 public:
144 PreferencesTest() {}
145 ~PreferencesTest() override {}
147 void SetUp() override {
148 profile_manager_.reset(
149 new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
150 ASSERT_TRUE(profile_manager_->SetUp());
152 chromeos::FakeChromeUserManager* user_manager =
153 new chromeos::FakeChromeUserManager();
154 user_manager_enabler_.reset(
155 new chromeos::ScopedUserManagerEnabler(user_manager));
157 const char test_user_email[] = "test_user@example.com";
158 test_user_ = user_manager->AddUser(test_user_email);
159 user_manager->LoginUser(test_user_email);
160 user_manager->SwitchActiveUser(test_user_email);
162 test_profile_ = profile_manager_->CreateTestingProfile(
163 chrome::kInitialProfile);
164 pref_service_ = test_profile_->GetTestingPrefService();
166 previous_input_method_.Init(
167 prefs::kLanguagePreviousInputMethod, pref_service_);
168 previous_input_method_.SetValue("KeyboardA");
169 current_input_method_.Init(
170 prefs::kLanguageCurrentInputMethod, pref_service_);
171 current_input_method_.SetValue("KeyboardB");
173 mock_manager_ = new input_method::MyMockInputMethodManager(
174 &previous_input_method_, &current_input_method_);
175 input_method::InitializeForTesting(mock_manager_);
176 system::InputDeviceSettings::SetSettingsForTesting(
177 new system::FakeInputDeviceSettings());
179 prefs_.reset(new Preferences(mock_manager_));
182 void TearDown() override {
183 input_method::Shutdown();
184 // UserSessionManager doesn't listen to profile destruction, so make sure
185 // the default IME state isn't still cached in case test_profile_ is
186 // given the same address in the next test.
187 UserSessionManager::GetInstance()->RemoveProfileForTesting(test_profile_);
190 void InitPreferences() {
191 prefs_->InitUserPrefsForTesting(
192 pref_service_, test_user_, mock_manager_->GetActiveIMEState());
193 prefs_->SetInputMethodListForTesting();
196 content::TestBrowserThreadBundle thread_bundle_;
197 scoped_ptr<TestingProfileManager> profile_manager_;
198 scoped_ptr<chromeos::ScopedUserManagerEnabler> user_manager_enabler_;
199 scoped_ptr<Preferences> prefs_;
200 StringPrefMember previous_input_method_;
201 StringPrefMember current_input_method_;
203 // Not owned.
204 const user_manager::User* test_user_;
205 TestingProfile* test_profile_;
206 TestingPrefServiceSyncable* pref_service_;
207 input_method::MyMockInputMethodManager* mock_manager_;
209 private:
210 DISALLOW_COPY_AND_ASSIGN(PreferencesTest);
213 TEST_F(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) {
214 InitPreferences();
216 // Confirm the current and previous input methods are unchanged.
217 EXPECT_EQ("KeyboardA", previous_input_method_.GetValue());
218 EXPECT_EQ("KeyboardB", current_input_method_.GetValue());
219 EXPECT_EQ("KeyboardB", mock_manager_->last_input_method_id_);
222 class InputMethodPreferencesTest : public PreferencesTest {
223 public:
224 InputMethodPreferencesTest() {}
225 ~InputMethodPreferencesTest() override {}
227 void SetUp() override {
228 PreferencesTest::SetUp();
230 // Initialize pref members.
231 preferred_languages_.Init(prefs::kLanguagePreferredLanguages,
232 pref_service_);
233 preferred_languages_syncable_.Init(
234 prefs::kLanguagePreferredLanguagesSyncable,
235 pref_service_);
236 preload_engines_.Init(prefs::kLanguagePreloadEngines, pref_service_);
237 preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable,
238 pref_service_);
239 enabled_extension_imes_.Init(prefs::kLanguageEnabledExtensionImes,
240 pref_service_);
241 enabled_extension_imes_syncable_.Init(
242 prefs::kLanguageEnabledExtensionImesSyncable, pref_service_);
244 // Initialize component and 3rd-party input method extensions.
245 InitComponentExtensionIMEManager();
246 input_method::InputMethodDescriptors descriptors;
247 mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
248 kIdentityIMEID,
249 descriptors,
250 NULL);
251 mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
252 kToUpperIMEID,
253 descriptors,
254 NULL);
255 mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
256 kAPIArgumentIMEID,
257 descriptors,
258 NULL);
261 void InitComponentExtensionIMEManager() {
262 // Set our custom IME list on the mock delegate.
263 input_method::MockComponentExtIMEManagerDelegate* mock_delegate =
264 new input_method::MockComponentExtIMEManagerDelegate();
265 mock_delegate->set_ime_list(CreateImeList());
267 // Pass the mock delegate to a new ComponentExtensionIMEManager.
268 scoped_ptr<ComponentExtensionIMEManagerDelegate> delegate(mock_delegate);
269 scoped_ptr<ComponentExtensionIMEManager> component_extension_ime_manager(
270 new ComponentExtensionIMEManager);
271 component_extension_ime_manager->Initialize(delegate.Pass());
273 // Add the ComponentExtensionIMEManager to the mock InputMethodManager.
274 mock_manager_->SetComponentExtensionIMEManager(
275 component_extension_ime_manager.Pass());
278 std::vector<ComponentExtensionIME> CreateImeList() {
279 std::vector<ComponentExtensionIME> ime_list;
281 ComponentExtensionIME ext;
282 ext.id = extension_ime_util::kMozcExtensionId;
283 ext.description = "ext_description";
284 ext.path = base::FilePath("ext_file_path");
286 ComponentExtensionEngine ext_engine1;
287 ext_engine1.engine_id = "nacl_mozc_us";
288 ext_engine1.display_name = "ext_engine_1_display_name";
289 ext_engine1.language_codes.push_back("ja");
290 ext_engine1.layouts.push_back("us");
291 ext.engines.push_back(ext_engine1);
293 ComponentExtensionEngine ext_engine2;
294 ext_engine2.engine_id = "nacl_mozc_jp";
295 ext_engine2.display_name = "ext_engine_2_display_name";
296 ext_engine2.language_codes.push_back("ja");
297 ext_engine2.layouts.push_back("jp");
298 ext.engines.push_back(ext_engine2);
300 ime_list.push_back(ext);
301 return ime_list;
304 // Helper function to set local language and input values.
305 void SetLocalValues(const std::string& preferred_languages,
306 const std::string& preload_engines,
307 const std::string& enabled_extension_imes) {
308 preferred_languages_.SetValue(preferred_languages);
309 preload_engines_.SetValue(preload_engines);
310 enabled_extension_imes_.SetValue(enabled_extension_imes);
313 // Helper function to set global language and input values.
314 void SetGlobalValues(const std::string& preferred_languages,
315 const std::string& preload_engines,
316 const std::string& enabled_extension_imes) {
317 preferred_languages_syncable_.SetValue(preferred_languages);
318 preload_engines_syncable_.SetValue(preload_engines);
319 enabled_extension_imes_syncable_.SetValue(enabled_extension_imes);
322 // Helper function to check local language and input values.
323 void ExpectLocalValues(const std::string& preferred_languages,
324 const std::string& preload_engines,
325 const std::string& enabled_extension_imes) {
326 EXPECT_EQ(preferred_languages, preferred_languages_.GetValue());
327 EXPECT_EQ(preload_engines, preload_engines_.GetValue());
328 EXPECT_EQ(enabled_extension_imes, enabled_extension_imes_.GetValue());
331 // Helper function to check global language and input values.
332 void ExpectGlobalValues(const std::string& preferred_languages,
333 const std::string& preload_engines,
334 const std::string& enabled_extension_imes) {
335 EXPECT_EQ(preferred_languages, preferred_languages_syncable_.GetValue());
336 EXPECT_EQ(preload_engines, preload_engines_syncable_.GetValue());
337 EXPECT_EQ(enabled_extension_imes,
338 enabled_extension_imes_syncable_.GetValue());
341 // Translates engine IDs in a CSV string to input method IDs.
342 std::string ToInputMethodIds(std::string value) {
343 std::vector<std::string> tokens = base::SplitString(
344 value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
345 std::transform(tokens.begin(), tokens.end(), tokens.begin(),
346 &extension_ime_util::GetInputMethodIDByEngineID);
347 return base::JoinString(tokens, ",");
350 StringPrefMember preferred_languages_;
351 StringPrefMember preferred_languages_syncable_;
352 StringPrefMember preload_engines_;
353 StringPrefMember preload_engines_syncable_;
354 StringPrefMember enabled_extension_imes_;
355 StringPrefMember enabled_extension_imes_syncable_;
357 private:
358 DISALLOW_COPY_AND_ASSIGN(InputMethodPreferencesTest);
361 // Tests that the server values are added to the values chosen at OOBE.
362 TEST_F(InputMethodPreferencesTest, TestOobeAndSync) {
363 // Choose options at OOBE.
364 pref_service_->SetBoolean(
365 prefs::kLanguageShouldMergeInputMethods, true);
366 SetLocalValues("es",
367 ToInputMethodIds("xkb:us:altgr-intl:eng"),
368 std::string());
369 InitPreferences();
371 // Suppose we add an input method before syncing starts.
372 preload_engines_.SetValue(
373 ToInputMethodIds("xkb:us:altgr-intl:eng,xkb:us:intl:eng"));
375 // Create some values to come from the server.
376 syncer::SyncDataList sync_data_list;
377 sync_data_list.push_back(CreatePrefSyncData(
378 prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
379 sync_data_list.push_back(CreatePrefSyncData(
380 prefs::kLanguagePreloadEnginesSyncable,
381 base::StringValue("xkb:se::swe")));
382 sync_data_list.push_back(CreatePrefSyncData(
383 prefs::kLanguageEnabledExtensionImesSyncable,
384 base::StringValue(kIdentityIMEID)));
386 // Sync for the first time.
387 syncer::SyncableService* sync =
388 pref_service_->GetSyncableService(
389 syncer::PREFERENCES);
390 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
391 sync_data_list,
392 scoped_ptr<syncer::SyncChangeProcessor>(
393 new syncer::FakeSyncChangeProcessor),
394 scoped_ptr<syncer::SyncErrorFactory>(
395 new syncer::SyncErrorFactoryMock));
396 content::RunAllBlockingPoolTasksUntilIdle();
398 // Note that we expect the preload_engines to have been translated to input
399 // method IDs during the merge.
400 std::string expected_languages("es,ru,fi");
401 std::string expected_preload_engines(
402 "xkb:us:altgr-intl:eng,xkb:us:intl:eng,xkb:se::swe");
403 std::string expected_extensions(kIdentityIMEID);
405 SCOPED_TRACE("Server values should have merged into local values.");
406 ExpectLocalValues(
407 expected_languages,
408 ToInputMethodIds(expected_preload_engines),
409 expected_extensions);
412 SCOPED_TRACE("Server values should have been updated to local values.");
413 ExpectGlobalValues(
414 expected_languages, expected_preload_engines, expected_extensions);
417 // Update the global values from the server again.
418 syncer::SyncChangeList change_list;
419 change_list.push_back(syncer::SyncChange(
420 FROM_HERE,
421 syncer::SyncChange::ACTION_UPDATE,
422 CreatePrefSyncData(
423 prefs::kLanguagePreferredLanguagesSyncable,
424 base::StringValue("de"))));
425 change_list.push_back(syncer::SyncChange(
426 FROM_HERE,
427 syncer::SyncChange::ACTION_UPDATE,
428 CreatePrefSyncData(
429 prefs::kLanguagePreloadEnginesSyncable,
430 base::StringValue(ToInputMethodIds("xkb:de::ger")))));
431 change_list.push_back(syncer::SyncChange(
432 FROM_HERE,
433 syncer::SyncChange::ACTION_UPDATE,
434 CreatePrefSyncData(
435 prefs::kLanguageEnabledExtensionImesSyncable,
436 base::StringValue(kToUpperIMEID))));
437 sync->ProcessSyncChanges(FROM_HERE, change_list);
438 content::RunAllBlockingPoolTasksUntilIdle();
441 SCOPED_TRACE("Local preferences should have remained the same.");
442 ExpectLocalValues(
443 expected_languages,
444 ToInputMethodIds(expected_preload_engines),
445 expected_extensions);
447 // Change local preferences.
448 SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), "ime2");
450 SCOPED_TRACE("Global preferences should have been updated.");
451 ExpectGlobalValues("ja", "xkb:jp::jpn", "ime2");
453 content::RunAllBlockingPoolTasksUntilIdle();
456 // Tests that logging in after sync has completed changes nothing.
457 TEST_F(InputMethodPreferencesTest, TestLogIn) {
458 // Set up existing preference values.
459 std::string languages("es");
460 std::string preload_engines(ToInputMethodIds("xkb:es::spa"));
461 std::string extensions(kIdentityIMEID);
463 SetLocalValues(languages, preload_engines, extensions);
464 SetGlobalValues(languages, preload_engines, extensions);
465 pref_service_->SetBoolean(
466 prefs::kLanguageShouldMergeInputMethods, false);
467 InitPreferences();
469 // Create some values to come from the server.
470 syncer::SyncDataList sync_data_list;
471 sync_data_list.push_back(CreatePrefSyncData(
472 prefs::kLanguagePreferredLanguages, base::StringValue("ru,fi")));
473 sync_data_list.push_back(CreatePrefSyncData(
474 prefs::kLanguagePreloadEngines,
475 base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
476 sync_data_list.push_back(CreatePrefSyncData(
477 prefs::kLanguageEnabledExtensionImes, base::StringValue(kIdentityIMEID)));
479 // Sync.
480 syncer::SyncableService* sync =
481 pref_service_->GetSyncableService(
482 syncer::PREFERENCES);
483 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
484 sync_data_list,
485 scoped_ptr<syncer::SyncChangeProcessor>(
486 new syncer::FakeSyncChangeProcessor),
487 scoped_ptr<syncer::SyncErrorFactory>(
488 new syncer::SyncErrorFactoryMock));
489 content::RunAllBlockingPoolTasksUntilIdle();
491 SCOPED_TRACE("Local preferences should have remained the same.");
492 ExpectLocalValues(languages, preload_engines, extensions);
494 // Change local preferences.
495 SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), kToUpperIMEID);
496 content::RunAllBlockingPoolTasksUntilIdle();
498 SCOPED_TRACE("Global preferences should have been updated.");
499 ExpectGlobalValues("ja", "xkb:jp::jpn", kToUpperIMEID);
503 // Tests that logging in with preferences from before a) XKB component
504 // extensions and b) the IME syncing logic doesn't overwrite settings.
505 TEST_F(InputMethodPreferencesTest, TestLogInLegacy) {
506 // Simulate existing local preferences from M-36.
507 SetLocalValues("es", "xkb:es::spa", kIdentityIMEID);
508 InitPreferences();
510 // Sync. Since this is an existing profile, the local values shouldn't change.
511 syncer::SyncDataList sync_data_list;
512 sync_data_list.push_back(CreatePrefSyncData(
513 prefs::kLanguagePreferredLanguagesSyncable, base::StringValue("ru,fi")));
514 sync_data_list.push_back(CreatePrefSyncData(
515 prefs::kLanguagePreloadEnginesSyncable,
516 base::StringValue(ToInputMethodIds("xkb:ru::rus"))));
517 sync_data_list.push_back(CreatePrefSyncData(
518 prefs::kLanguageEnabledExtensionImesSyncable,
519 base::StringValue(kToUpperIMEID)));
521 syncer::SyncableService* sync =
522 pref_service_->GetSyncableService(
523 syncer::PREFERENCES);
524 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
525 sync_data_list,
526 scoped_ptr<syncer::SyncChangeProcessor>(
527 new syncer::FakeSyncChangeProcessor),
528 scoped_ptr<syncer::SyncErrorFactory>(
529 new syncer::SyncErrorFactoryMock));
530 content::RunAllBlockingPoolTasksUntilIdle();
532 SCOPED_TRACE("Local preferences should have remained the same.");
533 ExpectLocalValues("es", "xkb:es::spa", kIdentityIMEID);
536 SCOPED_TRACE("Global preferences should have remained the same.");
537 ExpectGlobalValues("ru,fi", ToInputMethodIds("xkb:ru::rus"), kToUpperIMEID);
539 // Change local preferences.
540 SetLocalValues("ja", ToInputMethodIds("xkb:jp::jp"), kAPIArgumentIMEID);
542 SCOPED_TRACE("Global preferences should have been updated.");
543 ExpectGlobalValues("ja", "xkb:jp::jp", kAPIArgumentIMEID);
547 // Tests some edge cases: empty strings, lots of values, duplicates.
548 TEST_F(InputMethodPreferencesTest, MergeStressTest) {
549 SetLocalValues("hr,lv,lt,es-419,he,el,da,ca,es,cs,bg",
550 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
551 std::string());
552 pref_service_->SetBoolean(
553 prefs::kLanguageShouldMergeInputMethods, true);
554 InitPreferences();
556 // Change input methods and languages before syncing starts.
557 std::string local_extensions =
558 kToUpperIMEID + std::string(",") +
559 kAPIArgumentIMEID + std::string(",") +
560 kIdentityIMEID;
561 SetLocalValues(
562 "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar",
563 ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr"),
564 local_extensions);
566 // Create some tricky values to come from the server.
567 syncer::SyncDataList sync_data_list;
568 sync_data_list.push_back(CreatePrefSyncData(
569 prefs::kLanguagePreferredLanguagesSyncable,
570 base::StringValue("ar,fi,es,de,ar")));
571 sync_data_list.push_back(CreatePrefSyncData(
572 prefs::kLanguagePreloadEnginesSyncable,
573 base::StringValue(
574 "nacl_mozc_us,xkb:ru::rus,xkb:ru::rus,xkb:es::spa,xkb:es::spa")));
575 sync_data_list.push_back(CreatePrefSyncData(
576 prefs::kLanguageEnabledExtensionImesSyncable,
577 base::StringValue(std::string())));
579 // Sync for the first time.
580 syncer::SyncableService* sync =
581 pref_service_->GetSyncableService(
582 syncer::PREFERENCES);
583 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
584 sync_data_list,
585 scoped_ptr<syncer::SyncChangeProcessor>(
586 new syncer::FakeSyncChangeProcessor),
587 scoped_ptr<syncer::SyncErrorFactory>(
588 new syncer::SyncErrorFactoryMock));
589 content::RunAllBlockingPoolTasksUntilIdle();
591 SCOPED_TRACE("Server values should have merged into local values.");
592 ExpectLocalValues(
593 "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
594 ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,"
595 "nacl_mozc_us,xkb:ru::rus"),
596 local_extensions);
599 SCOPED_TRACE("Server values should have incorporated local values.");
600 ExpectGlobalValues(
601 "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
602 "xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,nacl_mozc_us,xkb:ru::rus",
603 local_extensions);
607 // Tests non-existent IDs.
608 TEST_F(InputMethodPreferencesTest, MergeInvalidValues) {
609 SetLocalValues("es",
610 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
611 kIdentityIMEID);
612 pref_service_->SetBoolean(
613 prefs::kLanguageShouldMergeInputMethods, true);
614 InitPreferences();
616 // Create some valid and some non-existent IDs from the server.
617 std::string preload_engines(
618 "xkb:ru::rus,xkb:xy::xyz,"
619 "_comp_ime_nothisisnotactuallyanextensionidxkb:es::spa," +
620 ToInputMethodIds("xkb:jp::jpn"));
621 syncer::SyncDataList sync_data_list;
622 sync_data_list.push_back(CreatePrefSyncData(
623 prefs::kLanguagePreferredLanguagesSyncable,
624 base::StringValue("klingon,en-US")));
625 sync_data_list.push_back(CreatePrefSyncData(
626 prefs::kLanguagePreloadEnginesSyncable,
627 base::StringValue(preload_engines)));
628 sync_data_list.push_back(CreatePrefSyncData(
629 prefs::kLanguageEnabledExtensionImesSyncable,
630 base::StringValue(kUnknownIMEID)));
632 // Sync for the first time.
633 syncer::SyncableService* sync =
634 pref_service_->GetSyncableService(
635 syncer::PREFERENCES);
636 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
637 sync_data_list,
638 scoped_ptr<syncer::SyncChangeProcessor>(
639 new syncer::FakeSyncChangeProcessor),
640 scoped_ptr<syncer::SyncErrorFactory>(
641 new syncer::SyncErrorFactoryMock));
642 content::RunAllBlockingPoolTasksUntilIdle();
644 SCOPED_TRACE("Only valid server values should have been merged in.");
645 ExpectLocalValues(
646 "es,en-US",
647 ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
648 kIdentityIMEID);
652 // Tests that we merge input methods even if syncing has started before
653 // initialization of Preferences.
654 TEST_F(InputMethodPreferencesTest, MergeAfterSyncing) {
655 SetLocalValues("es",
656 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
657 kIdentityIMEID);
658 pref_service_->SetBoolean(
659 prefs::kLanguageShouldMergeInputMethods, true);
661 // Create some valid and some non-existent IDs from the server.
662 std::string preload_engines(
663 "xkb:ru::rus,xkb:xy::xyz," + ToInputMethodIds("xkb:jp::jpn"));
664 syncer::SyncDataList sync_data_list;
665 sync_data_list.push_back(CreatePrefSyncData(
666 prefs::kLanguagePreferredLanguagesSyncable,
667 base::StringValue("en-US")));
668 sync_data_list.push_back(CreatePrefSyncData(
669 prefs::kLanguagePreloadEnginesSyncable,
670 base::StringValue(preload_engines)));
671 sync_data_list.push_back(CreatePrefSyncData(
672 prefs::kLanguageEnabledExtensionImesSyncable,
673 base::StringValue(kUnknownIMEID)));
675 // Sync for the first time.
676 syncer::SyncableService* sync =
677 pref_service_->GetSyncableService(
678 syncer::PREFERENCES);
679 sync->MergeDataAndStartSyncing(syncer::PREFERENCES,
680 sync_data_list,
681 scoped_ptr<syncer::SyncChangeProcessor>(
682 new syncer::FakeSyncChangeProcessor),
683 scoped_ptr<syncer::SyncErrorFactory>(
684 new syncer::SyncErrorFactoryMock));
685 content::RunAllBlockingPoolTasksUntilIdle();
686 InitPreferences();
687 content::RunAllBlockingPoolTasksUntilIdle();
690 SCOPED_TRACE("Local values should have been merged on initialization.");
691 ExpectLocalValues(
692 "es,en-US",
693 ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
694 kIdentityIMEID);
697 SCOPED_TRACE(
698 "Syncable values should have added local values on initialization.");
699 ExpectGlobalValues(
700 "es,en-US",
701 "xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:xy::xyz," +
702 ToInputMethodIds("xkb:jp::jpn"),
703 std::string(kIdentityIMEID) + "," + kUnknownIMEID);
707 } // namespace chromeos