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

Side by Side Diff: chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc

Issue 11445002: Sync user's custom spellcheck dictionary (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Fix compile on some platforms Created 7 years, 11 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
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 <vector> 5 #include <vector>
6 6
7 #include "base/file_util.h" 7 #include "base/file_util.h"
8 #include "base/string_number_conversions.h"
8 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h" 9 #include "chrome/browser/spellchecker/spellcheck_custom_dictionary.h"
9 #include "chrome/browser/spellchecker/spellcheck_factory.h" 10 #include "chrome/browser/spellchecker/spellcheck_factory.h"
10 #include "chrome/browser/spellchecker/spellcheck_service.h" 11 #include "chrome/browser/spellchecker/spellcheck_service.h"
11 #include "chrome/common/chrome_constants.h" 12 #include "chrome/common/chrome_constants.h"
12 #include "chrome/common/spellcheck_common.h" 13 #include "chrome/common/spellcheck_common.h"
13 #include "chrome/test/base/testing_profile.h" 14 #include "chrome/test/base/testing_profile.h"
14 #include "content/public/test/test_browser_thread.h" 15 #include "content/public/test/test_browser_thread.h"
16 #include "sync/api/sync_change.h"
17 #include "sync/api/sync_data.h"
18 #include "sync/api/sync_error_factory.h"
19 #include "sync/api/sync_error_factory_mock.h"
20 #include "sync/protocol/sync.pb.h"
15 #include "testing/gmock/include/gmock/gmock.h" 21 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
17 23
18 using content::BrowserThread; 24 using content::BrowserThread;
19 using chrome::spellcheck_common::WordList; 25 using chrome::spellcheck_common::WordList;
20 26
27 namespace {
28
29 // Get all sync data for the custom dictionary without limiting to maximum
30 // number of syncable words.
31 syncer::SyncDataList GetAllSyncDataNoLimit(
32 const SpellcheckCustomDictionary* dictionary) {
33 syncer::SyncDataList data;
34 std::string word;
35 for (WordList::const_iterator it = dictionary->GetWords().begin();
36 it != dictionary->GetWords().end();
37 ++it) {
38 word = *it;
39 sync_pb::EntitySpecifics specifics;
40 specifics.mutable_dictionary()->set_word(word);
41 data.push_back(syncer::SyncData::CreateLocalData(word, word, specifics));
42 }
43 return data;
44 }
45
46 } // namespace
47
21 static ProfileKeyedService* BuildSpellcheckService(Profile* profile) { 48 static ProfileKeyedService* BuildSpellcheckService(Profile* profile) {
22 return new SpellcheckService(profile); 49 return new SpellcheckService(profile);
23 } 50 }
24 51
25 class SpellcheckCustomDictionaryTest : public testing::Test { 52 class SpellcheckCustomDictionaryTest : public testing::Test {
26 protected: 53 protected:
27 SpellcheckCustomDictionaryTest() 54 SpellcheckCustomDictionaryTest()
28 : ui_thread_(BrowserThread::UI, &message_loop_), 55 : ui_thread_(BrowserThread::UI, &message_loop_),
29 file_thread_(BrowserThread::FILE, &message_loop_), 56 file_thread_(BrowserThread::FILE, &message_loop_),
30 profile_(new TestingProfile()) { 57 profile_(new TestingProfile) {
31 } 58 }
32 59
33 void SetUp() OVERRIDE { 60 void SetUp() OVERRIDE {
34 // Use SetTestingFactoryAndUse to force creation and initialization. 61 // Use SetTestingFactoryAndUse to force creation and initialization.
35 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( 62 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
36 profile_.get(), &BuildSpellcheckService); 63 profile_.get(), &BuildSpellcheckService);
37 } 64 }
38 65
39 void TearDown() OVERRIDE { 66 void TearDown() OVERRIDE {
40 MessageLoop::current()->RunUntilIdle(); 67 MessageLoop::current()->RunUntilIdle();
41 } 68 }
42 69
70 // A wrapper around SpellcheckCustomDictionary::LoadDictionaryFile private
71 // function to avoid a large number of FRIEND_TEST declarations in
72 // SpellcheckCustomDictionary.
73 chrome::spellcheck_common::WordList LoadDictionaryFile(const FilePath& path) {
74 return SpellcheckCustomDictionary::LoadDictionaryFile(path);
75 }
76
77 // A wrapper around SpellcheckCustomDictionary::UpdateDictionaryFile private
78 // function to avoid a large number of FRIEND_TEST declarations in
79 // SpellcheckCustomDictionary.
80 void UpdateDictionaryFile(
81 const SpellcheckCustomDictionary::Change& dictionary_change,
82 const FilePath& path) {
83 SpellcheckCustomDictionary::UpdateDictionaryFile(dictionary_change, path);
84 }
85
86 // A wrapper around SpellcheckCustomDictionary::OnLoaded private method to
87 // avoid a large number of FRIEND_TEST declarations in
88 // SpellcheckCustomDictionary.
89 void OnLoaded(
90 SpellcheckCustomDictionary& dictionary,
91 const chrome::spellcheck_common::WordList& custom_words) {
92 dictionary.OnLoaded(custom_words);
93 }
94
95 // A wrapper around SpellcheckCustomDictionary::Apply private method to avoid
96 // a large number of FRIEND_TEST declarations in SpellcheckCustomDictionary.
97 void Apply(
98 SpellcheckCustomDictionary& dictionary,
99 const SpellcheckCustomDictionary::Change& change) {
100 return dictionary.Apply(change);
101 }
102
43 MessageLoop message_loop_; 103 MessageLoop message_loop_;
44 content::TestBrowserThread ui_thread_; 104 content::TestBrowserThread ui_thread_;
45 content::TestBrowserThread file_thread_; 105 content::TestBrowserThread file_thread_;
46 106
47 scoped_ptr<TestingProfile> profile_; 107 scoped_ptr<TestingProfile> profile_;
48 }; 108 };
49 109
50 TEST_F(SpellcheckCustomDictionaryTest, SpellcheckSetCustomWordList) { 110 // A wrapper around SpellcheckCustomDictionary that does not own the wrapped
51 SpellcheckService* spellcheck_service = 111 // object. An instance of this class can be inside of a scoped pointer safely
52 SpellcheckServiceFactory::GetForProfile(profile_.get()); 112 // while the dictionary is managed by another scoped pointer.
113 class SyncChangeProcessorDelegate : public syncer::SyncChangeProcessor {
114 public:
115 explicit SyncChangeProcessorDelegate(SpellcheckCustomDictionary* dictionary)
116 : dictionary_(dictionary) {}
117 virtual ~SyncChangeProcessorDelegate() {}
53 118
54 WordList loaded_custom_words; 119 // Overridden from syncer::SyncChangeProcessor:
55 loaded_custom_words.push_back("foo"); 120 virtual syncer::SyncError ProcessSyncChanges(
56 loaded_custom_words.push_back("bar"); 121 const tracked_objects::Location& from_here,
57 WordList expected(loaded_custom_words); 122 const syncer::SyncChangeList& change_list) OVERRIDE {
58 SpellcheckCustomDictionary* custom_dictionary = 123 return dictionary_->ProcessSyncChanges(from_here, change_list);
59 spellcheck_service->GetCustomDictionary(); 124 }
60 custom_dictionary->SetCustomWordList(&loaded_custom_words);
61 EXPECT_EQ(custom_dictionary->GetWords(), expected);
62 }
63 125
64 TEST_F(SpellcheckCustomDictionaryTest, CustomWordAddedAndRemovedLocally) { 126 private:
65 SpellcheckService* spellcheck_service = 127 SpellcheckCustomDictionary* dictionary_;
66 SpellcheckServiceFactory::GetForProfile(profile_.get()); 128 DISALLOW_COPY_AND_ASSIGN(SyncChangeProcessorDelegate);
129 };
67 130
68 WordList loaded_custom_words; 131 // An implementation of SyncErrorFactory that does not upload the error message
69 SpellcheckCustomDictionary* custom_dictionary = 132 // and updates an outside error counter. This lets us know the number of error
70 spellcheck_service->GetCustomDictionary(); 133 // messages in an instance of this class after that instance is deleted.
71 WordList expected; 134 class SyncErrorFactoryStub : public syncer::SyncErrorFactory {
72 EXPECT_EQ(custom_dictionary->GetWords(), expected); 135 public:
73 custom_dictionary->CustomWordAddedLocally("foo"); 136 explicit SyncErrorFactoryStub(int* error_counter)
74 expected.push_back("foo"); 137 : error_counter_(error_counter) {}
75 EXPECT_EQ(custom_dictionary->GetWords(), expected); 138 virtual ~SyncErrorFactoryStub() {}
76 custom_dictionary->CustomWordAddedLocally("bar");
77 expected.push_back("bar");
78 EXPECT_EQ(custom_dictionary->GetWords(), expected);
79 139
80 custom_dictionary->CustomWordRemovedLocally("foo"); 140 // Overridden from syncer::SyncErrorFactory:
81 custom_dictionary->CustomWordRemovedLocally("bar"); 141 virtual syncer::SyncError CreateAndUploadError(
82 expected.clear(); 142 const tracked_objects::Location& location,
83 EXPECT_EQ(custom_dictionary->GetWords(), expected); 143 const std::string& message) OVERRIDE {
84 } 144 (*error_counter_)++;
145 return syncer::SyncError(location, message, syncer::DICTIONARY);
146 }
147
148 private:
149 int* error_counter_;
150 DISALLOW_COPY_AND_ASSIGN(SyncErrorFactoryStub);
151 };
152
153 // Counts the number of notifications for dictionary load and change.
154 class DictionaryObserverCounter : public SpellcheckCustomDictionary::Observer {
155 public:
156 DictionaryObserverCounter() : loads_(0), changes_(0) {}
157 virtual ~DictionaryObserverCounter() {}
158
159 int loads() const { return loads_; }
160 int changes() const { return changes_; }
161
162 // Overridden from SpellcheckCustomDictionary::Observer:
163 virtual void OnCustomDictionaryLoaded() OVERRIDE { loads_++; }
164 virtual void OnCustomDictionaryChanged(
165 const SpellcheckCustomDictionary::Change& change) OVERRIDE { changes_++; }
166
167 private:
168 int loads_;
169 int changes_;
170 DISALLOW_COPY_AND_ASSIGN(DictionaryObserverCounter);
171 };
85 172
86 TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) { 173 TEST_F(SpellcheckCustomDictionaryTest, SaveAndLoad) {
87 SpellcheckService* spellcheck_service = 174 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
88 SpellcheckServiceFactory::GetForProfile(profile_.get()); 175 WordList loaded_custom_words = LoadDictionaryFile(path);
89 SpellcheckCustomDictionary* custom_dictionary =
90 spellcheck_service->GetCustomDictionary();
91
92 WordList loaded_custom_words;
93 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
94 176
95 // The custom word list should be empty now. 177 // The custom word list should be empty now.
96 WordList expected; 178 WordList expected;
97 EXPECT_EQ(loaded_custom_words, expected); 179 EXPECT_EQ(expected, loaded_custom_words);
98 180
99 custom_dictionary->WriteWordToCustomDictionary("foo"); 181 SpellcheckCustomDictionary::Change change;
182 change.AddWord("bar");
183 change.AddWord("foo");
184
185 UpdateDictionaryFile(change, path);
186 expected.push_back("bar");
100 expected.push_back("foo"); 187 expected.push_back("foo");
101 188
102 custom_dictionary->WriteWordToCustomDictionary("bar"); 189 // The custom word list should include written words.
103 expected.push_back("bar"); 190 loaded_custom_words = LoadDictionaryFile(path);
191 EXPECT_EQ(expected, loaded_custom_words);
104 192
105 // The custom word list should include written words. 193 change = SpellcheckCustomDictionary::Change();
106 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); 194 change.RemoveWord("bar");
107 std::sort(expected.begin(), expected.end()); 195 change.RemoveWord("foo");
108 EXPECT_EQ(loaded_custom_words, expected); 196 UpdateDictionaryFile(change, path);
109 197 loaded_custom_words = LoadDictionaryFile(path);
110 // Load in another instance of SpellCheckService.
111 // The result should be the same.
112 SpellcheckService spellcheck_service2(profile_.get());
113 WordList loaded_custom_words2;
114 spellcheck_service2.GetCustomDictionary()->
115 LoadDictionaryIntoCustomWordList(&loaded_custom_words2);
116 EXPECT_EQ(loaded_custom_words2, expected);
117
118 custom_dictionary->EraseWordFromCustomDictionary("foo");
119 custom_dictionary->EraseWordFromCustomDictionary("bar");
120 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
121 expected.clear(); 198 expected.clear();
122 EXPECT_EQ(loaded_custom_words, expected); 199 EXPECT_EQ(expected, loaded_custom_words);
123 200
124 // Flush the loop now to prevent service init tasks from being run during 201 // Flush the loop now to prevent service init tasks from being run during
125 // TearDown(); 202 // TearDown();
126 MessageLoop::current()->RunUntilIdle(); 203 MessageLoop::current()->RunUntilIdle();
127 } 204 }
128 205
129 TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) { 206 TEST_F(SpellcheckCustomDictionaryTest, MultiProfile) {
130 SpellcheckService* spellcheck_service = 207 SpellcheckService* spellcheck_service =
131 SpellcheckServiceFactory::GetForProfile(profile_.get()); 208 SpellcheckServiceFactory::GetForProfile(profile_.get());
132 SpellcheckCustomDictionary* custom_dictionary = 209 SpellcheckCustomDictionary* custom_dictionary =
133 spellcheck_service->GetCustomDictionary(); 210 spellcheck_service->GetCustomDictionary();
134 TestingProfile profile2; 211 TestingProfile profile2;
135 SpellcheckService* spellcheck_service2 = 212 SpellcheckService* spellcheck_service2 =
136 static_cast<SpellcheckService*>( 213 static_cast<SpellcheckService*>(
137 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse( 214 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
138 &profile2, &BuildSpellcheckService)); 215 &profile2, &BuildSpellcheckService));
139 SpellcheckCustomDictionary* custom_dictionary2 = 216 SpellcheckCustomDictionary* custom_dictionary2 =
140 spellcheck_service2->GetCustomDictionary(); 217 spellcheck_service2->GetCustomDictionary();
141 218
142 WordList expected1; 219 WordList expected1;
143 WordList expected2; 220 WordList expected2;
144 221
145 custom_dictionary->WriteWordToCustomDictionary("foo"); 222 custom_dictionary->AddWord("foo");
146 custom_dictionary->WriteWordToCustomDictionary("bar"); 223 custom_dictionary->AddWord("bar");
147 expected1.push_back("foo"); 224 expected1.push_back("foo");
148 expected1.push_back("bar"); 225 expected1.push_back("bar");
149 226
150 custom_dictionary2->WriteWordToCustomDictionary("hoge"); 227 custom_dictionary2->AddWord("hoge");
151 custom_dictionary2->WriteWordToCustomDictionary("fuga"); 228 custom_dictionary2->AddWord("fuga");
152 expected2.push_back("hoge"); 229 expected2.push_back("hoge");
153 expected2.push_back("fuga"); 230 expected2.push_back("fuga");
154 231
155 WordList actual1; 232 WordList actual1 = custom_dictionary->GetWords();
156 custom_dictionary->LoadDictionaryIntoCustomWordList(&actual1); 233 std::sort(actual1.begin(), actual1.end());
157 std::sort(expected1.begin(), expected1.end()); 234 std::sort(expected1.begin(), expected1.end());
158 EXPECT_EQ(actual1, expected1); 235 EXPECT_EQ(actual1, expected1);
159 236
160 WordList actual2; 237 WordList actual2 = custom_dictionary2->GetWords();
161 custom_dictionary2->LoadDictionaryIntoCustomWordList(&actual2); 238 std::sort(actual2.begin(), actual2.end());
162 std::sort(expected2.begin(), expected2.end()); 239 std::sort(expected2.begin(), expected2.end());
163 EXPECT_EQ(actual2, expected2); 240 EXPECT_EQ(actual2, expected2);
164 241
165 // Flush the loop now to prevent service init tasks from being run during 242 // Flush the loop now to prevent service init tasks from being run during
166 // TearDown(); 243 // TearDown();
167 MessageLoop::current()->RunUntilIdle(); 244 MessageLoop::current()->RunUntilIdle();
168 } 245 }
169 246
170 // Legacy empty dictionary should be converted to new format empty dicitonary. 247 // Legacy empty dictionary should be converted to new format empty dictionary.
171 TEST_F(SpellcheckCustomDictionaryTest, LegacyEmptyDictionaryShouldBeConverted) { 248 TEST_F(SpellcheckCustomDictionaryTest, LegacyEmptyDictionaryShouldBeConverted) {
172 FilePath dictionary_path( 249 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
173 profile_->GetPath().Append(chrome::kCustomDictionaryFileName));
174 SpellcheckService* spellcheck_service =
175 SpellcheckServiceFactory::GetForProfile(profile_.get());
176 SpellcheckCustomDictionary* custom_dictionary =
177 spellcheck_service->GetCustomDictionary();
178 WordList loaded_custom_words;
179 250
180 std::string content; 251 std::string content;
181 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); 252 file_util::WriteFile(path, content.c_str(), content.length());
182 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); 253 WordList loaded_custom_words = LoadDictionaryFile(path);
183 EXPECT_TRUE(loaded_custom_words.empty()); 254 EXPECT_TRUE(loaded_custom_words.empty());
184 255
185 // Flush the loop now to prevent service init tasks from being run during 256 // Flush the loop now to prevent service init tasks from being run during
186 // TearDown(); 257 // TearDown();
187 MessageLoop::current()->RunUntilIdle(); 258 MessageLoop::current()->RunUntilIdle();
188 } 259 }
189 260
190 // Legacy dictionary with two words should be converted to new format dictionary 261 // Legacy dictionary with two words should be converted to new format dictionary
191 // with two words. 262 // with two words.
192 TEST_F(SpellcheckCustomDictionaryTest, 263 TEST_F(SpellcheckCustomDictionaryTest,
193 LegacyDictionaryWithTwoWordsShouldBeConverted) { 264 LegacyDictionaryWithTwoWordsShouldBeConverted) {
194 FilePath dictionary_path( 265 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
195 profile_->GetPath().Append(chrome::kCustomDictionaryFileName)); 266
196 SpellcheckService* spellcheck_service = 267 std::string content = "foo\nbar\nfoo\n";
197 SpellcheckServiceFactory::GetForProfile(profile_.get()); 268 file_util::WriteFile(path, content.c_str(), content.length());
198 SpellcheckCustomDictionary* custom_dictionary = 269 WordList loaded_custom_words = LoadDictionaryFile(path);
199 spellcheck_service->GetCustomDictionary();
200 WordList loaded_custom_words;
201 WordList expected; 270 WordList expected;
202
203 std::string content = "foo\nbar";
204 file_util::WriteFile(dictionary_path, content.c_str(), content.length());
205 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
206 expected.push_back("bar"); 271 expected.push_back("bar");
207 expected.push_back("foo"); 272 expected.push_back("foo");
208 EXPECT_EQ(expected, loaded_custom_words); 273 EXPECT_EQ(expected, loaded_custom_words);
209 274
210 // Flush the loop now to prevent service init tasks from being run during 275 // Flush the loop now to prevent service init tasks from being run during
211 // TearDown(); 276 // TearDown();
212 MessageLoop::current()->RunUntilIdle(); 277 MessageLoop::current()->RunUntilIdle();
213 } 278 }
214 279
215 // Words with spaces are illegal and should be removed. 280 // Words with spaces are illegal and should be removed.
216 TEST_F(SpellcheckCustomDictionaryTest, 281 TEST_F(SpellcheckCustomDictionaryTest,
217 IllegalWordsShouldBeRemovedFromDictionary) { 282 IllegalWordsShouldBeRemovedFromDictionary) {
218 FilePath dictionary_path( 283 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
219 profile_->GetPath().Append(chrome::kCustomDictionaryFileName));
220 SpellcheckService* spellcheck_service =
221 SpellcheckServiceFactory::GetForProfile(profile_.get());
222 SpellcheckCustomDictionary* custom_dictionary =
223 spellcheck_service->GetCustomDictionary();
224 WordList loaded_custom_words;
225 WordList expected;
226 284
227 std::string content = "foo\nfoo bar\nbar\nfoo bar"; 285 std::string content = "foo\nfoo bar\nbar\nfoo bar";
228 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); 286 file_util::WriteFile(path, content.c_str(), content.length());
229 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); 287 WordList loaded_custom_words = LoadDictionaryFile(path);
288 WordList expected;
230 expected.push_back("bar"); 289 expected.push_back("bar");
231 expected.push_back("foo"); 290 expected.push_back("foo");
232 EXPECT_EQ(expected, loaded_custom_words); 291 EXPECT_EQ(expected, loaded_custom_words);
233 292
234 // Flush the loop now to prevent service init tasks from being run during 293 // Flush the loop now to prevent service init tasks from being run during
235 // TearDown(); 294 // TearDown();
236 MessageLoop::current()->RunUntilIdle(); 295 MessageLoop::current()->RunUntilIdle();
237 } 296 }
238 297
239 // Write to dicitonary should backup previous version and write the word to the 298 // Write to dictionary should backup previous version and write the word to the
240 // end of the dictionary. If the dictionary file is corrupted on disk, the 299 // end of the dictionary. If the dictionary file is corrupted on disk, the
241 // previous version should be reloaded. 300 // previous version should be reloaded.
242 TEST_F(SpellcheckCustomDictionaryTest, CorruptedWriteShouldBeRecovered) { 301 TEST_F(SpellcheckCustomDictionaryTest, CorruptedWriteShouldBeRecovered) {
243 FilePath dictionary_path( 302 FilePath path = profile_->GetPath().Append(chrome::kCustomDictionaryFileName);
244 profile_->GetPath().Append(chrome::kCustomDictionaryFileName)); 303
245 SpellcheckService* spellcheck_service = 304 std::string content = "foo\nbar";
246 SpellcheckServiceFactory::GetForProfile(profile_.get()); 305 file_util::WriteFile(path, content.c_str(), content.length());
247 SpellcheckCustomDictionary* custom_dictionary = 306 WordList loaded_custom_words = LoadDictionaryFile(path);
248 spellcheck_service->GetCustomDictionary();
249 WordList loaded_custom_words;
250 WordList expected; 307 WordList expected;
251
252 std::string content = "foo\nbar";
253 file_util::WriteFile(dictionary_path, content.c_str(), content.length());
254 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words);
255 expected.push_back("bar"); 308 expected.push_back("bar");
256 expected.push_back("foo"); 309 expected.push_back("foo");
257 EXPECT_EQ(expected, loaded_custom_words); 310 EXPECT_EQ(expected, loaded_custom_words);
258 311
259 custom_dictionary->WriteWordToCustomDictionary("baz"); 312 SpellcheckCustomDictionary::Change change;
313 change.AddWord("baz");
314 UpdateDictionaryFile(change, path);
260 content.clear(); 315 content.clear();
261 file_util::ReadFileToString(dictionary_path, &content); 316 file_util::ReadFileToString(path, &content);
262 content.append("corruption"); 317 content.append("corruption");
263 file_util::WriteFile(dictionary_path, content.c_str(), content.length()); 318 file_util::WriteFile(path, content.c_str(), content.length());
264 custom_dictionary->LoadDictionaryIntoCustomWordList(&loaded_custom_words); 319 loaded_custom_words = LoadDictionaryFile(path);
265 EXPECT_EQ(expected, loaded_custom_words); 320 EXPECT_EQ(expected, loaded_custom_words);
266 321
267 // Flush the loop now to prevent service init tasks from being run during 322 // Flush the loop now to prevent service init tasks from being run during
268 // TearDown(); 323 // TearDown();
269 MessageLoop::current()->RunUntilIdle(); 324 MessageLoop::current()->RunUntilIdle();
270 } 325 }
326
327 TEST_F(SpellcheckCustomDictionaryTest,
328 GetAllSyncDataAccuratelyReflectsDictionaryState) {
329 SpellcheckCustomDictionary* dictionary =
330 SpellcheckServiceFactory::GetForProfile(
331 profile_.get())->GetCustomDictionary();
332
333 syncer::SyncDataList data = dictionary->GetAllSyncData(syncer::DICTIONARY);
334 EXPECT_TRUE(data.empty());
335
336 EXPECT_TRUE(dictionary->AddWord("foo"));
337 EXPECT_TRUE(dictionary->AddWord("bar"));
338
339 data = dictionary->GetAllSyncData(syncer::DICTIONARY);
340 EXPECT_EQ(2UL, data.size());
341 std::vector<std::string> words;
342 words.push_back("foo");
343 words.push_back("bar");
344 for (size_t i = 0; i < data.size(); i++) {
345 EXPECT_TRUE(data[i].GetSpecifics().has_dictionary());
346 EXPECT_EQ(syncer::DICTIONARY, data[i].GetDataType());
347 EXPECT_EQ(words[i], data[i].GetTag());
348 EXPECT_EQ(words[i], data[i].GetSpecifics().dictionary().word());
349 }
350
351 EXPECT_TRUE(dictionary->RemoveWord("foo"));
352 EXPECT_TRUE(dictionary->RemoveWord("bar"));
353
354 data = dictionary->GetAllSyncData(syncer::DICTIONARY);
355 EXPECT_TRUE(data.empty());
356
357 // Flush the loop now to prevent service init tasks from being run during
358 // TearDown();
359 MessageLoop::current()->RunUntilIdle();
360 }
361
362 TEST_F(SpellcheckCustomDictionaryTest, GetAllSyncDataHasLimit) {
363 SpellcheckCustomDictionary* dictionary =
364 SpellcheckServiceFactory::GetForProfile(
365 profile_.get())->GetCustomDictionary();
366
367 SpellcheckCustomDictionary::Change change;
368 for (size_t i = 0;
369 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
370 i++) {
371 change.AddWord("foo" + base::Uint64ToString(i));
372 }
373 Apply(*dictionary, change);
374 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1,
375 dictionary->GetWords().size());
376 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1,
377 dictionary->GetAllSyncData(syncer::DICTIONARY).size());
378
379 dictionary->AddWord("baz");
380 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
381 dictionary->GetWords().size());
382 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
383 dictionary->GetAllSyncData(syncer::DICTIONARY).size());
384
385 dictionary->AddWord("bar");
386 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
387 dictionary->GetWords().size());
388 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
389 dictionary->GetAllSyncData(syncer::DICTIONARY).size());
390
391 dictionary->AddWord("snafoo");
392 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 2,
393 dictionary->GetWords().size());
394 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
395 dictionary->GetAllSyncData(syncer::DICTIONARY).size());
396
397 // Flush the loop now to prevent service init tasks from being run during
398 // TearDown();
399 MessageLoop::current()->RunUntilIdle();
400 }
401
402 TEST_F(SpellcheckCustomDictionaryTest, ProcessSyncChanges) {
403 SpellcheckService* spellcheck_service =
404 SpellcheckServiceFactory::GetForProfile(profile_.get());
405 SpellcheckCustomDictionary* dictionary =
406 spellcheck_service->GetCustomDictionary();
407
408 dictionary->AddWord("foo");
409 dictionary->AddWord("bar");
410
411 syncer::SyncChangeList changes;
412 {
413 // Add existing word.
414 std::string word = "foo";
415 sync_pb::EntitySpecifics specifics;
416 specifics.mutable_dictionary()->set_word(word);
417 changes.push_back(syncer::SyncChange(
418 FROM_HERE,
419 syncer::SyncChange::ACTION_ADD,
420 syncer::SyncData::CreateLocalData(word, word, specifics)));
421 }
422 {
423 // Add invalid word.
424 std::string word = "foo bar";
425 sync_pb::EntitySpecifics specifics;
426 specifics.mutable_dictionary()->set_word(word);
427 changes.push_back(syncer::SyncChange(
428 FROM_HERE,
429 syncer::SyncChange::ACTION_ADD,
430 syncer::SyncData::CreateLocalData(word, word, specifics)));
431 }
432 {
433 // Add valid word.
434 std::string word = "baz";
435 sync_pb::EntitySpecifics specifics;
436 specifics.mutable_dictionary()->set_word(word);
437 changes.push_back(syncer::SyncChange(
438 FROM_HERE,
439 syncer::SyncChange::ACTION_ADD,
440 syncer::SyncData::CreateLocalData(word, word, specifics)));
441 }
442 {
443 // Remove missing word.
444 std::string word = "snafoo";
445 sync_pb::EntitySpecifics specifics;
446 specifics.mutable_dictionary()->set_word(word);
447 changes.push_back(syncer::SyncChange(
448 FROM_HERE,
449 syncer::SyncChange::ACTION_DELETE,
450 syncer::SyncData::CreateLocalData(word, word, specifics)));
451 }
452 {
453 // Remove existing word.
454 std::string word = "bar";
455 sync_pb::EntitySpecifics specifics;
456 specifics.mutable_dictionary()->set_word(word);
457 changes.push_back(syncer::SyncChange(
458 FROM_HERE,
459 syncer::SyncChange::ACTION_DELETE,
460 syncer::SyncData::CreateLocalData(word, word, specifics)));
461 }
462
463 EXPECT_FALSE(dictionary->ProcessSyncChanges(FROM_HERE, changes).IsSet());
464
465 const chrome::spellcheck_common::WordList& words = dictionary->GetWords();
466 EXPECT_EQ(2UL, words.size());
467 EXPECT_EQ(words.end(), std::find(words.begin(), words.end(), "bar"));
468 EXPECT_NE(words.end(), std::find(words.begin(), words.end(), "foo"));
469 EXPECT_NE(words.end(), std::find(words.begin(), words.end(), "baz"));
470
471 // Flush the loop now to prevent service init tasks from being run during
472 // TearDown();
473 MessageLoop::current()->RunUntilIdle();
474 }
475
476 TEST_F(SpellcheckCustomDictionaryTest, MergeDataAndStartSyncing) {
477 SpellcheckService* spellcheck_service =
478 SpellcheckServiceFactory::GetForProfile(profile_.get());
479 SpellcheckCustomDictionary* custom_dictionary =
480 spellcheck_service->GetCustomDictionary();
481 TestingProfile profile2;
482 SpellcheckService* spellcheck_service2 =
483 static_cast<SpellcheckService*>(
484 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
485 &profile2, &BuildSpellcheckService));
486 SpellcheckCustomDictionary* custom_dictionary2 =
487 spellcheck_service2->GetCustomDictionary();
488
489 SpellcheckCustomDictionary::Change change;
490 for (size_t i = 0;
491 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
492 ++i) {
493 change.AddWord("foo" + base::Uint64ToString(i));
494 }
495 Apply(*custom_dictionary, change);
496
497 SpellcheckCustomDictionary::Change change2;
498 for (size_t i = 0;
499 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
500 ++i) {
501 change2.AddWord("bar" + base::Uint64ToString(i));
502 }
503 Apply(*custom_dictionary2, change2);
504
505 int error_counter = 0;
506 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
507 syncer::DICTIONARY,
508 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
509 scoped_ptr<syncer::SyncChangeProcessor>(
510 new SyncChangeProcessorDelegate(custom_dictionary2)),
511 scoped_ptr<syncer::SyncErrorFactory>(
512 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
513 EXPECT_EQ(0, error_counter);
514 EXPECT_TRUE(custom_dictionary->IsSyncing());
515
516 WordList words = custom_dictionary->GetWords();
517 WordList words2 = custom_dictionary2->GetWords();
518 EXPECT_EQ(words.size(), words2.size());
519
520 std::sort(words.begin(), words.end());
521 std::sort(words2.begin(), words2.end());
522 EXPECT_EQ(words, words2);
523
524 // Flush the loop now to prevent service init tasks from being run during
525 // TearDown();
526 MessageLoop::current()->RunUntilIdle();
527 }
528
529 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigBeforeSyncing) {
530 SpellcheckService* spellcheck_service =
531 SpellcheckServiceFactory::GetForProfile(profile_.get());
532 SpellcheckCustomDictionary* custom_dictionary =
533 spellcheck_service->GetCustomDictionary();
534 TestingProfile profile2;
535 SpellcheckService* spellcheck_service2 =
536 static_cast<SpellcheckService*>(
537 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
538 &profile2, &BuildSpellcheckService));
539 SpellcheckCustomDictionary* custom_dictionary2 =
540 spellcheck_service2->GetCustomDictionary();
541
542 SpellcheckCustomDictionary::Change change;
543 for (size_t i = 0;
544 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1;
545 ++i) {
546 change.AddWord("foo" + base::Uint64ToString(i));
547 }
548 Apply(*custom_dictionary, change);
549
550 int error_counter = 0;
551 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
552 syncer::DICTIONARY,
553 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
554 scoped_ptr<syncer::SyncChangeProcessor>(
555 new SyncChangeProcessorDelegate(custom_dictionary2)),
556 scoped_ptr<syncer::SyncErrorFactory>(
557 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
558 EXPECT_EQ(0, error_counter);
559 EXPECT_FALSE(custom_dictionary->IsSyncing());
560
561 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
562 custom_dictionary->GetWords().size());
563 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
564 custom_dictionary2->GetWords().size());
565
566 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
567 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
568 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
569 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
570
571 // Flush the loop now to prevent service init tasks from being run during
572 // TearDown();
573 MessageLoop::current()->RunUntilIdle();
574 }
575
576 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigAndServerFull) {
577 SpellcheckService* spellcheck_service =
578 SpellcheckServiceFactory::GetForProfile(profile_.get());
579 SpellcheckCustomDictionary* custom_dictionary =
580 spellcheck_service->GetCustomDictionary();
581 TestingProfile profile2;
582 SpellcheckService* spellcheck_service2 =
583 static_cast<SpellcheckService*>(
584 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
585 &profile2, &BuildSpellcheckService));
586 SpellcheckCustomDictionary* custom_dictionary2 =
587 spellcheck_service2->GetCustomDictionary();
588
589 SpellcheckCustomDictionary::Change change;
590 SpellcheckCustomDictionary::Change change2;
591 for (size_t i = 0;
592 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
593 ++i) {
594 change.AddWord("foo" + base::Uint64ToString(i));
595 change2.AddWord("bar" + base::Uint64ToString(i));
596 }
597 change.AddWord("foo");
598 Apply(*custom_dictionary, change);
599 Apply(*custom_dictionary2, change2);
600
601 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
602 custom_dictionary->GetWords().size());
603 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
604 custom_dictionary2->GetWords().size());
605
606 int error_counter = 0;
607 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
608 syncer::DICTIONARY,
609 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
610 scoped_ptr<syncer::SyncChangeProcessor>(
611 new SyncChangeProcessorDelegate(custom_dictionary2)),
612 scoped_ptr<syncer::SyncErrorFactory>(
613 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
614 EXPECT_EQ(0, error_counter);
615 EXPECT_FALSE(custom_dictionary->IsSyncing());
616
617 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS * 2 + 1,
618 custom_dictionary->GetWords().size());
619 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
620 custom_dictionary2->GetWords().size());
621
622 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
623 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
624 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
625 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
626
627 // Flush the loop now to prevent service init tasks from being run during
628 // TearDown();
629 MessageLoop::current()->RunUntilIdle();
630 }
631
632 TEST_F(SpellcheckCustomDictionaryTest, ServerTooBig) {
633 SpellcheckService* spellcheck_service =
634 SpellcheckServiceFactory::GetForProfile(profile_.get());
635 SpellcheckCustomDictionary* custom_dictionary =
636 spellcheck_service->GetCustomDictionary();
637 TestingProfile profile2;
638 SpellcheckService* spellcheck_service2 =
639 static_cast<SpellcheckService*>(
640 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
641 &profile2, &BuildSpellcheckService));
642 SpellcheckCustomDictionary* custom_dictionary2 =
643 spellcheck_service2->GetCustomDictionary();
644
645 SpellcheckCustomDictionary::Change change;
646 SpellcheckCustomDictionary::Change change2;
647 for (size_t i = 0;
648 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1;
649 ++i) {
650 change.AddWord("foo" + base::Uint64ToString(i));
651 change2.AddWord("bar" + base::Uint64ToString(i));
652 }
653 Apply(*custom_dictionary, change);
654 Apply(*custom_dictionary2, change2);
655
656 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
657 custom_dictionary->GetWords().size());
658 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
659 custom_dictionary2->GetWords().size());
660
661 int error_counter = 0;
662 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
663 syncer::DICTIONARY,
664 GetAllSyncDataNoLimit(custom_dictionary2),
665 scoped_ptr<syncer::SyncChangeProcessor>(
666 new SyncChangeProcessorDelegate(custom_dictionary2)),
667 scoped_ptr<syncer::SyncErrorFactory>(
668 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
669 EXPECT_EQ(0, error_counter);
670 EXPECT_FALSE(custom_dictionary->IsSyncing());
671
672 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS * 2 + 2,
673 custom_dictionary->GetWords().size());
674 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
675 custom_dictionary2->GetWords().size());
676
677 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
678 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
679 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
680 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
681
682 // Flush the loop now to prevent service init tasks from being run during
683 // TearDown();
684 MessageLoop::current()->RunUntilIdle();
685 }
686
687 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigToStartSyncing) {
688 SpellcheckService* spellcheck_service =
689 SpellcheckServiceFactory::GetForProfile(profile_.get());
690 SpellcheckCustomDictionary* custom_dictionary =
691 spellcheck_service->GetCustomDictionary();
692 TestingProfile profile2;
693 SpellcheckService* spellcheck_service2 =
694 static_cast<SpellcheckService*>(
695 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
696 &profile2, &BuildSpellcheckService));
697 SpellcheckCustomDictionary* custom_dictionary2 =
698 spellcheck_service2->GetCustomDictionary();
699
700 SpellcheckCustomDictionary::Change change;
701 for (size_t i = 0;
702 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
703 ++i) {
704 change.AddWord("foo" + base::Uint64ToString(i));
705 }
706 Apply(*custom_dictionary, change);
707
708 custom_dictionary2->AddWord("bar");
709 custom_dictionary2->AddWord("baz");
710
711 int error_counter = 0;
712 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
713 syncer::DICTIONARY,
714 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
715 scoped_ptr<syncer::SyncChangeProcessor>(
716 new SyncChangeProcessorDelegate(custom_dictionary2)),
717 scoped_ptr<syncer::SyncErrorFactory>(
718 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
719 EXPECT_EQ(0, error_counter);
720 EXPECT_FALSE(custom_dictionary->IsSyncing());
721
722 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
723 custom_dictionary->GetWords().size());
724 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
725 custom_dictionary2->GetWords().size());
726
727 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
728 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
729 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
730 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
731
732 // Flush the loop now to prevent service init tasks from being run during
733 // TearDown();
734 MessageLoop::current()->RunUntilIdle();
735 }
736
737 TEST_F(SpellcheckCustomDictionaryTest, DictionaryTooBigToContiueSyncing) {
738 SpellcheckService* spellcheck_service =
739 SpellcheckServiceFactory::GetForProfile(profile_.get());
740 SpellcheckCustomDictionary* custom_dictionary =
741 spellcheck_service->GetCustomDictionary();
742 TestingProfile profile2;
743 SpellcheckService* spellcheck_service2 =
744 static_cast<SpellcheckService*>(
745 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
746 &profile2, &BuildSpellcheckService));
747 SpellcheckCustomDictionary* custom_dictionary2 =
748 spellcheck_service2->GetCustomDictionary();
749
750 SpellcheckCustomDictionary::Change change;
751 for (size_t i = 0;
752 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS - 1;
753 ++i) {
754 change.AddWord("foo" + base::Uint64ToString(i));
755 }
756 Apply(*custom_dictionary, change);
757
758 int error_counter = 0;
759 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
760 syncer::DICTIONARY,
761 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
762 scoped_ptr<syncer::SyncChangeProcessor>(
763 new SyncChangeProcessorDelegate(custom_dictionary2)),
764 scoped_ptr<syncer::SyncErrorFactory>(
765 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
766 EXPECT_EQ(0, error_counter);
767 EXPECT_TRUE(custom_dictionary->IsSyncing());
768
769 custom_dictionary->AddWord("bar");
770 EXPECT_EQ(0, error_counter);
771 EXPECT_TRUE(custom_dictionary->IsSyncing());
772
773 custom_dictionary->AddWord("baz");
774 EXPECT_EQ(0, error_counter);
775 EXPECT_FALSE(custom_dictionary->IsSyncing());
776
777 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
778 custom_dictionary->GetWords().size());
779 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
780 custom_dictionary2->GetWords().size());
781
782 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
783 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
784 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
785 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
786
787 // Flush the loop now to prevent service init tasks from being run during
788 // TearDown();
789 MessageLoop::current()->RunUntilIdle();
790 }
791
792 TEST_F(SpellcheckCustomDictionaryTest, LoadAfterSyncStart) {
793 SpellcheckService* spellcheck_service =
794 SpellcheckServiceFactory::GetForProfile(profile_.get());
795 SpellcheckCustomDictionary* custom_dictionary =
796 spellcheck_service->GetCustomDictionary();
797 TestingProfile profile2;
798 SpellcheckService* spellcheck_service2 =
799 static_cast<SpellcheckService*>(
800 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
801 &profile2, &BuildSpellcheckService));
802 SpellcheckCustomDictionary* custom_dictionary2 =
803 spellcheck_service2->GetCustomDictionary();
804
805 custom_dictionary->AddWord("foo");
806
807 int error_counter = 0;
808 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
809 syncer::DICTIONARY,
810 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
811 scoped_ptr<syncer::SyncChangeProcessor>(
812 new SyncChangeProcessorDelegate(custom_dictionary2)),
813 scoped_ptr<syncer::SyncErrorFactory>(
814 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
815 EXPECT_EQ(0, error_counter);
816 EXPECT_TRUE(custom_dictionary->IsSyncing());
817
818 WordList custom_words;
819 custom_words.push_back("bar");
820 OnLoaded(*custom_dictionary, custom_words);
821 EXPECT_TRUE(custom_dictionary->IsSyncing());
822
823 EXPECT_EQ(2UL, custom_dictionary->GetWords().size());
824 EXPECT_EQ(2UL, custom_dictionary2->GetWords().size());
825
826 EXPECT_EQ(2UL, custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
827 EXPECT_EQ(2UL, custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
828
829 // Flush the loop now to prevent service init tasks from being run during
830 // TearDown();
831 MessageLoop::current()->RunUntilIdle();
832 }
833
834 TEST_F(SpellcheckCustomDictionaryTest, LoadAfterSyncStartTooBigToSync) {
835 SpellcheckService* spellcheck_service =
836 SpellcheckServiceFactory::GetForProfile(profile_.get());
837 SpellcheckCustomDictionary* custom_dictionary =
838 spellcheck_service->GetCustomDictionary();
839 TestingProfile profile2;
840 SpellcheckService* spellcheck_service2 =
841 static_cast<SpellcheckService*>(
842 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
843 &profile2, &BuildSpellcheckService));
844 SpellcheckCustomDictionary* custom_dictionary2 =
845 spellcheck_service2->GetCustomDictionary();
846
847 custom_dictionary->AddWord("foo");
848
849 int error_counter = 0;
850 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
851 syncer::DICTIONARY,
852 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
853 scoped_ptr<syncer::SyncChangeProcessor>(
854 new SyncChangeProcessorDelegate(custom_dictionary2)),
855 scoped_ptr<syncer::SyncErrorFactory>(
856 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
857 EXPECT_EQ(0, error_counter);
858 EXPECT_TRUE(custom_dictionary->IsSyncing());
859
860 WordList custom_words;
861 for (size_t i = 0;
862 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
863 ++i) {
864 custom_words.push_back("foo" + base::Uint64ToString(i));
865 }
866 OnLoaded(*custom_dictionary, custom_words);
867 EXPECT_EQ(0, error_counter);
868 EXPECT_FALSE(custom_dictionary->IsSyncing());
869
870 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS + 1,
871 custom_dictionary->GetWords().size());
872 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
873 custom_dictionary2->GetWords().size());
874
875 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
876 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
877 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
878 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
879
880 // Flush the loop now to prevent service init tasks from being run during
881 // TearDown();
882 MessageLoop::current()->RunUntilIdle();
883 }
884
885 TEST_F(SpellcheckCustomDictionaryTest, LoadDuplicatesAfterSync) {
886 SpellcheckService* spellcheck_service =
887 SpellcheckServiceFactory::GetForProfile(profile_.get());
888 SpellcheckCustomDictionary* custom_dictionary =
889 spellcheck_service->GetCustomDictionary();
890 TestingProfile profile2;
891 SpellcheckService* spellcheck_service2 =
892 static_cast<SpellcheckService*>(
893 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
894 &profile2, &BuildSpellcheckService));
895 SpellcheckCustomDictionary* custom_dictionary2 =
896 spellcheck_service2->GetCustomDictionary();
897
898 WordList to_add;
899 for (size_t i = 0;
900 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2;
901 ++i) {
902 to_add.push_back("foo" + base::Uint64ToString(i));
903 }
904 Apply(*custom_dictionary, SpellcheckCustomDictionary::Change(to_add));
905
906 int error_counter = 0;
907 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
908 syncer::DICTIONARY,
909 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
910 scoped_ptr<syncer::SyncChangeProcessor>(
911 new SyncChangeProcessorDelegate(custom_dictionary2)),
912 scoped_ptr<syncer::SyncErrorFactory>(
913 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
914 EXPECT_EQ(0, error_counter);
915 EXPECT_TRUE(custom_dictionary->IsSyncing());
916
917 OnLoaded(*custom_dictionary, to_add);
918 EXPECT_EQ(0, error_counter);
919 EXPECT_TRUE(custom_dictionary->IsSyncing());
920
921 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
922 custom_dictionary->GetWords().size());
923 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
924 custom_dictionary2->GetWords().size());
925
926 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
927 custom_dictionary->GetAllSyncData(syncer::DICTIONARY).size());
928 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS / 2,
929 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY).size());
930
931 // Flush the loop now to prevent service init tasks from being run during
932 // TearDown();
933 MessageLoop::current()->RunUntilIdle();
934 }
935
936 TEST_F(SpellcheckCustomDictionaryTest, DictionaryLoadNotification) {
937 SpellcheckService* spellcheck_service =
938 SpellcheckServiceFactory::GetForProfile(profile_.get());
939 SpellcheckCustomDictionary* custom_dictionary =
940 spellcheck_service->GetCustomDictionary();
941
942 DictionaryObserverCounter observer;
943 custom_dictionary->AddObserver(&observer);
944
945 WordList custom_words;
946 custom_words.push_back("foo");
947 custom_words.push_back("bar");
948 OnLoaded(*custom_dictionary, custom_words);
949
950 EXPECT_GE(observer.loads(), 1);
951 EXPECT_LE(observer.loads(), 2);
952 EXPECT_EQ(0, observer.changes());
953
954 custom_dictionary->RemoveObserver(&observer);
955
956 // Flush the loop now to prevent service init tasks from being run during
957 // TearDown();
958 MessageLoop::current()->RunUntilIdle();
959 }
960
961 TEST_F(SpellcheckCustomDictionaryTest, DictionaryAddWordNotification) {
962 SpellcheckService* spellcheck_service =
963 SpellcheckServiceFactory::GetForProfile(profile_.get());
964 SpellcheckCustomDictionary* custom_dictionary =
965 spellcheck_service->GetCustomDictionary();
966
967 OnLoaded(*custom_dictionary, WordList());
968
969 DictionaryObserverCounter observer;
970 custom_dictionary->AddObserver(&observer);
971
972 EXPECT_TRUE(custom_dictionary->AddWord("foo"));
973 EXPECT_TRUE(custom_dictionary->AddWord("bar"));
974 EXPECT_FALSE(custom_dictionary->AddWord("bar"));
975
976 EXPECT_EQ(2, observer.changes());
977
978 custom_dictionary->RemoveObserver(&observer);
979
980 // Flush the loop now to prevent service init tasks from being run during
981 // TearDown();
982 MessageLoop::current()->RunUntilIdle();
983 }
984
985 TEST_F(SpellcheckCustomDictionaryTest, DictionaryRemoveWordNotification) {
986 SpellcheckService* spellcheck_service =
987 SpellcheckServiceFactory::GetForProfile(profile_.get());
988 SpellcheckCustomDictionary* custom_dictionary =
989 spellcheck_service->GetCustomDictionary();
990
991 OnLoaded(*custom_dictionary, WordList());
992
993 EXPECT_TRUE(custom_dictionary->AddWord("foo"));
994 EXPECT_TRUE(custom_dictionary->AddWord("bar"));
995
996 DictionaryObserverCounter observer;
997 custom_dictionary->AddObserver(&observer);
998
999 EXPECT_TRUE(custom_dictionary->RemoveWord("foo"));
1000 EXPECT_TRUE(custom_dictionary->RemoveWord("bar"));
1001 EXPECT_FALSE(custom_dictionary->RemoveWord("baz"));
1002
1003 EXPECT_EQ(2, observer.changes());
1004
1005 custom_dictionary->RemoveObserver(&observer);
1006
1007 // Flush the loop now to prevent service init tasks from being run during
1008 // TearDown();
1009 MessageLoop::current()->RunUntilIdle();
1010 }
1011
1012 TEST_F(SpellcheckCustomDictionaryTest, DictionarySyncNotification) {
1013 SpellcheckService* spellcheck_service =
1014 SpellcheckServiceFactory::GetForProfile(profile_.get());
1015 SpellcheckCustomDictionary* custom_dictionary =
1016 spellcheck_service->GetCustomDictionary();
1017 TestingProfile profile2;
1018 SpellcheckService* spellcheck_service2 =
1019 static_cast<SpellcheckService*>(
1020 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1021 &profile2, &BuildSpellcheckService));
1022 SpellcheckCustomDictionary* custom_dictionary2 =
1023 spellcheck_service2->GetCustomDictionary();
1024
1025 OnLoaded(*custom_dictionary, WordList());
1026 OnLoaded(*custom_dictionary2, WordList());
1027
1028 custom_dictionary->AddWord("foo");
1029 custom_dictionary->AddWord("bar");
1030 custom_dictionary2->AddWord("foo");
1031 custom_dictionary2->AddWord("baz");
1032
1033 DictionaryObserverCounter observer;
1034 custom_dictionary->AddObserver(&observer);
1035
1036 DictionaryObserverCounter observer2;
1037 custom_dictionary2->AddObserver(&observer2);
1038
1039 int error_counter = 0;
1040 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
1041 syncer::DICTIONARY,
1042 custom_dictionary2->GetAllSyncData(syncer::DICTIONARY),
1043 scoped_ptr<syncer::SyncChangeProcessor>(
1044 new SyncChangeProcessorDelegate(custom_dictionary2)),
1045 scoped_ptr<syncer::SyncErrorFactory>(
1046 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
1047 EXPECT_EQ(0, error_counter);
1048 EXPECT_TRUE(custom_dictionary->IsSyncing());
1049
1050 EXPECT_EQ(1, observer.changes());
1051 EXPECT_EQ(1, observer2.changes());
1052
1053 custom_dictionary->RemoveObserver(&observer);
1054 custom_dictionary2->RemoveObserver(&observer2);
1055
1056 // Flush the loop now to prevent service init tasks from being run during
1057 // TearDown();
1058 MessageLoop::current()->RunUntilIdle();
1059 }
1060
1061 // The server has maximum number of words and the client has maximum number of
1062 // different words before association time. No new words should be pushed to the
1063 // sync server upon association. The client should accept words from the sync
1064 // server, however.
1065 TEST_F(SpellcheckCustomDictionaryTest, DictionarySyncLimit) {
1066 TestingProfile server_profile;
1067 SpellcheckService* server_spellcheck_service =
1068 static_cast<SpellcheckService*>(
1069 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1070 &server_profile, &BuildSpellcheckService));
1071
1072 // Here, |server_custom_dictionary| plays the role of the sync server.
1073 SpellcheckCustomDictionary* server_custom_dictionary =
1074 server_spellcheck_service->GetCustomDictionary();
1075
1076 // Upload the maximum number of words to the sync server.
1077 {
1078 SpellcheckService* spellcheck_service =
1079 SpellcheckServiceFactory::GetForProfile(profile_.get());
1080 SpellcheckCustomDictionary* custom_dictionary =
1081 spellcheck_service->GetCustomDictionary();
1082
1083 SpellcheckCustomDictionary::Change change;
1084 for (size_t i = 0;
1085 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
1086 ++i) {
1087 change.AddWord("foo" + base::Uint64ToString(i));
1088 }
1089 Apply(*custom_dictionary, change);
1090
1091 int error_counter = 0;
1092 EXPECT_FALSE(custom_dictionary->MergeDataAndStartSyncing(
1093 syncer::DICTIONARY,
1094 server_custom_dictionary->GetAllSyncData(syncer::DICTIONARY),
1095 scoped_ptr<syncer::SyncChangeProcessor>(
1096 new SyncChangeProcessorDelegate(server_custom_dictionary)),
1097 scoped_ptr<syncer::SyncErrorFactory>(
1098 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
1099 EXPECT_EQ(0, error_counter);
1100 EXPECT_TRUE(custom_dictionary->IsSyncing());
1101 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
1102 custom_dictionary->GetWords().size());
1103 }
1104
1105 // The sync server now has the maximum number of words.
1106 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
1107 server_custom_dictionary->GetWords().size());
1108
1109 // Associate the sync server with a client that also has the maximum number of
1110 // words, but all of these words are different from the ones on the sync
1111 // server.
1112 {
1113 TestingProfile client_profile;
1114 SpellcheckService* client_spellcheck_service =
1115 static_cast<SpellcheckService*>(
1116 SpellcheckServiceFactory::GetInstance()->SetTestingFactoryAndUse(
1117 &client_profile, &BuildSpellcheckService));
1118
1119 // Here, |client_custom_dictionary| plays the role of the client.
1120 SpellcheckCustomDictionary* client_custom_dictionary =
1121 client_spellcheck_service->GetCustomDictionary();
1122
1123 // Add the maximum number of words to the client. These words are all
1124 // different from those on the server.
1125 SpellcheckCustomDictionary::Change change;
1126 for (size_t i = 0;
1127 i < chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS;
1128 ++i) {
1129 change.AddWord("bar" + base::Uint64ToString(i));
1130 }
1131 Apply(*client_custom_dictionary, change);
1132
1133 // Associate the server and the client.
1134 int error_counter = 0;
1135 EXPECT_FALSE(client_custom_dictionary->MergeDataAndStartSyncing(
1136 syncer::DICTIONARY,
1137 server_custom_dictionary->GetAllSyncData(syncer::DICTIONARY),
1138 scoped_ptr<syncer::SyncChangeProcessor>(
1139 new SyncChangeProcessorDelegate(server_custom_dictionary)),
1140 scoped_ptr<syncer::SyncErrorFactory>(
1141 new SyncErrorFactoryStub(&error_counter))).error().IsSet());
1142 EXPECT_EQ(0, error_counter);
1143 EXPECT_FALSE(client_custom_dictionary->IsSyncing());
1144 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS * 2,
1145 client_custom_dictionary->GetWords().size());
1146
1147 // Flush the loop now to prevent service init tasks from being run during
1148 // TearDown();
1149 MessageLoop::current()->RunUntilIdle();
1150 }
1151
1152 // The sync server should not receive more words, because it has the maximum
1153 // number of words already.
1154 EXPECT_EQ(chrome::spellcheck_common::MAX_SYNCABLE_DICTIONARY_WORDS,
1155 server_custom_dictionary->GetWords().size());
1156
1157 // Flush the loop now to prevent service init tasks from being run during
1158 // TearDown();
1159 MessageLoop::current()->RunUntilIdle();
1160 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698