1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/spellcheck_common.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/test/test_utils.h"
#include "url/gurl.h"
using content::BrowserContext;
namespace {
// A corrupted BDICT data used in DeleteCorruptedBDICT. Please do not use this
// BDICT data for other tests.
const uint8 kCorruptedBDICT[] = {
0x42, 0x44, 0x69, 0x63, 0x02, 0x00, 0x01, 0x00,
0x20, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
0x65, 0x72, 0xe0, 0xac, 0x27, 0xc7, 0xda, 0x66,
0x6d, 0x1e, 0xa6, 0x35, 0xd1, 0xf6, 0xb7, 0x35,
0x32, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
0x0a, 0x0a, 0x41, 0x46, 0x20, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0xe6, 0x49, 0x00, 0x68, 0x02,
0x73, 0x06, 0x74, 0x0b, 0x77, 0x11, 0x79, 0x15,
};
} // namespace
class SpellcheckServiceBrowserTest : public InProcessBrowserTest {
public:
BrowserContext* GetContext() {
return static_cast<BrowserContext*>(browser()->profile());
}
};
// Tests that we can delete a corrupted BDICT file used by hunspell. We do not
// run this test on Mac because Mac does not use hunspell by default.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest, DeleteCorruptedBDICT) {
// Write the corrupted BDICT data to create a corrupted BDICT file.
base::FilePath dict_dir;
ASSERT_TRUE(PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir));
base::FilePath bdict_path =
chrome::spellcheck_common::GetVersionedFileName("en-US", dict_dir);
size_t actual = base::WriteFile(bdict_path,
reinterpret_cast<const char*>(kCorruptedBDICT),
arraysize(kCorruptedBDICT));
EXPECT_EQ(arraysize(kCorruptedBDICT), actual);
// Attach an event to the SpellcheckService object so we can receive its
// status updates.
base::WaitableEvent event(true, false);
SpellcheckService::AttachStatusEvent(&event);
BrowserContext* context = GetContext();
// Ensure that the SpellcheckService object does not already exist. Otherwise
// the next line will not force creation of the SpellcheckService and the
// test will fail.
SpellcheckService* service = static_cast<SpellcheckService*>(
SpellcheckServiceFactory::GetInstance()->GetServiceForBrowserContext(
context,
false));
ASSERT_EQ(NULL, service);
// Getting the spellcheck_service will initialize the SpellcheckService
// object with the corrupted BDICT file created above since the hunspell
// dictionary is loaded in the SpellcheckService constructor right now.
// The SpellCheckHost object will send a BDICT_CORRUPTED event.
SpellcheckServiceFactory::GetForContext(context);
// Check the received event. Also we check if Chrome has successfully deleted
// the corrupted dictionary. We delete the corrupted dictionary to avoid
// leaking it when this test fails.
content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
EXPECT_EQ(SpellcheckService::BDICT_CORRUPTED,
SpellcheckService::GetStatusEvent());
if (base::PathExists(bdict_path)) {
ADD_FAILURE();
EXPECT_TRUE(base::DeleteFile(bdict_path, true));
}
}
// Checks that preferences migrate correctly.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest, PreferencesMigrated) {
PrefService* prefs = user_prefs::UserPrefs::Get(GetContext());
prefs->Set(prefs::kSpellCheckDictionaries, base::ListValue());
prefs->SetString(prefs::kSpellCheckDictionary, "en-US");
// Create a SpellcheckService which will migrate the preferences.
SpellcheckServiceFactory::GetForContext(GetContext());
// Make sure the preferences have been migrated.
std::string new_pref;
EXPECT_TRUE(
prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &new_pref));
EXPECT_EQ("en-US", new_pref);
EXPECT_TRUE(prefs->GetString(prefs::kSpellCheckDictionary).empty());
}
// Checks that preferences are not migrated when they shouldn't be.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest, PreferencesNotMigrated) {
PrefService* prefs = user_prefs::UserPrefs::Get(GetContext());
base::ListValue dictionaries;
dictionaries.AppendString("en-US");
prefs->Set(prefs::kSpellCheckDictionaries, dictionaries);
prefs->SetString(prefs::kSpellCheckDictionary, "fr");
// Create a SpellcheckService which will migrate the preferences.
SpellcheckServiceFactory::GetForContext(GetContext());
// Make sure the preferences have not been migrated.
std::string new_pref;
EXPECT_TRUE(
prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &new_pref));
EXPECT_EQ("en-US", new_pref);
EXPECT_TRUE(prefs->GetString(prefs::kSpellCheckDictionary).empty());
}
// Checks that if a user starts multilingual mode with spellchecking disabled
// that all languages get deselected and spellchecking gets enabled.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest,
SpellcheckingDisabledPreferenceMigration) {
ASSERT_TRUE(chrome::spellcheck_common::IsMultilingualSpellcheckEnabled());
PrefService* prefs = user_prefs::UserPrefs::Get(GetContext());
base::ListValue dictionaries;
dictionaries.AppendString("en-US");
prefs->Set(prefs::kSpellCheckDictionaries, dictionaries);
prefs->SetBoolean(prefs::kEnableContinuousSpellcheck, false);
// Migrate the preferences.
SpellcheckServiceFactory::GetForContext(GetContext());
EXPECT_TRUE(prefs->GetBoolean(prefs::kEnableContinuousSpellcheck));
EXPECT_EQ(0U, prefs->GetList(prefs::kSpellCheckDictionaries)->GetSize());
}
// Make sure that there is only one language in the preference when not using
// multilingual spellchecking.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest,
MultilingualToSingleLanguagePreferenceMigration) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableMultilingualSpellChecker);
ASSERT_FALSE(chrome::spellcheck_common::IsMultilingualSpellcheckEnabled());
PrefService* prefs = user_prefs::UserPrefs::Get(GetContext());
base::ListValue dictionaries;
dictionaries.AppendString("en-US");
dictionaries.AppendString("fr");
prefs->Set(prefs::kSpellCheckDictionaries, dictionaries);
// Migrate the preference.
SpellcheckServiceFactory::GetForContext(GetContext());
EXPECT_EQ(1U, prefs->GetList(prefs::kSpellCheckDictionaries)->GetSize());
std::string new_pref;
ASSERT_TRUE(
prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &new_pref));
EXPECT_EQ("en-US", new_pref);
}
// If using multilingual spellchecking with spellchecking enabled, make sure the
// preference stays the same and spellchecking stays enabled.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest,
MultilingualPreferenceNotMigrated) {
ASSERT_TRUE(chrome::spellcheck_common::IsMultilingualSpellcheckEnabled());
PrefService* prefs = user_prefs::UserPrefs::Get(GetContext());
base::ListValue dictionaries;
dictionaries.AppendString("en-US");
dictionaries.AppendString("fr");
prefs->Set(prefs::kSpellCheckDictionaries, dictionaries);
prefs->SetBoolean(prefs::kEnableContinuousSpellcheck, true);
// Should not migrate any preferences.
SpellcheckServiceFactory::GetForContext(GetContext());
EXPECT_TRUE(prefs->GetBoolean(prefs::kEnableContinuousSpellcheck));
EXPECT_EQ(2U, prefs->GetList(prefs::kSpellCheckDictionaries)->GetSize());
std::string pref;
ASSERT_TRUE(
prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &pref));
EXPECT_EQ("en-US", pref);
ASSERT_TRUE(
prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(1, &pref));
EXPECT_EQ("fr", pref);
}
// If not using multilingual spellchecking and only one language is selected,
// the preference should not change.
IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest,
SingleLanguagePreferenceNotMigrated) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
switches::kDisableMultilingualSpellChecker);
ASSERT_FALSE(chrome::spellcheck_common::IsMultilingualSpellcheckEnabled());
PrefService* prefs = user_prefs::UserPrefs::Get(GetContext());
base::ListValue dictionaries;
dictionaries.AppendString("en-US");
prefs->Set(prefs::kSpellCheckDictionaries, dictionaries);
// Should not migrate any preferences.
SpellcheckServiceFactory::GetForContext(GetContext());
EXPECT_EQ(1U, prefs->GetList(prefs::kSpellCheckDictionaries)->GetSize());
std::string pref;
ASSERT_TRUE(
prefs->GetList(prefs::kSpellCheckDictionaries)->GetString(0, &pref));
EXPECT_EQ("en-US", pref);
}
|