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

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

Powered by Google App Engine
This is Rietveld 408576698