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

Side by Side Diff: chrome/browser/chromeos/contacts/contact_database_unittest.cc

Issue 190063004: chromeos: Delete old, unused contacts code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge again Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/chromeos/contacts/contact_database.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/file_util.h"
11 #include "base/files/file_enumerator.h"
12 #include "base/files/file_path.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/message_loop/message_loop.h"
17 #include "chrome/browser/chromeos/contacts/contact.pb.h"
18 #include "chrome/browser/chromeos/contacts/contact_test_util.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/test/test_browser_thread.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "ui/gfx/size.h"
23
24 using content::BrowserThread;
25
26 namespace contacts {
27 namespace test {
28
29 // Name of the directory created within a temporary directory to store the
30 // contacts database.
31 const base::FilePath::CharType kDatabaseDirectoryName[] =
32 FILE_PATH_LITERAL("contacts");
33
34 class ContactDatabaseTest : public testing::Test {
35 public:
36 ContactDatabaseTest()
37 : ui_thread_(BrowserThread::UI, &message_loop_),
38 db_(NULL) {
39 }
40
41 virtual ~ContactDatabaseTest() {
42 }
43
44 protected:
45 // testing::Test implementation.
46 virtual void SetUp() OVERRIDE {
47 CHECK(temp_dir_.CreateUniqueTempDir());
48 CreateDatabase();
49 }
50
51 virtual void TearDown() OVERRIDE {
52 DestroyDatabase();
53 }
54
55 protected:
56 base::FilePath database_path() const {
57 return temp_dir_.path().Append(kDatabaseDirectoryName);
58 }
59
60 void CreateDatabase() {
61 DestroyDatabase();
62 db_ = new ContactDatabase;
63 db_->Init(database_path(),
64 base::Bind(&ContactDatabaseTest::OnDatabaseInitialized,
65 base::Unretained(this)));
66
67 // The database will be initialized on the file thread; run the message loop
68 // until that happens.
69 message_loop_.Run();
70 }
71
72 void DestroyDatabase() {
73 if (db_) {
74 db_->DestroyOnUIThread();
75 db_ = NULL;
76 }
77 }
78
79 // Calls ContactDatabase::SaveContacts() and blocks until the operation is
80 // complete.
81 void SaveContacts(scoped_ptr<ContactPointers> contacts_to_save,
82 scoped_ptr<ContactDatabaseInterface::ContactIds>
83 contact_ids_to_delete,
84 scoped_ptr<UpdateMetadata> metadata,
85 bool is_full_update) {
86 CHECK(db_);
87 db_->SaveContacts(contacts_to_save.Pass(),
88 contact_ids_to_delete.Pass(),
89 metadata.Pass(),
90 is_full_update,
91 base::Bind(&ContactDatabaseTest::OnContactsSaved,
92 base::Unretained(this)));
93 message_loop_.Run();
94 }
95
96 // Calls ContactDatabase::LoadContacts() and blocks until the operation is
97 // complete.
98 void LoadContacts(scoped_ptr<ScopedVector<Contact> >* contacts_out,
99 scoped_ptr<UpdateMetadata>* metadata_out) {
100 CHECK(db_);
101 db_->LoadContacts(base::Bind(&ContactDatabaseTest::OnContactsLoaded,
102 base::Unretained(this)));
103 message_loop_.Run();
104 contacts_out->swap(loaded_contacts_);
105 metadata_out->swap(loaded_metadata_);
106 }
107
108 private:
109 void OnDatabaseInitialized(bool success) {
110 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111 CHECK(success);
112 // TODO(derat): Move google_apis::test::RunBlockingPoolTask() to a shared
113 // location and use it for these tests.
114 message_loop_.Quit();
115 }
116
117 void OnContactsSaved(bool success) {
118 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
119 CHECK(success);
120 message_loop_.Quit();
121 }
122
123 void OnContactsLoaded(bool success,
124 scoped_ptr<ScopedVector<Contact> > contacts,
125 scoped_ptr<UpdateMetadata> metadata) {
126 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
127 CHECK(success);
128 loaded_contacts_.swap(contacts);
129 loaded_metadata_.swap(metadata);
130 message_loop_.Quit();
131 }
132
133 base::MessageLoopForUI message_loop_;
134 content::TestBrowserThread ui_thread_;
135
136 // Temporary directory where the database is saved.
137 base::ScopedTempDir temp_dir_;
138
139 // This class retains ownership of this object.
140 ContactDatabase* db_;
141
142 // Contacts and metadata returned by the most-recent
143 // ContactDatabase::LoadContacts() call. Used to pass returned values from
144 // OnContactsLoaded() to LoadContacts().
145 scoped_ptr<ScopedVector<Contact> > loaded_contacts_;
146 scoped_ptr<UpdateMetadata> loaded_metadata_;
147
148 DISALLOW_COPY_AND_ASSIGN(ContactDatabaseTest);
149 };
150
151 TEST_F(ContactDatabaseTest, SaveAndReload) {
152 // Save a contact to the database and check that we get the same data back
153 // when loading it.
154 const std::string kContactId = "contact_id_1";
155 scoped_ptr<Contact> contact(new Contact);
156 InitContact(kContactId, "1", false, contact.get());
157 AddEmailAddress("email_1", Contact_AddressType_Relation_HOME,
158 "email_label_1", true, contact.get());
159 AddEmailAddress("email_2", Contact_AddressType_Relation_WORK,
160 "", false, contact.get());
161 AddPhoneNumber("123-456-7890", Contact_AddressType_Relation_HOME,
162 "phone_label", true, contact.get());
163 AddPostalAddress("postal_1", Contact_AddressType_Relation_HOME,
164 "postal_label_1", true, contact.get());
165 AddPostalAddress("postal_2", Contact_AddressType_Relation_OTHER,
166 "postal_label_2", false, contact.get());
167 AddInstantMessagingAddress("im_1",
168 Contact_InstantMessagingAddress_Protocol_AIM,
169 Contact_AddressType_Relation_HOME,
170 "im_label_1", true, contact.get());
171 SetPhoto(gfx::Size(20, 20), contact.get());
172 scoped_ptr<ContactPointers> contacts_to_save(new ContactPointers);
173 contacts_to_save->push_back(contact.get());
174 scoped_ptr<ContactDatabaseInterface::ContactIds> contact_ids_to_delete(
175 new ContactDatabaseInterface::ContactIds);
176
177 const int64 kLastUpdateTime = 1234;
178 scoped_ptr<UpdateMetadata> metadata_to_save(new UpdateMetadata);
179 metadata_to_save->set_last_update_start_time(kLastUpdateTime);
180
181 SaveContacts(contacts_to_save.Pass(),
182 contact_ids_to_delete.Pass(),
183 metadata_to_save.Pass(),
184 true);
185 scoped_ptr<ScopedVector<Contact> > loaded_contacts;
186 scoped_ptr<UpdateMetadata> loaded_metadata;
187 LoadContacts(&loaded_contacts, &loaded_metadata);
188 EXPECT_EQ(VarContactsToString(1, contact.get()),
189 ContactsToString(*loaded_contacts));
190 EXPECT_EQ(kLastUpdateTime, loaded_metadata->last_update_start_time());
191
192 // Modify the contact, save it, and check that the loaded contact is also
193 // updated.
194 InitContact(kContactId, "2", false, contact.get());
195 AddEmailAddress("email_3", Contact_AddressType_Relation_OTHER,
196 "email_label_2", true, contact.get());
197 AddPhoneNumber("phone_2", Contact_AddressType_Relation_OTHER,
198 "phone_label_2", false, contact.get());
199 AddPostalAddress("postal_3", Contact_AddressType_Relation_HOME,
200 "postal_label_3", true, contact.get());
201 SetPhoto(gfx::Size(64, 64), contact.get());
202 contacts_to_save.reset(new ContactPointers);
203 contacts_to_save->push_back(contact.get());
204 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
205 metadata_to_save.reset(new UpdateMetadata);
206 const int64 kNewLastUpdateTime = 5678;
207 metadata_to_save->set_last_update_start_time(kNewLastUpdateTime);
208 SaveContacts(contacts_to_save.Pass(),
209 contact_ids_to_delete.Pass(),
210 metadata_to_save.Pass(),
211 true);
212
213 LoadContacts(&loaded_contacts, &loaded_metadata);
214 EXPECT_EQ(VarContactsToString(1, contact.get()),
215 ContactsToString(*loaded_contacts));
216 EXPECT_EQ(kNewLastUpdateTime, loaded_metadata->last_update_start_time());
217 }
218
219 TEST_F(ContactDatabaseTest, FullAndIncrementalUpdates) {
220 // Do a full update that inserts two contacts into the database.
221 const std::string kContactId1 = "contact_id_1";
222 const std::string kSharedEmail = "foo@example.org";
223 scoped_ptr<Contact> contact1(new Contact);
224 InitContact(kContactId1, "1", false, contact1.get());
225 AddEmailAddress(kSharedEmail, Contact_AddressType_Relation_HOME,
226 "", true, contact1.get());
227
228 const std::string kContactId2 = "contact_id_2";
229 scoped_ptr<Contact> contact2(new Contact);
230 InitContact(kContactId2, "2", false, contact2.get());
231 AddEmailAddress(kSharedEmail, Contact_AddressType_Relation_WORK,
232 "", true, contact2.get());
233
234 scoped_ptr<ContactPointers> contacts_to_save(new ContactPointers);
235 contacts_to_save->push_back(contact1.get());
236 contacts_to_save->push_back(contact2.get());
237 scoped_ptr<ContactDatabaseInterface::ContactIds> contact_ids_to_delete(
238 new ContactDatabaseInterface::ContactIds);
239 scoped_ptr<UpdateMetadata> metadata_to_save(new UpdateMetadata);
240 SaveContacts(contacts_to_save.Pass(),
241 contact_ids_to_delete.Pass(),
242 metadata_to_save.Pass(),
243 true);
244
245 scoped_ptr<ScopedVector<Contact> > loaded_contacts;
246 scoped_ptr<UpdateMetadata> loaded_metadata;
247 LoadContacts(&loaded_contacts, &loaded_metadata);
248 EXPECT_EQ(VarContactsToString(2, contact1.get(), contact2.get()),
249 ContactsToString(*loaded_contacts));
250
251 // Do an incremental update including just the second contact.
252 InitContact(kContactId2, "2b", false, contact2.get());
253 AddPostalAddress("postal_1", Contact_AddressType_Relation_HOME,
254 "", true, contact2.get());
255 contacts_to_save.reset(new ContactPointers);
256 contacts_to_save->push_back(contact2.get());
257 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
258 metadata_to_save.reset(new UpdateMetadata);
259 SaveContacts(contacts_to_save.Pass(),
260 contact_ids_to_delete.Pass(),
261 metadata_to_save.Pass(),
262 false);
263 LoadContacts(&loaded_contacts, &loaded_metadata);
264 EXPECT_EQ(VarContactsToString(2, contact1.get(), contact2.get()),
265 ContactsToString(*loaded_contacts));
266
267 // Do an empty incremental update and check that the metadata is still
268 // updated.
269 contacts_to_save.reset(new ContactPointers);
270 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
271 metadata_to_save.reset(new UpdateMetadata);
272 const int64 kLastUpdateTime = 1234;
273 metadata_to_save->set_last_update_start_time(kLastUpdateTime);
274 SaveContacts(contacts_to_save.Pass(),
275 contact_ids_to_delete.Pass(),
276 metadata_to_save.Pass(),
277 false);
278 LoadContacts(&loaded_contacts, &loaded_metadata);
279 EXPECT_EQ(VarContactsToString(2, contact1.get(), contact2.get()),
280 ContactsToString(*loaded_contacts));
281 EXPECT_EQ(kLastUpdateTime, loaded_metadata->last_update_start_time());
282
283 // Do a full update including just the first contact. The second contact
284 // should be removed from the database.
285 InitContact(kContactId1, "1b", false, contact1.get());
286 AddPostalAddress("postal_2", Contact_AddressType_Relation_WORK,
287 "", true, contact1.get());
288 AddPhoneNumber("phone", Contact_AddressType_Relation_HOME,
289 "", true, contact1.get());
290 contacts_to_save.reset(new ContactPointers);
291 contacts_to_save->push_back(contact1.get());
292 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
293 metadata_to_save.reset(new UpdateMetadata);
294 SaveContacts(contacts_to_save.Pass(),
295 contact_ids_to_delete.Pass(),
296 metadata_to_save.Pass(),
297 true);
298 LoadContacts(&loaded_contacts, &loaded_metadata);
299 EXPECT_EQ(VarContactsToString(1, contact1.get()),
300 ContactsToString(*loaded_contacts));
301
302 // Do a full update including no contacts. The database should be cleared.
303 contacts_to_save.reset(new ContactPointers);
304 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
305 metadata_to_save.reset(new UpdateMetadata);
306 SaveContacts(contacts_to_save.Pass(),
307 contact_ids_to_delete.Pass(),
308 metadata_to_save.Pass(),
309 true);
310 LoadContacts(&loaded_contacts, &loaded_metadata);
311 EXPECT_TRUE(loaded_contacts->empty());
312 }
313
314 // Test that we create a new database when we encounter a corrupted one.
315 TEST_F(ContactDatabaseTest, DeleteWhenCorrupt) {
316 DestroyDatabase();
317 // Overwrite all of the files in the database with a space character.
318 base::FileEnumerator enumerator(
319 database_path(), false, base::FileEnumerator::FILES);
320 for (base::FilePath path = enumerator.Next(); !path.empty();
321 path = enumerator.Next()) {
322 base::WriteFile(path, " ", 1);
323 }
324 CreateDatabase();
325
326 // Make sure that the resulting database is usable.
327 scoped_ptr<Contact> contact(new Contact);
328 InitContact("1", "1", false, contact.get());
329 scoped_ptr<ContactPointers> contacts_to_save(new ContactPointers);
330 contacts_to_save->push_back(contact.get());
331 scoped_ptr<ContactDatabaseInterface::ContactIds> contact_ids_to_delete(
332 new ContactDatabaseInterface::ContactIds);
333 scoped_ptr<UpdateMetadata> metadata_to_save(new UpdateMetadata);
334 SaveContacts(contacts_to_save.Pass(),
335 contact_ids_to_delete.Pass(),
336 metadata_to_save.Pass(),
337 true);
338
339 scoped_ptr<ScopedVector<Contact> > loaded_contacts;
340 scoped_ptr<UpdateMetadata> loaded_metadata;
341 LoadContacts(&loaded_contacts, &loaded_metadata);
342 EXPECT_EQ(VarContactsToString(1, contact.get()),
343 ContactsToString(*loaded_contacts));
344 }
345
346 TEST_F(ContactDatabaseTest, DeleteRequestedContacts) {
347 // Insert two contacts into the database with a full update.
348 const std::string kContactId1 = "contact_id_1";
349 scoped_ptr<Contact> contact1(new Contact);
350 InitContact(kContactId1, "1", false, contact1.get());
351 const std::string kContactId2 = "contact_id_2";
352 scoped_ptr<Contact> contact2(new Contact);
353 InitContact(kContactId2, "2", false, contact2.get());
354
355 scoped_ptr<ContactPointers> contacts_to_save(new ContactPointers);
356 contacts_to_save->push_back(contact1.get());
357 contacts_to_save->push_back(contact2.get());
358 scoped_ptr<ContactDatabaseInterface::ContactIds> contact_ids_to_delete(
359 new ContactDatabaseInterface::ContactIds);
360 scoped_ptr<UpdateMetadata> metadata_to_save(new UpdateMetadata);
361 SaveContacts(contacts_to_save.Pass(),
362 contact_ids_to_delete.Pass(),
363 metadata_to_save.Pass(),
364 true);
365
366 // Do an incremental update that inserts a third contact and deletes the first
367 // contact.
368 const std::string kContactId3 = "contact_id_3";
369 scoped_ptr<Contact> contact3(new Contact);
370 InitContact(kContactId3, "3", false, contact3.get());
371
372 contacts_to_save.reset(new ContactPointers);
373 contacts_to_save->push_back(contact3.get());
374 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
375 contact_ids_to_delete->push_back(kContactId1);
376 metadata_to_save.reset(new UpdateMetadata);
377 SaveContacts(contacts_to_save.Pass(),
378 contact_ids_to_delete.Pass(),
379 metadata_to_save.Pass(),
380 false);
381
382 // LoadContacts() should return only the second and third contacts.
383 scoped_ptr<ScopedVector<Contact> > loaded_contacts;
384 scoped_ptr<UpdateMetadata> loaded_metadata;
385 LoadContacts(&loaded_contacts, &loaded_metadata);
386 EXPECT_EQ(VarContactsToString(2, contact2.get(), contact3.get()),
387 ContactsToString(*loaded_contacts));
388
389 // Do another incremental update that deletes the second contact.
390 contacts_to_save.reset(new ContactPointers);
391 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
392 contact_ids_to_delete->push_back(kContactId2);
393 metadata_to_save.reset(new UpdateMetadata);
394 SaveContacts(contacts_to_save.Pass(),
395 contact_ids_to_delete.Pass(),
396 metadata_to_save.Pass(),
397 false);
398 LoadContacts(&loaded_contacts, &loaded_metadata);
399 EXPECT_EQ(VarContactsToString(1, contact3.get()),
400 ContactsToString(*loaded_contacts));
401
402 // Deleting a contact that isn't present should be a no-op.
403 contacts_to_save.reset(new ContactPointers);
404 contact_ids_to_delete.reset(new ContactDatabaseInterface::ContactIds);
405 contact_ids_to_delete->push_back("bogus_id");
406 metadata_to_save.reset(new UpdateMetadata);
407 SaveContacts(contacts_to_save.Pass(),
408 contact_ids_to_delete.Pass(),
409 metadata_to_save.Pass(),
410 false);
411 LoadContacts(&loaded_contacts, &loaded_metadata);
412 EXPECT_EQ(VarContactsToString(1, contact3.get()),
413 ContactsToString(*loaded_contacts));
414 }
415
416 } // namespace test
417 } // namespace contacts
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/contacts/contact_database.cc ('k') | chrome/browser/chromeos/contacts/contact_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698