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