| 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 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 } |
| OLD | NEW |