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

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

Powered by Google App Engine
This is Rietveld 408576698