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