summaryrefslogtreecommitdiffstats
path: root/tests/assets
diff options
context:
space:
mode:
authorDaniel Lehmann <lehmannd@google.com>2010-03-17 11:48:58 -0700
committerDaniel Lehmann <lehmannd@google.com>2010-03-17 11:48:58 -0700
commit18cba80a41494e82464aaf8c6ab1ac3f608492bc (patch)
tree691d4c69c2b775419d465ae244498f1a81c28e7f /tests/assets
parenteb8d2387e312748e4f1d92e00b4dcc7eb8085e15 (diff)
downloadpackages_providers_ContactsProvider-18cba80a41494e82464aaf8c6ab1ac3f608492bc.zip
packages_providers_ContactsProvider-18cba80a41494e82464aaf8c6ab1ac3f608492bc.tar.gz
packages_providers_ContactsProvider-18cba80a41494e82464aaf8c6ab1ac3f608492bc.tar.bz2
Fixed visibility of contacts, display-names and lookup-keys after Donut->Froyo update. Reworked Tests.
Bug:2517163 Bug:2521116 Change-Id: I8e33650acf9a59b52719289e37257c1b3c55a7a9
Diffstat (limited to 'tests/assets')
-rw-r--r--tests/assets/legacy_contacts.dbbin70656 -> 0 bytes
-rw-r--r--tests/assets/test1/expected_calls.txt (renamed from tests/assets/expected_calls.txt)0
-rw-r--r--tests/assets/test1/expected_contacts.txt (renamed from tests/assets/expected_contacts.txt)0
-rw-r--r--tests/assets/test1/expected_data.txt (renamed from tests/assets/expected_data.txt)0
-rw-r--r--tests/assets/test1/expected_groups.txt (renamed from tests/assets/expected_groups.txt)0
-rw-r--r--tests/assets/test1/expected_raw_contacts.txt (renamed from tests/assets/expected_raw_contacts.txt)0
-rw-r--r--tests/assets/test1/legacy_contacts.sql154
-rw-r--r--tests/assets/test1/readme.txt1
-rw-r--r--tests/assets/testSynced/expected_calls.txt11
-rw-r--r--tests/assets/testSynced/expected_contacts.txt168
-rw-r--r--tests/assets/testSynced/expected_data.txt810
-rw-r--r--tests/assets/testSynced/expected_groups.txt17
-rw-r--r--tests/assets/testSynced/expected_raw_contacts.txt216
-rw-r--r--tests/assets/testSynced/legacy_contacts.sql178
-rw-r--r--tests/assets/testSynced/readme.txt3
-rw-r--r--tests/assets/testUnsynced/expected_calls.txt11
-rw-r--r--tests/assets/testUnsynced/expected_contacts.txt70
-rw-r--r--tests/assets/testUnsynced/expected_data.txt378
-rw-r--r--tests/assets/testUnsynced/expected_groups.txt17
-rw-r--r--tests/assets/testUnsynced/expected_raw_contacts.txt90
-rw-r--r--tests/assets/testUnsynced/legacy_contacts.sql122
-rw-r--r--tests/assets/testUnsynced/readme.txt3
22 files changed, 2249 insertions, 0 deletions
diff --git a/tests/assets/legacy_contacts.db b/tests/assets/legacy_contacts.db
deleted file mode 100644
index bdef5cf..0000000
--- a/tests/assets/legacy_contacts.db
+++ /dev/null
Binary files differ
diff --git a/tests/assets/expected_calls.txt b/tests/assets/test1/expected_calls.txt
index 5bac955..5bac955 100644
--- a/tests/assets/expected_calls.txt
+++ b/tests/assets/test1/expected_calls.txt
diff --git a/tests/assets/expected_contacts.txt b/tests/assets/test1/expected_contacts.txt
index ebe4dad..ebe4dad 100644
--- a/tests/assets/expected_contacts.txt
+++ b/tests/assets/test1/expected_contacts.txt
diff --git a/tests/assets/expected_data.txt b/tests/assets/test1/expected_data.txt
index 5a3447c..5a3447c 100644
--- a/tests/assets/expected_data.txt
+++ b/tests/assets/test1/expected_data.txt
diff --git a/tests/assets/expected_groups.txt b/tests/assets/test1/expected_groups.txt
index 90fa2bc..90fa2bc 100644
--- a/tests/assets/expected_groups.txt
+++ b/tests/assets/test1/expected_groups.txt
diff --git a/tests/assets/expected_raw_contacts.txt b/tests/assets/test1/expected_raw_contacts.txt
index 355258b..355258b 100644
--- a/tests/assets/expected_raw_contacts.txt
+++ b/tests/assets/test1/expected_raw_contacts.txt
diff --git a/tests/assets/test1/legacy_contacts.sql b/tests/assets/test1/legacy_contacts.sql
new file mode 100644
index 0000000..1f7d0e5
--- /dev/null
+++ b/tests/assets/test1/legacy_contacts.sql
@@ -0,0 +1,154 @@
+BEGIN TRANSACTION;
+PRAGMA user_version = 82;
+CREATE TABLE _deleted_groups (_sync_version TEXT,_sync_id TEXT,_sync_account TEXT,_sync_mark INTEGER);
+CREATE TABLE _deleted_people (_sync_version TEXT,_sync_id TEXT,_sync_account TEXT,_sync_mark INTEGER);
+INSERT INTO _deleted_people VALUES(1249441421793000,'20d08a710c3df43d','android.contacts.test.eclair@gmail.com',NULL);
+CREATE TABLE _sync_state (_id INTEGER PRIMARY KEY,_sync_account TEXT,data TEXT,UNIQUE(_sync_account));
+INSERT INTO _sync_state VALUES(1,'android.contacts.test.eclair@gmail.com','');
+CREATE TABLE _sync_state_metadata (version INTEGER);
+INSERT INTO _sync_state_metadata VALUES(2);
+CREATE TABLE android_metadata (locale TEXT);
+INSERT INTO android_metadata VALUES('en_US');
+CREATE TABLE calls (_id INTEGER PRIMARY KEY AUTOINCREMENT,number TEXT,date INTEGER,duration INTEGER,type INTEGER,new INTEGER,name TEXT,numbertype INTEGER,numberlabel TEXT);
+INSERT INTO calls VALUES(1,18004664411,1249177360040,10,2,1,'Jane Doe',1,NULL);
+CREATE TABLE contact_methods (_id INTEGER PRIMARY KEY AUTOINCREMENT,person INTEGER REFERENCES people(_id),kind INTEGER NOT NULL,data TEXT,aux_data TEXT,type INTEGER NOT NULL,label TEXT,isprimary INTEGER NOT NULL DEFAULT 0);
+INSERT INTO contact_methods VALUES(1,2,1,'a@acme.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(2,2,1,'b@acme.com',NULL,2,NULL,0);
+INSERT INTO contact_methods VALUES(3,2,1,'c@acme.com',NULL,3,NULL,0);
+INSERT INTO contact_methods VALUES(4,2,1,'d@acme.com',NULL,3,NULL,0);
+INSERT INTO contact_methods VALUES(5,2,3,'a','pre:5',3,NULL,0);
+INSERT INTO contact_methods VALUES(6,2,3,'b','pre:0',3,NULL,0);
+INSERT INTO contact_methods VALUES(7,2,3,'c','pre:2',3,NULL,0);
+INSERT INTO contact_methods VALUES(8,2,3,'d','pre:3',3,NULL,0);
+INSERT INTO contact_methods VALUES(9,2,3,'e','pre:4',3,NULL,0);
+INSERT INTO contact_methods VALUES(10,2,3,'f','pre:1',3,NULL,0);
+INSERT INTO contact_methods VALUES(11,2,3,'g','pre:6',3,NULL,0);
+INSERT INTO contact_methods VALUES(12,2,3,'h','pre:7',3,NULL,0);
+INSERT INTO contact_methods VALUES(13,3,1,'deer@acme.com',NULL,2,NULL,1);
+INSERT INTO contact_methods VALUES(14,3,2,'12345 Main Street
+Main Town, CA 95000',NULL,2,NULL,0);
+INSERT INTO contact_methods VALUES(15,3,3,'deerdough','pre:5',3,NULL,0);
+CREATE TABLE extensions (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,value TEXT NOT NULL,person INTEGER REFERENCES people(_id),UNIQUE(person, name));
+CREATE TABLE fave_msg_status (_id INTEGER PRIMARY KEY, msg TEXT, next_retry INTEGER, num_retries INTEGER);
+CREATE TABLE fave_phone_changes (_id INTEGER PRIMARY KEY, old_phone TEXT, new_phone TEXT, change_timestamp TEXT);
+CREATE TABLE faves (_id INTEGER PRIMARY KEY, ui_pos INTEGER, phone TEXT NOT NULL, nickname TEXT NOT NULL, photo TEXT NOT NULL, timestamp TEXT NOT NULL, pending_phone TEXT, pending_nickname TEXT, pending_photo TEXT);
+INSERT INTO faves VALUES(1,1,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(2,2,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(3,3,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(4,4,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(5,5,0,'','',000000000000,NULL,NULL,NULL);
+CREATE TABLE groupmembership (_id INTEGER PRIMARY KEY,person INTEGER REFERENCES people(_id),group_id INTEGER REFERENCES groups(_id),group_sync_account STRING,group_sync_id STRING);
+INSERT INTO groupmembership VALUES(1,2,NULL,'android.contacts.test.eclair@gmail.com',6);
+INSERT INTO groupmembership VALUES(2,3,NULL,'android.contacts.test.eclair@gmail.com',6);
+INSERT INTO groupmembership VALUES(3,3,NULL,'android.contacts.test.eclair@gmail.com','20a186238cf27aaa');
+INSERT INTO groupmembership VALUES(9,3,NULL,'android.contacts.test.eclair@gmail.com',55555555555);
+INSERT INTO groupmembership VALUES(10,11,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(11,2,3,'android.contacts.test.eclair@gmail.com','2fcbf74c8be345dc');
+CREATE TABLE groups (_id INTEGER PRIMARY KEY AUTOINCREMENT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,name TEXT NOT NULL,notes TEXT,should_sync INTEGER NOT NULL DEFAULT 0,system_id TEXT,UNIQUE(name,system_id,_sync_account));
+INSERT INTO groups VALUES(1,'android.contacts.test.eclair@gmail.com',6,NULL,NULL,NULL,0,1,'System Group: My Contacts','System Group: My Contacts',0,'Contacts');
+INSERT INTO groups VALUES(2,'android.contacts.test.eclair@gmail.com','20a186238cf27aaa',1249172992736000,1249172992736000,NULL,0,1,'Eclair Contacts','Eclair Contacts',0,NULL);
+INSERT INTO groups VALUES(3,'android.contacts.test.eclair@gmail.com','2fcbf74c8be345dc',1249176693566000,1249176693566000,NULL,0,1,'Starred in Android','Starred in Android',0,NULL);
+CREATE TABLE organizations (_id INTEGER PRIMARY KEY AUTOINCREMENT,company TEXT,title TEXT,isprimary INTEGER NOT NULL DEFAULT 0,type INTEGER NOT NULL,label TEXT,person INTEGER REFERENCES people(_id));
+INSERT INTO organizations VALUES(1,'Acme Corp','President',0,1,NULL,3);
+CREATE TABLE people (_id INTEGER PRIMARY KEY AUTOINCREMENT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,name TEXT COLLATE LOCALIZED,notes TEXT COLLATE LOCALIZED,times_contacted INTEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred INTEGER NOT NULL DEFAULT 0,primary_phone INTEGER REFERENCES phones(_id),primary_organization INTEGER REFERENCES organizations(_id),primary_email INTEGER REFERENCES contact_methods(_id),photo_version TEXT,custom_ringtone TEXT,send_to_voicemail INTEGER,phonetic_name TEXT COLLATE LOCALIZED);
+INSERT INTO people VALUES(1,'non_syncable',NULL,NULL,NULL,NULL,1,1,'Test Android',NULL,0,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+INSERT INTO people VALUES(2,'android.contacts.test.eclair@gmail.com','3d09f37e0f0dbc6f',1249441106583000,1249441106583000,NULL,1,1,'Jane Doe',NULL,1,1249177384979,1,1,NULL,1,NULL,NULL,NULL,NULL);
+INSERT INTO people VALUES(3,'android.contacts.test.eclair@gmail.com','5c9ae978b346ac9',1249441067558000,1249441067558000,NULL,1,1,'John Doe','This is a test account for Eclair Android Contacts',0,NULL,1,8,1,13,NULL,'content://media/internal/audio/media/80',1,NULL);
+INSERT INTO people VALUES(11,'android.contacts.test.eclair@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'Added On Android',NULL,0,NULL,0,16,NULL,NULL,NULL,NULL,0,'');
+CREATE TABLE peopleLookup (token TEXT,source INTEGER REFERENCES people(_id),token_index INTEGER);
+INSERT INTO peopleLookup VALUES('4f314d4f0629432f4b45392f',1,0);
+INSERT INTO peopleLookup VALUES('29432f4b45392f',1,1);
+INSERT INTO peopleLookup VALUES('3b294331062f4531',2,0);
+INSERT INTO peopleLookup VALUES('2f4531',2,1);
+INSERT INTO peopleLookup VALUES('3b453743062f4531',3,0);
+INSERT INTO peopleLookup VALUES('2f4531',3,1);
+INSERT INTO peopleLookup VALUES('292f2f312f0645430629432f4b45392f',11,0);
+INSERT INTO peopleLookup VALUES(4543,11,1);
+INSERT INTO peopleLookup VALUES('29432f4b45392f',11,2);
+CREATE TABLE peopleLookupWithPhoneticName (token TEXT,source INTEGER REFERENCES people(_id),token_index INTEGER);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4f314d4f0629432f4b45392f',1,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('29432f4b45392f',1,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('3b294331062f4531',2,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('2f4531',2,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('3b453743062f4531',3,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('2f4531',3,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('292f2f312f0645430629432f4b45392f',11,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES(4543,11,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('29432f4b45392f',11,2);
+CREATE TABLE phones (_id INTEGER PRIMARY KEY AUTOINCREMENT,person INTEGER REFERENCES people(_id),type INTEGER NOT NULL,number TEXT,number_key TEXT,label TEXT,isprimary INTEGER NOT NULL DEFAULT 0);
+INSERT INTO phones VALUES(1,2,1,'1-800-466-4411',11446640081,NULL,1);
+INSERT INTO phones VALUES(2,2,3,2345678901,1098765432,NULL,0);
+INSERT INTO phones VALUES(3,2,2,3456789012,2109876543,NULL,0);
+INSERT INTO phones VALUES(4,2,5,4567890123,3210987654,NULL,0);
+INSERT INTO phones VALUES(5,2,4,5678901234,4321098765,NULL,0);
+INSERT INTO phones VALUES(6,2,6,6789012345,5432109876,NULL,0);
+INSERT INTO phones VALUES(7,2,7,7890123456,6543210987,NULL,0);
+INSERT INTO phones VALUES(8,3,2,'555-555-5555',5555555555,NULL,0);
+INSERT INTO phones VALUES(11,2,1,1234567890,0987654321,NULL,0);
+INSERT INTO phones VALUES(16,11,2,'1-987-4563',36547891,NULL,1);
+CREATE TABLE photos (_id INTEGER PRIMARY KEY AUTOINCREMENT,exists_on_server INTEGER NOT NULL DEFAULT 0,person INTEGER REFERENCES people(_id), local_version TEXT,data BLOB,sync_error TEXT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,UNIQUE(person) );
+INSERT INTO photos VALUES(1,0,1,NULL,NULL,NULL,'non_syncable',NULL,NULL,NULL,NULL,0,1);
+INSERT INTO photos VALUES(2,1,2,'4Yujp-X7nRp5v8zJca7cxg','����',NULL,'android.contacts.test.eclair@gmail.com','3d09f37e0f0dbc6f','4Yujp-X7nRp5v8zJca7cxg','4Yujp-X7nRp5v8zJca7cxg',NULL,0,1);
+INSERT INTO photos VALUES(3,1,3,'sQwgwiST8gBzusqDIFkOgg','����',NULL,'android.contacts.test.eclair@gmail.com','5c9ae978b346ac9','sQwgwiST8gBzusqDIFkOgg','sQwgwiST8gBzusqDIFkOgg',NULL,0,1);
+INSERT INTO photos VALUES(11,0,11,NULL,NULL,NULL,'android.contacts.test.eclair@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+CREATE TABLE settings (_id INTEGER PRIMARY KEY,_sync_account TEXT,key STRING NOT NULL,value STRING );
+INSERT INTO settings VALUES(1,NULL,'syncEverything',1);
+CREATE TABLE sqlite_sequence(name,seq);
+INSERT INTO sqlite_sequence VALUES('groups',3);
+INSERT INTO sqlite_sequence VALUES('people',11);
+INSERT INTO sqlite_sequence VALUES('photos',11);
+INSERT INTO sqlite_sequence VALUES('phones',16);
+INSERT INTO sqlite_sequence VALUES('contact_methods',24);
+INSERT INTO sqlite_sequence VALUES('organizations',2);
+INSERT INTO sqlite_sequence VALUES('calls',1);
+CREATE TABLE voice_dialer_timestamp (_id INTEGER PRIMARY KEY,timestamp INTEGER);
+INSERT INTO voice_dialer_timestamp VALUES(1,1249441215);
+CREATE INDEX contactMethodsPeopleIndex ON contact_methods (person);
+CREATE INDEX extensionsIndex1 ON extensions (person, name);
+CREATE INDEX groupmembershipIndex1 ON groupmembership (person, group_id);
+CREATE INDEX groupmembershipIndex2 ON groupmembership (group_id, person);
+CREATE INDEX groupmembershipIndex3 ON groupmembership (group_sync_account, group_sync_id);
+CREATE INDEX groupsSyncDirtyIndex ON groups (_sync_dirty);
+CREATE INDEX organizationsIndex1 ON organizations (person);
+CREATE INDEX peopleLookupIndex ON peopleLookup (token,source);
+CREATE INDEX peopleLookupWithPhoneticNameIndex ON peopleLookupWithPhoneticName (token,source);
+CREATE INDEX peopleNameIndex ON people (name);
+CREATE INDEX peopleSyncDirtyIndex ON people (_sync_dirty);
+CREATE INDEX peopleSyncIdIndex ON people (_sync_id);
+CREATE INDEX phonesIndex1 ON phones (person);
+CREATE INDEX phonesIndex2 ON phones (number_key);
+CREATE INDEX photoPersonIndex ON photos (person);
+CREATE INDEX photosSyncDirtyIndex ON photos (_sync_dirty);
+CREATE TRIGGER contact_cleanup DELETE ON people BEGIN DELETE FROM peopleLookup WHERE source = old._id;DELETE FROM peopleLookupWithPhoneticName WHERE source = old._id;DELETE FROM phones WHERE person = old._id;DELETE FROM contact_methods WHERE person = old._id;DELETE FROM organizations WHERE person = old._id;DELETE FROM groupmembership WHERE person = old._id;DELETE FROM extensions WHERE person = old._id;END;
+CREATE TRIGGER contact_methods_INSERT_typeAndLabel AFTER INSERT ON contact_methods WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER contact_methods_UPDATE_typeAndLabel AFTER UPDATE ON contact_methods WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER contact_methods_delete DELETE ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER contact_methods_insert INSERT ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;END;
+CREATE TRIGGER contact_methods_update UPDATE ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER extensions_delete DELETE ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER extensions_insert INSERT ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER extensions_update AFTER UPDATE ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER groupmembership_delete DELETE ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER groupmembership_insert INSERT ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER groupmembership_update AFTER UPDATE ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER groups_cleanup DELETE ON groups BEGIN UPDATE groupmembership SET group_id = null WHERE group_id = old._id;END;
+CREATE TRIGGER groups_to_deleted DELETE ON groups WHEN old._sync_id is not null BEGIN INSERT INTO _deleted_groups (_sync_id, _sync_account, _sync_version) VALUES (old._sync_id, old._sync_account, old._sync_version);END;
+CREATE TRIGGER organizations_INSERT_typeAndLabel AFTER INSERT ON organizations WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER organizations_UPDATE_typeAndLabel AFTER UPDATE ON organizations WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER organizations_delete DELETE ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER organizations_insert INSERT ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER organizations_update AFTER UPDATE ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER peopleDeleteAndPhotos DELETE ON people BEGIN DELETE FROM photos WHERE person=OLD._id; END;
+CREATE TRIGGER peopleLookupWithPhoneticName_insert AFTER INSERT ON people BEGIN SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, GET_NORMALIZED_STRING(CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') THEN new.phonetic_name ELSE (CASE WHEN (new.name is NOT NULL AND new.name != '') THEN new.name ELSE '' END) END), ' ', 1);END;
+CREATE TRIGGER peopleLookupWithPhoneticName_update UPDATE OF name, phonetic_name ON people BEGIN DELETE FROM peopleLookupWithPhoneticName WHERE source = new._id;SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, GET_NORMALIZED_STRING(CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') THEN new.phonetic_name ELSE (CASE WHEN (new.name is NOT NULL AND new.name != '') THEN new.name ELSE '' END) END), ' ', 1);END;
+CREATE TRIGGER peopleLookup_insert AFTER INSERT ON people BEGIN SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);END;
+CREATE TRIGGER peopleLookup_update UPDATE OF name ON people BEGIN DELETE FROM peopleLookup WHERE source = new._id;SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);END;
+CREATE TRIGGER people_timesContacted UPDATE OF last_time_contacted ON people BEGIN UPDATE people SET times_contacted = (new.times_contacted + 1) WHERE _id = new._id;END;
+CREATE TRIGGER phones_INSERT_typeAndLabel AFTER INSERT ON phones WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER phones_UPDATE_typeAndLabel AFTER UPDATE ON phones WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER phones_delete DELETE ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER phones_insert INSERT ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;END;
+CREATE TRIGGER phones_update UPDATE ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER timestamp_trigger1 AFTER UPDATE ON phones BEGIN UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') WHERE _id=1;END;
+CREATE TRIGGER timestamp_trigger2 AFTER UPDATE OF name ON people BEGIN UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') WHERE _id=1;END;
+COMMIT;
diff --git a/tests/assets/test1/readme.txt b/tests/assets/test1/readme.txt
new file mode 100644
index 0000000..4b80668
--- /dev/null
+++ b/tests/assets/test1/readme.txt
@@ -0,0 +1 @@
+What's tested here: \ No newline at end of file
diff --git a/tests/assets/testSynced/expected_calls.txt b/tests/assets/testSynced/expected_calls.txt
new file mode 100644
index 0000000..3d566ec
--- /dev/null
+++ b/tests/assets/testSynced/expected_calls.txt
@@ -0,0 +1,11 @@
+1 0 {
+2 _id=1
+3 number=18004664411
+4 date=1249177360040
+5 duration=10
+6 new=1
+7 type=2
+8 name=Jane Doe
+9 numberlabel=null
+10 numbertype=1
+11 }
diff --git a/tests/assets/testSynced/expected_contacts.txt b/tests/assets/testSynced/expected_contacts.txt
new file mode 100644
index 0000000..8ce6f03
--- /dev/null
+++ b/tests/assets/testSynced/expected_contacts.txt
@@ -0,0 +1,168 @@
+1 0 {
+2 _id=1
+3 display_name=Lemmy Test
+4 sort_key=Lemmy Test
+5 photo_id=null
+6 times_contacted=0
+7 last_time_contacted=0
+8 custom_ringtone=null
+9 send_to_voicemail=0
+10 starred=0
+11 in_visible_group=0
+12 has_phone_number=0
+13 lookup=2273r1-423444445C52345052
+14 }
+15 1 {
+16 _id=2
+17 display_name=698-147-02
+18 sort_key=698-147-02
+19 photo_id=null
+20 times_contacted=0
+21 last_time_contacted=0
+22 custom_ringtone=null
+23 send_to_voicemail=0
+24 starred=0
+25 in_visible_group=1
+26 has_phone_number=1
+27 lookup=389i561d08a30def1f46
+28 }
+29 2 {
+30 _id=3
+31 display_name=Mail
+32 sort_key=Mail
+33 photo_id=null
+34 times_contacted=0
+35 last_time_contacted=0
+36 custom_ringtone=null
+37 send_to_voicemail=0
+38 starred=0
+39 in_visible_group=1
+40 has_phone_number=0
+41 lookup=389i506b6479896c635d
+42 }
+43 3 {
+44 _id=4
+45 display_name=mail@dom.com
+46 sort_key=mail@dom.com
+47 photo_id=null
+48 times_contacted=0
+49 last_time_contacted=0
+50 custom_ringtone=null
+51 send_to_voicemail=0
+52 starred=0
+53 in_visible_group=1
+54 has_phone_number=0
+55 lookup=389i192ec38f0de81866
+56 }
+57 4 {
+58 _id=5
+59 display_name=Number
+60 sort_key=Number
+61 photo_id=null
+62 times_contacted=0
+63 last_time_contacted=0
+64 custom_ringtone=null
+65 send_to_voicemail=0
+66 starred=0
+67 in_visible_group=1
+68 has_phone_number=1
+69 lookup=389i3e879d80b2673fc
+70 }
+71 5 {
+72 _id=6
+73 display_name=Number And Mail
+74 sort_key=Number And Mail
+75 photo_id=null
+76 times_contacted=0
+77 last_time_contacted=0
+78 custom_ringtone=null
+79 send_to_voicemail=0
+80 starred=0
+81 in_visible_group=1
+82 has_phone_number=1
+83 lookup=389i4413217a0a1f5437
+84 }
+85 6 {
+86 _id=7
+87 display_name=Not Synced Number
+88 sort_key=Not Synced Number
+89 photo_id=null
+90 times_contacted=0
+91 last_time_contacted=0
+92 custom_ringtone=null
+93 send_to_voicemail=0
+94 starred=0
+95 in_visible_group=1
+96 has_phone_number=1
+97 lookup=389r7-464852505C463034324654442E344E
+98 }
+99 7 {
+100 _id=8
+101 display_name=Not Synced NumberMail
+102 sort_key=Not Synced NumberMail
+103 photo_id=null
+104 times_contacted=0
+105 last_time_contacted=0
+106 custom_ringtone=null
+107 send_to_voicemail=0
+108 starred=0
+109 in_visible_group=1
+110 has_phone_number=1
+111 lookup=389r8-464852505C463034324654442E344E442C3C42
+112 }
+113 8 {
+114 _id=9
+115 display_name=Not Synced Mail
+116 sort_key=Not Synced Mail
+117 photo_id=null
+118 times_contacted=0
+119 last_time_contacted=0
+120 custom_ringtone=null
+121 send_to_voicemail=0
+122 starred=0
+123 in_visible_group=1
+124 has_phone_number=0
+125 lookup=389r9-464852505C46303432442C3C42
+126 }
+127 9 {
+128 _id=10
+129 display_name=Not Synced
+130 sort_key=Not Synced
+131 photo_id=null
+132 times_contacted=0
+133 last_time_contacted=0
+134 custom_ringtone=null
+135 send_to_voicemail=0
+136 starred=0
+137 in_visible_group=1
+138 has_phone_number=0
+139 lookup=389r10-464852505C46303432
+140 }
+141 10 {
+142 _id=11
+143 display_name=1111111111
+144 sort_key=1111111111
+145 photo_id=null
+146 times_contacted=0
+147 last_time_contacted=0
+148 custom_ringtone=null
+149 send_to_voicemail=0
+150 starred=0
+151 in_visible_group=1
+152 has_phone_number=1
+153 lookup=389r11-297E297E297E297E297E297E297E297E297E297E
+154 }
+155 11 {
+156 _id=12
+157 display_name=notsynced@gmail.com
+158 sort_key=notsynced@gmail.com
+159 photo_id=null
+160 times_contacted=0
+161 last_time_contacted=0
+162 custom_ringtone=null
+163 send_to_voicemail=0
+164 starred=0
+165 in_visible_group=1
+166 has_phone_number=0
+167 lookup=389r12-464852505C4630343238442C3C42304844
+168 } \ No newline at end of file
diff --git a/tests/assets/testSynced/expected_data.txt b/tests/assets/testSynced/expected_data.txt
new file mode 100644
index 0000000..4cbb294
--- /dev/null
+++ b/tests/assets/testSynced/expected_data.txt
@@ -0,0 +1,810 @@
+1 0 {
+2 _id=778
+3 raw_contact_id=1
+4 mimetype=vnd.android.cursor.item/name
+5 data1=Lemmy Test
+6 data2=Lemmy
+7 data3=Test
+8 data4=null
+9 data5=null
+10 data6=null
+11 data7=null
+12 data8=null
+13 data9=null
+14 data10=1
+15 data11=0
+16 data12=null
+17 data13=null
+18 data14=null
+19 data15=null
+20 is_primary=0
+21 is_super_primary=0
+22 data_version=0
+23 data_sync1=null
+24 data_sync2=null
+25 data_sync3=null
+26 data_sync4=null
+27 }
+28 1 {
+29 _id=779
+30 raw_contact_id=3
+31 mimetype=vnd.android.cursor.item/name
+32 data1=Mail
+33 data2=Mail
+34 data3=null
+35 data4=null
+36 data5=null
+37 data6=null
+38 data7=null
+39 data8=null
+40 data9=null
+41 data10=1
+42 data11=0
+43 data12=null
+44 data13=null
+45 data14=null
+46 data15=null
+47 is_primary=0
+48 is_super_primary=0
+49 data_version=0
+50 data_sync1=null
+51 data_sync2=null
+52 data_sync3=null
+53 data_sync4=null
+54 }
+55 2 {
+56 _id=780
+57 raw_contact_id=5
+58 mimetype=vnd.android.cursor.item/name
+59 data1=Number
+60 data2=Number
+61 data3=null
+62 data4=null
+63 data5=null
+64 data6=null
+65 data7=null
+66 data8=null
+67 data9=null
+68 data10=1
+69 data11=0
+70 data12=null
+71 data13=null
+72 data14=null
+73 data15=null
+74 is_primary=0
+75 is_super_primary=0
+76 data_version=0
+77 data_sync1=null
+78 data_sync2=null
+79 data_sync3=null
+80 data_sync4=null
+81 }
+82 3 {
+83 _id=781
+84 raw_contact_id=6
+85 mimetype=vnd.android.cursor.item/name
+86 data1=Number And Mail
+87 data2=Number
+88 data3=Mail
+89 data4=null
+90 data5=And
+91 data6=null
+92 data7=null
+93 data8=null
+94 data9=null
+95 data10=1
+96 data11=0
+97 data12=null
+98 data13=null
+99 data14=null
+100 data15=null
+101 is_primary=0
+102 is_super_primary=0
+103 data_version=0
+104 data_sync1=null
+105 data_sync2=null
+106 data_sync3=null
+107 data_sync4=null
+108 }
+109 4 {
+110 _id=782
+111 raw_contact_id=7
+112 mimetype=vnd.android.cursor.item/name
+113 data1=Not Synced Number
+114 data2=Not
+115 data3=Number
+116 data4=null
+117 data5=Synced
+118 data6=null
+119 data7=null
+120 data8=null
+121 data9=
+122 data10=1
+123 data11=0
+124 data12=null
+125 data13=null
+126 data14=null
+127 data15=null
+128 is_primary=0
+129 is_super_primary=0
+130 data_version=0
+131 data_sync1=null
+132 data_sync2=null
+133 data_sync3=null
+134 data_sync4=null
+135 }
+136 5 {
+137 _id=783
+138 raw_contact_id=8
+139 mimetype=vnd.android.cursor.item/name
+140 data1=Not Synced NumberMail
+141 data2=Not
+142 data3=NumberMail
+143 data4=null
+144 data5=Synced
+145 data6=null
+146 data7=null
+147 data8=null
+148 data9=
+149 data10=1
+150 data11=0
+151 data12=null
+152 data13=null
+153 data14=null
+154 data15=null
+155 is_primary=0
+156 is_super_primary=0
+157 data_version=0
+158 data_sync1=null
+159 data_sync2=null
+160 data_sync3=null
+161 data_sync4=null
+162 }
+163 6 {
+164 _id=784
+165 raw_contact_id=9
+166 mimetype=vnd.android.cursor.item/name
+167 data1=Not Synced Mail
+168 data2=Not
+169 data3=Mail
+170 data4=null
+171 data5=Synced
+172 data6=null
+173 data7=null
+174 data8=null
+175 data9=
+176 data10=1
+177 data11=0
+178 data12=null
+179 data13=null
+180 data14=null
+181 data15=null
+182 is_primary=0
+183 is_super_primary=0
+184 data_version=0
+185 data_sync1=null
+186 data_sync2=null
+187 data_sync3=null
+188 data_sync4=null
+189 }
+190 7 {
+191 _id=785
+192 raw_contact_id=10
+193 mimetype=vnd.android.cursor.item/name
+194 data1=Not Synced
+195 data2=Not
+196 data3=Synced
+197 data4=null
+198 data5=null
+199 data6=null
+200 data7=null
+201 data8=null
+202 data9=
+203 data10=1
+204 data11=0
+205 data12=null
+206 data13=null
+207 data14=null
+208 data15=null
+209 is_primary=0
+210 is_super_primary=0
+211 data_version=0
+212 data_sync1=null
+213 data_sync2=null
+214 data_sync3=null
+215 data_sync4=null
+216 }
+217 8 {
+218 _id=786
+219 raw_contact_id=2
+220 mimetype=vnd.android.cursor.item/phone_v2
+221 data1=698-147-02
+222 data2=2
+223 data3=null
+224 data4=20741896
+225 data5=null
+226 data6=null
+227 data7=null
+228 data8=null
+229 data9=null
+230 data10=null
+231 data11=null
+232 data12=null
+233 data13=null
+234 data14=null
+235 data15=null
+236 is_primary=1
+237 is_super_primary=0
+238 data_version=0
+239 data_sync1=null
+240 data_sync2=null
+241 data_sync3=null
+242 data_sync4=null
+243 }
+244 9 {
+245 _id=787
+246 raw_contact_id=5
+247 mimetype=vnd.android.cursor.item/phone_v2
+248 data1=716-5432
+249 data2=2
+250 data3=null
+251 data4=2345617
+252 data5=null
+253 data6=null
+254 data7=null
+255 data8=null
+256 data9=null
+257 data10=null
+258 data11=null
+259 data12=null
+260 data13=null
+261 data14=null
+262 data15=null
+263 is_primary=1
+264 is_super_primary=0
+265 data_version=0
+266 data_sync1=null
+267 data_sync2=null
+268 data_sync3=null
+269 data_sync4=null
+270 }
+271 10 {
+272 _id=788
+273 raw_contact_id=6
+274 mimetype=vnd.android.cursor.item/phone_v2
+275 data1=542-31
+276 data2=2
+277 data3=null
+278 data4=13245
+279 data5=null
+280 data6=null
+281 data7=null
+282 data8=null
+283 data9=null
+284 data10=null
+285 data11=null
+286 data12=null
+287 data13=null
+288 data14=null
+289 data15=null
+290 is_primary=1
+291 is_super_primary=0
+292 data_version=0
+293 data_sync1=null
+294 data_sync2=null
+295 data_sync3=null
+296 data_sync4=null
+297 }
+298 11 {
+299 _id=789
+300 raw_contact_id=7
+301 mimetype=vnd.android.cursor.item/phone_v2
+302 data1=564-123-789
+303 data2=2
+304 data3=null
+305 data4=987321465
+306 data5=null
+307 data6=null
+308 data7=null
+309 data8=null
+310 data9=null
+311 data10=null
+312 data11=null
+313 data12=null
+314 data13=null
+315 data14=null
+316 data15=null
+317 is_primary=1
+318 is_super_primary=0
+319 data_version=0
+320 data_sync1=null
+321 data_sync2=null
+322 data_sync3=null
+323 data_sync4=null
+324 }
+325 12 {
+326 _id=790
+327 raw_contact_id=8
+328 mimetype=vnd.android.cursor.item/phone_v2
+329 data1=841-735-24
+330 data2=2
+331 data3=null
+332 data4=42537148
+333 data5=null
+334 data6=null
+335 data7=null
+336 data8=null
+337 data9=null
+338 data10=null
+339 data11=null
+340 data12=null
+341 data13=null
+342 data14=null
+343 data15=null
+344 is_primary=1
+345 is_super_primary=0
+346 data_version=0
+347 data_sync1=null
+348 data_sync2=null
+349 data_sync3=null
+350 data_sync4=null
+351 }
+352 13 {
+353 _id=791
+354 raw_contact_id=11
+355 mimetype=vnd.android.cursor.item/phone_v2
+356 data1=1111111111
+357 data2=2
+358 data3=null
+359 data4=1111111111
+360 data5=null
+361 data6=null
+362 data7=null
+363 data8=null
+364 data9=null
+365 data10=null
+366 data11=null
+367 data12=null
+368 data13=null
+369 data14=null
+370 data15=null
+371 is_primary=1
+372 is_super_primary=0
+373 data_version=0
+374 data_sync1=null
+375 data_sync2=null
+376 data_sync3=null
+377 data_sync4=null
+378 }
+379 14 {
+380 _id=792
+381 raw_contact_id=3
+382 mimetype=vnd.android.cursor.item/email_v2
+383 data1=weyj@xtdt.com
+384 data2=1
+385 data3=null
+386 data4=null
+387 data5=null
+388 data6=null
+389 data7=null
+390 data8=null
+391 data9=null
+392 data10=null
+393 data11=null
+394 data12=null
+395 data13=null
+396 data14=null
+397 data15=null
+398 is_primary=1
+399 is_super_primary=0
+400 data_version=0
+401 data_sync1=null
+402 data_sync2=null
+403 data_sync3=null
+404 data_sync4=null
+405 }
+406 15 {
+407 _id=793
+408 raw_contact_id=4
+409 mimetype=vnd.android.cursor.item/email_v2
+410 data1=mail@dom.com
+411 data2=1
+412 data3=null
+413 data4=null
+414 data5=null
+415 data6=null
+416 data7=null
+417 data8=null
+418 data9=null
+419 data10=null
+420 data11=null
+421 data12=null
+422 data13=null
+423 data14=null
+424 data15=null
+425 is_primary=1
+426 is_super_primary=0
+427 data_version=0
+428 data_sync1=null
+429 data_sync2=null
+430 data_sync3=null
+431 data_sync4=null
+432 }
+433 16 {
+434 _id=794
+435 raw_contact_id=8
+436 mimetype=vnd.android.cursor.item/email_v2
+437 data1=doooooo@sgghhh.com
+438 data2=1
+439 data3=null
+440 data4=null
+441 data5=null
+442 data6=null
+443 data7=null
+444 data8=null
+445 data9=null
+446 data10=null
+447 data11=null
+448 data12=null
+449 data13=null
+450 data14=null
+451 data15=null
+452 is_primary=1
+453 is_super_primary=0
+454 data_version=0
+455 data_sync1=null
+456 data_sync2=null
+457 data_sync3=null
+458 data_sync4=null
+459 }
+460 17 {
+461 _id=795
+462 raw_contact_id=9
+463 mimetype=vnd.android.cursor.item/email_v2
+464 data1=ahhh@glkbgghh.com
+465 data2=1
+466 data3=null
+467 data4=null
+468 data5=null
+469 data6=null
+470 data7=null
+471 data8=null
+472 data9=null
+473 data10=null
+474 data11=null
+475 data12=null
+476 data13=null
+477 data14=null
+478 data15=null
+479 is_primary=1
+480 is_super_primary=0
+481 data_version=0
+482 data_sync1=null
+483 data_sync2=null
+484 data_sync3=null
+485 data_sync4=null
+486 }
+487 18 {
+488 _id=796
+489 raw_contact_id=12
+490 mimetype=vnd.android.cursor.item/email_v2
+491 data1=notsynced@gmail.com
+492 data2=1
+493 data3=null
+494 data4=null
+495 data5=null
+496 data6=null
+497 data7=null
+498 data8=null
+499 data9=null
+500 data10=null
+501 data11=null
+502 data12=null
+503 data13=null
+504 data14=null
+505 data15=null
+506 is_primary=1
+507 is_super_primary=0
+508 data_version=0
+509 data_sync1=null
+510 data_sync2=null
+511 data_sync3=null
+512 data_sync4=null
+513 }
+514 19 {
+515 _id=797
+516 raw_contact_id=2
+517 mimetype=vnd.android.cursor.item/group_membership
+518 data1=1
+519 data2=null
+520 data3=null
+521 data4=null
+522 data5=null
+523 data6=null
+524 data7=null
+525 data8=null
+526 data9=null
+527 data10=null
+528 data11=null
+529 data12=null
+530 data13=null
+531 data14=null
+532 data15=null
+533 is_primary=0
+534 is_super_primary=0
+535 data_version=0
+536 data_sync1=null
+537 data_sync2=null
+538 data_sync3=null
+539 data_sync4=null
+540 }
+541 20 {
+542 _id=798
+543 raw_contact_id=3
+544 mimetype=vnd.android.cursor.item/group_membership
+545 data1=1
+546 data2=null
+547 data3=null
+548 data4=null
+549 data5=null
+550 data6=null
+551 data7=null
+552 data8=null
+553 data9=null
+554 data10=null
+555 data11=null
+556 data12=null
+557 data13=null
+558 data14=null
+559 data15=null
+560 is_primary=0
+561 is_super_primary=0
+562 data_version=0
+563 data_sync1=null
+564 data_sync2=null
+565 data_sync3=null
+566 data_sync4=null
+567 }
+568 21 {
+569 _id=799
+570 raw_contact_id=4
+571 mimetype=vnd.android.cursor.item/group_membership
+572 data1=1
+573 data2=null
+574 data3=null
+575 data4=null
+576 data5=null
+577 data6=null
+578 data7=null
+579 data8=null
+580 data9=null
+581 data10=null
+582 data11=null
+583 data12=null
+584 data13=null
+585 data14=null
+586 data15=null
+587 is_primary=0
+588 is_super_primary=0
+589 data_version=0
+590 data_sync1=null
+591 data_sync2=null
+592 data_sync3=null
+593 data_sync4=null
+594 }
+595 22 {
+596 _id=800
+597 raw_contact_id=5
+598 mimetype=vnd.android.cursor.item/group_membership
+599 data1=1
+600 data2=null
+601 data3=null
+602 data4=null
+603 data5=null
+604 data6=null
+605 data7=null
+606 data8=null
+607 data9=null
+608 data10=null
+609 data11=null
+610 data12=null
+611 data13=null
+612 data14=null
+613 data15=null
+614 is_primary=0
+615 is_super_primary=0
+616 data_version=0
+617 data_sync1=null
+618 data_sync2=null
+619 data_sync3=null
+620 data_sync4=null
+621 }
+622 23 {
+623 _id=801
+624 raw_contact_id=6
+625 mimetype=vnd.android.cursor.item/group_membership
+626 data1=1
+627 data2=null
+628 data3=null
+629 data4=null
+630 data5=null
+631 data6=null
+632 data7=null
+633 data8=null
+634 data9=null
+635 data10=null
+636 data11=null
+637 data12=null
+638 data13=null
+639 data14=null
+640 data15=null
+641 is_primary=0
+642 is_super_primary=0
+643 data_version=0
+644 data_sync1=null
+645 data_sync2=null
+646 data_sync3=null
+647 data_sync4=null
+648 }
+649 24 {
+650 _id=802
+651 raw_contact_id=7
+652 mimetype=vnd.android.cursor.item/group_membership
+653 data1=1
+654 data2=null
+655 data3=null
+656 data4=null
+657 data5=null
+658 data6=null
+659 data7=null
+660 data8=null
+661 data9=null
+662 data10=null
+663 data11=null
+664 data12=null
+665 data13=null
+666 data14=null
+667 data15=null
+668 is_primary=0
+669 is_super_primary=0
+670 data_version=0
+671 data_sync1=null
+672 data_sync2=null
+673 data_sync3=null
+674 data_sync4=null
+675 }
+676 25 {
+677 _id=803
+678 raw_contact_id=8
+679 mimetype=vnd.android.cursor.item/group_membership
+680 data1=1
+681 data2=null
+682 data3=null
+683 data4=null
+684 data5=null
+685 data6=null
+686 data7=null
+687 data8=null
+688 data9=null
+689 data10=null
+690 data11=null
+691 data12=null
+692 data13=null
+693 data14=null
+694 data15=null
+695 is_primary=0
+696 is_super_primary=0
+697 data_version=0
+698 data_sync1=null
+699 data_sync2=null
+700 data_sync3=null
+701 data_sync4=null
+702 }
+703 26 {
+704 _id=804
+705 raw_contact_id=9
+706 mimetype=vnd.android.cursor.item/group_membership
+707 data1=1
+708 data2=null
+709 data3=null
+710 data4=null
+711 data5=null
+712 data6=null
+713 data7=null
+714 data8=null
+715 data9=null
+716 data10=null
+717 data11=null
+718 data12=null
+719 data13=null
+720 data14=null
+721 data15=null
+722 is_primary=0
+723 is_super_primary=0
+724 data_version=0
+725 data_sync1=null
+726 data_sync2=null
+727 data_sync3=null
+728 data_sync4=null
+729 }
+730 27 {
+731 _id=805
+732 raw_contact_id=10
+733 mimetype=vnd.android.cursor.item/group_membership
+734 data1=1
+735 data2=null
+736 data3=null
+737 data4=null
+738 data5=null
+739 data6=null
+740 data7=null
+741 data8=null
+742 data9=null
+743 data10=null
+744 data11=null
+745 data12=null
+746 data13=null
+747 data14=null
+748 data15=null
+749 is_primary=0
+750 is_super_primary=0
+751 data_version=0
+752 data_sync1=null
+753 data_sync2=null
+754 data_sync3=null
+755 data_sync4=null
+756 }
+757 28 {
+758 _id=806
+759 raw_contact_id=11
+760 mimetype=vnd.android.cursor.item/group_membership
+761 data1=1
+762 data2=null
+763 data3=null
+764 data4=null
+765 data5=null
+766 data6=null
+767 data7=null
+768 data8=null
+769 data9=null
+770 data10=null
+771 data11=null
+772 data12=null
+773 data13=null
+774 data14=null
+775 data15=null
+776 is_primary=0
+777 is_super_primary=0
+778 data_version=0
+779 data_sync1=null
+780 data_sync2=null
+781 data_sync3=null
+782 data_sync4=null
+783 }
+784 29 {
+785 _id=807
+786 raw_contact_id=12
+787 mimetype=vnd.android.cursor.item/group_membership
+788 data1=1
+789 data2=null
+790 data3=null
+791 data4=null
+792 data5=null
+793 data6=null
+794 data7=null
+795 data8=null
+796 data9=null
+797 data10=null
+798 data11=null
+799 data12=null
+800 data13=null
+801 data14=null
+802 data15=null
+803 is_primary=0
+804 is_super_primary=0
+805 data_version=0
+806 data_sync1=null
+807 data_sync2=null
+808 data_sync3=null
+809 data_sync4=null
+810 } \ No newline at end of file
diff --git a/tests/assets/testSynced/expected_groups.txt b/tests/assets/testSynced/expected_groups.txt
new file mode 100644
index 0000000..f253df2
--- /dev/null
+++ b/tests/assets/testSynced/expected_groups.txt
@@ -0,0 +1,17 @@
+1 0 {
+2 _id=1
+3 account_name=lemmytest@gmail.com
+4 account_type=com.google
+5 dirty=0
+6 group_visible=1
+7 notes=System Group: My Contacts
+8 res_package=null
+9 sourceid=6
+10 system_id=Contacts
+11 title=System Group: My Contacts
+12 version=1
+13 sync1=null
+14 sync2=null
+15 sync3=null
+16 sync4=null
+17 }
diff --git a/tests/assets/testSynced/expected_raw_contacts.txt b/tests/assets/testSynced/expected_raw_contacts.txt
new file mode 100644
index 0000000..d2da83c
--- /dev/null
+++ b/tests/assets/testSynced/expected_raw_contacts.txt
@@ -0,0 +1,216 @@
+1 0 {
+2 _id=1
+3 account_name=non_syncable
+4 account_type=com.google
+5 deleted=0
+6 dirty=1
+7 sourceid=null
+8 version=1
+9 sync1=null
+10 sync2=null
+11 sync3=null
+12 sync4=null
+13 display_name_source=40
+14 display_name=Lemmy Test
+15 display_name_alt=Test, Lemmy
+16 sort_key=Lemmy Test
+17 sort_key_alt=Test, Lemmy
+18 }
+19 1 {
+20 _id=2
+21 account_name=lemmytest@gmail.com
+22 account_type=com.google
+23 deleted=0
+24 dirty=0
+25 sourceid=561d08a30def1f46
+26 version=1
+27 sync1=1268764045346000
+28 sync2=null
+29 sync3=null
+30 sync4=null
+31 display_name_source=20
+32 display_name=698-147-02
+33 display_name_alt=698-147-02
+34 sort_key=698-147-02
+35 sort_key_alt=698-147-02
+36 }
+37 2 {
+38 _id=3
+39 account_name=lemmytest@gmail.com
+40 account_type=com.google
+41 deleted=0
+42 dirty=0
+43 sourceid=506b6479896c635d
+44 version=1
+45 sync1=1268764047603000
+46 sync2=null
+47 sync3=null
+48 sync4=null
+49 display_name_source=40
+50 display_name=Mail
+51 display_name_alt=Mail
+52 sort_key=Mail
+53 sort_key_alt=Mail
+54 }
+55 3 {
+56 _id=4
+57 account_name=lemmytest@gmail.com
+58 account_type=com.google
+59 deleted=0
+60 dirty=0
+61 sourceid=192ec38f0de81866
+62 version=1
+63 sync1=1268764074839000
+64 sync2=null
+65 sync3=null
+66 sync4=null
+67 display_name_source=10
+68 display_name=mail@dom.com
+69 display_name_alt=mail@dom.com
+70 sort_key=mail@dom.com
+71 sort_key_alt=mail@dom.com
+72 }
+73 4 {
+74 _id=5
+75 account_name=lemmytest@gmail.com
+76 account_type=com.google
+77 deleted=0
+78 dirty=0
+79 sourceid=3e879d80b2673fc
+80 version=1
+81 sync1=1268764126701000
+82 sync2=null
+83 sync3=null
+84 sync4=null
+85 display_name_source=40
+86 display_name=Number
+87 display_name_alt=Number
+88 sort_key=Number
+89 sort_key_alt=Number
+90 }
+91 5 {
+92 _id=6
+93 account_name=lemmytest@gmail.com
+94 account_type=com.google
+95 deleted=0
+96 dirty=0
+97 sourceid=4413217a0a1f5437
+98 version=1
+99 sync1=1268764154975000
+100 sync2=null
+101 sync3=null
+102 sync4=null
+103 display_name_source=40
+104 display_name=Number And Mail
+105 display_name_alt=Mail, Number And
+106 sort_key=Number And Mail
+107 sort_key_alt=Mail, Number And
+108 }
+109 6 {
+110 _id=7
+111 account_name=lemmytest@gmail.com
+112 account_type=com.google
+113 deleted=0
+114 dirty=1
+115 sourceid=null
+116 version=1
+117 sync1=null
+118 sync2=null
+119 sync3=null
+120 sync4=null
+121 display_name_source=40
+122 display_name=Not Synced Number
+123 display_name_alt=Number, Not Synced
+124 sort_key=Not Synced Number
+125 sort_key_alt=Number, Not Synced
+126 }
+127 7 {
+128 _id=8
+129 account_name=lemmytest@gmail.com
+130 account_type=com.google
+131 deleted=0
+132 dirty=1
+133 sourceid=null
+134 version=1
+135 sync1=null
+136 sync2=null
+137 sync3=null
+138 sync4=null
+139 display_name_source=40
+140 display_name=Not Synced NumberMail
+141 display_name_alt=NumberMail, Not Synced
+142 sort_key=Not Synced NumberMail
+143 sort_key_alt=NumberMail, Not Synced
+144 }
+145 8 {
+146 _id=9
+147 account_name=lemmytest@gmail.com
+148 account_type=com.google
+149 deleted=0
+150 dirty=1
+151 sourceid=null
+152 version=1
+153 sync1=null
+154 sync2=null
+155 sync3=null
+156 sync4=null
+157 display_name_source=40
+158 display_name=Not Synced Mail
+159 display_name_alt=Mail, Not Synced
+160 sort_key=Not Synced Mail
+161 sort_key_alt=Mail, Not Synced
+162 }
+163 9 {
+164 _id=10
+165 account_name=lemmytest@gmail.com
+166 account_type=com.google
+167 deleted=0
+168 dirty=1
+169 sourceid=null
+170 version=1
+171 sync1=null
+172 sync2=null
+173 sync3=null
+174 sync4=null
+175 display_name_source=40
+176 display_name=Not Synced
+177 display_name_alt=Synced, Not
+178 sort_key=Not Synced
+179 sort_key_alt=Synced, Not
+180 }
+181 10 {
+182 _id=11
+183 account_name=lemmytest@gmail.com
+184 account_type=com.google
+185 deleted=0
+186 dirty=1
+187 sourceid=null
+188 version=1
+189 sync1=null
+190 sync2=null
+191 sync3=null
+192 sync4=null
+193 display_name_source=20
+194 display_name=1111111111
+195 display_name_alt=1111111111
+196 sort_key=1111111111
+197 sort_key_alt=1111111111
+198 }
+199 11 {
+200 _id=12
+201 account_name=lemmytest@gmail.com
+202 account_type=com.google
+203 deleted=0
+204 dirty=1
+205 sourceid=null
+206 version=1
+207 sync1=null
+208 sync2=null
+209 sync3=null
+210 sync4=null
+211 display_name_source=10
+212 display_name=notsynced@gmail.com
+213 display_name_alt=notsynced@gmail.com
+214 sort_key=notsynced@gmail.com
+215 sort_key_alt=notsynced@gmail.com
+216 } \ No newline at end of file
diff --git a/tests/assets/testSynced/legacy_contacts.sql b/tests/assets/testSynced/legacy_contacts.sql
new file mode 100644
index 0000000..f5c374d
--- /dev/null
+++ b/tests/assets/testSynced/legacy_contacts.sql
@@ -0,0 +1,178 @@
+BEGIN TRANSACTION;
+PRAGMA user_version = 82;
+CREATE TABLE _deleted_groups (_sync_version TEXT,_sync_id TEXT,_sync_account TEXT,_sync_mark INTEGER);
+CREATE TABLE _deleted_people (_sync_version TEXT,_sync_id TEXT,_sync_account TEXT,_sync_mark INTEGER);
+CREATE TABLE _sync_state (_id INTEGER PRIMARY KEY,_sync_account TEXT,data TEXT,UNIQUE(_sync_account));
+INSERT INTO _sync_state VALUES(1,'lemmytest@gmail.com','');
+CREATE TABLE _sync_state_metadata (version INTEGER);
+INSERT INTO _sync_state_metadata VALUES(2);
+CREATE TABLE android_metadata (locale TEXT);
+INSERT INTO android_metadata VALUES('en_US');
+CREATE TABLE calls (_id INTEGER PRIMARY KEY AUTOINCREMENT,number TEXT,date INTEGER,duration INTEGER,type INTEGER,new INTEGER,name TEXT,numbertype INTEGER,numberlabel TEXT);
+CREATE TABLE contact_methods (_id INTEGER PRIMARY KEY AUTOINCREMENT,person INTEGER REFERENCES people(_id),kind INTEGER NOT NULL,data TEXT,aux_data TEXT,type INTEGER NOT NULL,label TEXT,isprimary INTEGER NOT NULL DEFAULT 0);
+INSERT INTO contact_methods VALUES(1,3,1,'weyj@xtdt.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(2,4,1,'mail@dom.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(3,8,1,'doooooo@sgghhh.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(4,9,1,'ahhh@glkbgghh.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(5,12,1,'notsynced@gmail.com',NULL,1,NULL,1);
+CREATE TABLE extensions (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,value TEXT NOT NULL,person INTEGER REFERENCES people(_id),UNIQUE(person, name));
+CREATE TABLE fave_msg_status (_id INTEGER PRIMARY KEY, msg TEXT, next_retry INTEGER, num_retries INTEGER);
+INSERT INTO fave_msg_status VALUES(100,16359444020020760201000000000000000000000000000000000000000000000000000000000000,1268764830477,2);
+CREATE TABLE fave_phone_changes (_id INTEGER PRIMARY KEY, old_phone TEXT, new_phone TEXT, change_timestamp TEXT);
+CREATE TABLE faves (_id INTEGER PRIMARY KEY, ui_pos INTEGER, phone TEXT NOT NULL, nickname TEXT NOT NULL, photo TEXT NOT NULL, timestamp TEXT NOT NULL, pending_phone TEXT, pending_nickname TEXT, pending_photo TEXT);
+INSERT INTO faves VALUES(1,1,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(2,2,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(3,3,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(4,4,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(5,5,0,'','',000000000000,NULL,NULL,NULL);
+CREATE TABLE groupmembership (_id INTEGER PRIMARY KEY,person INTEGER REFERENCES people(_id),group_id INTEGER REFERENCES groups(_id),group_sync_account STRING,group_sync_id STRING);
+INSERT INTO groupmembership VALUES(3,2,NULL,'lemmytest@gmail.com',6);
+INSERT INTO groupmembership VALUES(4,3,NULL,'lemmytest@gmail.com',6);
+INSERT INTO groupmembership VALUES(5,4,NULL,'lemmytest@gmail.com',6);
+INSERT INTO groupmembership VALUES(6,5,NULL,'lemmytest@gmail.com',6);
+INSERT INTO groupmembership VALUES(7,6,NULL,'lemmytest@gmail.com',6);
+INSERT INTO groupmembership VALUES(8,7,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(9,8,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(10,9,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(11,10,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(12,11,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(13,12,1,NULL,NULL);
+CREATE TABLE groups (_id INTEGER PRIMARY KEY AUTOINCREMENT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,name TEXT NOT NULL,notes TEXT,should_sync INTEGER NOT NULL DEFAULT 0,system_id TEXT,UNIQUE(name,system_id,_sync_account));
+INSERT INTO groups VALUES(1,'lemmytest@gmail.com',6,NULL,NULL,NULL,0,1,'System Group: My Contacts','System Group: My Contacts',0,'Contacts');
+CREATE TABLE organizations (_id INTEGER PRIMARY KEY AUTOINCREMENT,company TEXT,title TEXT,isprimary INTEGER NOT NULL DEFAULT 0,type INTEGER NOT NULL,label TEXT,person INTEGER REFERENCES people(_id));
+CREATE TABLE people (_id INTEGER PRIMARY KEY AUTOINCREMENT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,name TEXT COLLATE LOCALIZED,notes TEXT COLLATE LOCALIZED,times_contacted INTEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred INTEGER NOT NULL DEFAULT 0,primary_phone INTEGER REFERENCES phones(_id),primary_organization INTEGER REFERENCES organizations(_id),primary_email INTEGER REFERENCES contact_methods(_id),photo_version TEXT,custom_ringtone TEXT,send_to_voicemail INTEGER,phonetic_name TEXT COLLATE LOCALIZED);
+INSERT INTO people VALUES(1,'non_syncable',NULL,NULL,NULL,NULL,1,1,'Lemmy Test',NULL,0,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
+INSERT INTO people VALUES(2,'lemmytest@gmail.com','561d08a30def1f46',1268764045346000,1268764045346000,NULL,0,1,NULL,NULL,0,NULL,0,1,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO people VALUES(3,'lemmytest@gmail.com','506b6479896c635d',1268764047603000,1268764047603000,NULL,0,1,'Mail',NULL,0,NULL,0,NULL,NULL,1,NULL,NULL,0,NULL);
+INSERT INTO people VALUES(4,'lemmytest@gmail.com','192ec38f0de81866',1268764074839000,1268764074839000,NULL,0,1,NULL,NULL,0,NULL,0,NULL,NULL,2,NULL,NULL,0,NULL);
+INSERT INTO people VALUES(5,'lemmytest@gmail.com','3e879d80b2673fc',1268764126701000,1268764126701000,NULL,0,1,'Number',NULL,0,NULL,0,2,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO people VALUES(6,'lemmytest@gmail.com','4413217a0a1f5437',1268764154975000,1268764154975000,NULL,0,1,'Number And Mail',NULL,0,NULL,0,3,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO people VALUES(7,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'Not Synced Number',NULL,0,NULL,0,4,NULL,NULL,NULL,NULL,0,'');
+INSERT INTO people VALUES(8,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'Not Synced NumberMail',NULL,0,NULL,0,5,NULL,3,NULL,NULL,0,'');
+INSERT INTO people VALUES(9,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'Not Synced Mail',NULL,0,NULL,0,NULL,NULL,4,NULL,NULL,0,'');
+INSERT INTO people VALUES(10,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'Not Synced',NULL,0,NULL,0,NULL,NULL,NULL,NULL,NULL,0,'');
+INSERT INTO people VALUES(11,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'',NULL,0,NULL,0,6,NULL,NULL,NULL,NULL,0,'');
+INSERT INTO people VALUES(12,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,1,NULL,'',NULL,0,NULL,0,NULL,NULL,5,NULL,NULL,0,'');
+CREATE TABLE peopleLookup (token TEXT,source INTEGER REFERENCES people(_id),token_index INTEGER);
+INSERT INTO peopleLookup VALUES('3f31414159064f314d4f',1,0);
+INSERT INTO peopleLookup VALUES('4f314d4f',1,1);
+INSERT INTO peopleLookup VALUES('4129393f',3,0);
+INSERT INTO peopleLookup VALUES('4351412b314b',5,0);
+INSERT INTO peopleLookup VALUES('4351412b314b0629432f064129393f',6,0);
+INSERT INTO peopleLookup VALUES('29432f',6,1);
+INSERT INTO peopleLookup VALUES('4129393f',6,2);
+INSERT INTO peopleLookup VALUES('43454f064d59432d312f064351412b314b',7,0);
+INSERT INTO peopleLookup VALUES('4d59432d312f',7,1);
+INSERT INTO peopleLookup VALUES('4351412b314b',7,2);
+INSERT INTO peopleLookup VALUES('43454f064d59432d312f064351412b314b4129393f',8,0);
+INSERT INTO peopleLookup VALUES('4d59432d312f',8,1);
+INSERT INTO peopleLookup VALUES('4351412b314b4129393f',8,2);
+INSERT INTO peopleLookup VALUES('43454f064d59432d312f064129393f',9,0);
+INSERT INTO peopleLookup VALUES('4d59432d312f',9,1);
+INSERT INTO peopleLookup VALUES('4129393f',9,2);
+INSERT INTO peopleLookup VALUES('43454f064d59432d312f',10,0);
+INSERT INTO peopleLookup VALUES('4d59432d312f',10,1);
+INSERT INTO peopleLookup VALUES('',11,0);
+INSERT INTO peopleLookup VALUES('',12,0);
+CREATE TABLE peopleLookupWithPhoneticName (token TEXT,source INTEGER REFERENCES people(_id),token_index INTEGER);
+INSERT INTO peopleLookupWithPhoneticName VALUES('3f31414159064f314d4f',1,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4f314d4f',1,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('225d',2,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4129393f',3,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('225d',4,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4351412b314b',5,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4351412b314b0629432f064129393f',6,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('29432f',6,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4129393f',6,2);
+INSERT INTO peopleLookupWithPhoneticName VALUES('43454f064d59432d312f064351412b314b',7,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4d59432d312f',7,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4351412b314b',7,2);
+INSERT INTO peopleLookupWithPhoneticName VALUES('43454f064d59432d312f064351412b314b4129393f',8,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4d59432d312f',8,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4351412b314b4129393f',8,2);
+INSERT INTO peopleLookupWithPhoneticName VALUES('43454f064d59432d312f064129393f',9,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4d59432d312f',9,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4129393f',9,2);
+INSERT INTO peopleLookupWithPhoneticName VALUES('43454f064d59432d312f',10,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4d59432d312f',10,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('225d',11,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('225d',12,0);
+CREATE TABLE phones (_id INTEGER PRIMARY KEY AUTOINCREMENT,person INTEGER REFERENCES people(_id),type INTEGER NOT NULL,number TEXT,number_key TEXT,label TEXT,isprimary INTEGER NOT NULL DEFAULT 0);
+INSERT INTO phones VALUES(1,2,2,'698-147-02',20741896,NULL,1);
+INSERT INTO phones VALUES(2,5,2,'716-5432',2345617,NULL,1);
+INSERT INTO phones VALUES(3,6,2,'542-31',13245,NULL,1);
+INSERT INTO phones VALUES(4,7,2,'564-123-789',987321465,NULL,1);
+INSERT INTO phones VALUES(5,8,2,'841-735-24',42537148,NULL,1);
+INSERT INTO phones VALUES(6,11,2,1111111111,1111111111,NULL,1);
+CREATE TABLE photos (_id INTEGER PRIMARY KEY AUTOINCREMENT,exists_on_server INTEGER NOT NULL DEFAULT 0,person INTEGER REFERENCES people(_id), local_version TEXT,data BLOB,sync_error TEXT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,UNIQUE(person) );
+INSERT INTO photos VALUES(1,0,1,NULL,NULL,NULL,'non_syncable',NULL,NULL,NULL,NULL,0,1);
+INSERT INTO photos VALUES(2,0,2,NULL,NULL,NULL,'lemmytest@gmail.com','561d08a30def1f46','1B2M2Y8AsgTpgAmY7PhCfg','1B2M2Y8AsgTpgAmY7PhCfg',NULL,0,1);
+INSERT INTO photos VALUES(3,0,3,NULL,NULL,NULL,'lemmytest@gmail.com','506b6479896c635d','1B2M2Y8AsgTpgAmY7PhCfg','1B2M2Y8AsgTpgAmY7PhCfg',NULL,0,1);
+INSERT INTO photos VALUES(4,0,4,NULL,NULL,NULL,'lemmytest@gmail.com','192ec38f0de81866','1B2M2Y8AsgTpgAmY7PhCfg','1B2M2Y8AsgTpgAmY7PhCfg',NULL,0,1);
+INSERT INTO photos VALUES(5,0,5,NULL,NULL,NULL,'lemmytest@gmail.com','3e879d80b2673fc','1B2M2Y8AsgTpgAmY7PhCfg','1B2M2Y8AsgTpgAmY7PhCfg',NULL,0,1);
+INSERT INTO photos VALUES(6,0,6,NULL,NULL,NULL,'lemmytest@gmail.com','4413217a0a1f5437','1B2M2Y8AsgTpgAmY7PhCfg','1B2M2Y8AsgTpgAmY7PhCfg',NULL,0,1);
+INSERT INTO photos VALUES(7,0,7,NULL,NULL,NULL,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(8,0,8,NULL,NULL,NULL,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(9,0,9,NULL,NULL,NULL,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(10,0,10,NULL,NULL,NULL,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(11,0,11,NULL,NULL,NULL,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(12,0,12,NULL,NULL,NULL,'lemmytest@gmail.com',NULL,NULL,NULL,NULL,0,NULL);
+CREATE TABLE settings (_id INTEGER PRIMARY KEY,_sync_account TEXT,key STRING NOT NULL,value STRING );
+INSERT INTO settings VALUES(1,NULL,'syncEverything',1);
+CREATE TABLE sqlite_sequence(name,seq);
+INSERT INTO sqlite_sequence VALUES('groups',1);
+INSERT INTO sqlite_sequence VALUES('people',12);
+INSERT INTO sqlite_sequence VALUES('photos',12);
+INSERT INTO sqlite_sequence VALUES('phones',6);
+INSERT INTO sqlite_sequence VALUES('contact_methods',5);
+CREATE TABLE voice_dialer_timestamp (_id INTEGER PRIMARY KEY,timestamp INTEGER);
+INSERT INTO voice_dialer_timestamp VALUES(1,1268764377);
+CREATE INDEX contactMethodsPeopleIndex ON contact_methods (person);
+CREATE INDEX extensionsIndex1 ON extensions (person, name);
+CREATE INDEX groupmembershipIndex1 ON groupmembership (person, group_id);
+CREATE INDEX groupmembershipIndex2 ON groupmembership (group_id, person);
+CREATE INDEX groupmembershipIndex3 ON groupmembership (group_sync_account, group_sync_id);
+CREATE INDEX groupsSyncDirtyIndex ON groups (_sync_dirty);
+CREATE INDEX organizationsIndex1 ON organizations (person);
+CREATE INDEX peopleLookupIndex ON peopleLookup (token,source);
+CREATE INDEX peopleLookupWithPhoneticNameIndex ON peopleLookupWithPhoneticName (token,source);
+CREATE INDEX peopleNameIndex ON people (name);
+CREATE INDEX peopleSyncDirtyIndex ON people (_sync_dirty);
+CREATE INDEX peopleSyncIdIndex ON people (_sync_id);
+CREATE INDEX phonesIndex1 ON phones (person);
+CREATE INDEX phonesIndex2 ON phones (number_key);
+CREATE INDEX photoPersonIndex ON photos (person);
+CREATE INDEX photosSyncDirtyIndex ON photos (_sync_dirty);
+CREATE TRIGGER contact_cleanup DELETE ON people BEGIN DELETE FROM peopleLookup WHERE source = old._id;DELETE FROM peopleLookupWithPhoneticName WHERE source = old._id;DELETE FROM phones WHERE person = old._id;DELETE FROM contact_methods WHERE person = old._id;DELETE FROM organizations WHERE person = old._id;DELETE FROM groupmembership WHERE person = old._id;DELETE FROM extensions WHERE person = old._id;END;
+CREATE TRIGGER contact_methods_INSERT_typeAndLabel AFTER INSERT ON contact_methods WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER contact_methods_UPDATE_typeAndLabel AFTER UPDATE ON contact_methods WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER contact_methods_delete DELETE ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER contact_methods_insert INSERT ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;END;
+CREATE TRIGGER contact_methods_update UPDATE ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER extensions_delete DELETE ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER extensions_insert INSERT ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER extensions_update AFTER UPDATE ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER groupmembership_delete DELETE ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER groupmembership_insert INSERT ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER groupmembership_update AFTER UPDATE ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER groups_cleanup DELETE ON groups BEGIN UPDATE groupmembership SET group_id = null WHERE group_id = old._id;END;
+CREATE TRIGGER groups_to_deleted DELETE ON groups WHEN old._sync_id is not null BEGIN INSERT INTO _deleted_groups (_sync_id, _sync_account, _sync_version) VALUES (old._sync_id, old._sync_account, old._sync_version);END;
+CREATE TRIGGER organizations_INSERT_typeAndLabel AFTER INSERT ON organizations WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER organizations_UPDATE_typeAndLabel AFTER UPDATE ON organizations WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER organizations_delete DELETE ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER organizations_insert INSERT ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER organizations_update AFTER UPDATE ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER peopleDeleteAndPhotos DELETE ON people BEGIN DELETE FROM photos WHERE person=OLD._id; END;
+CREATE TRIGGER peopleLookupWithPhoneticName_insert AFTER INSERT ON people BEGIN SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, GET_NORMALIZED_STRING(CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') THEN new.phonetic_name ELSE (CASE WHEN (new.name is NOT NULL AND new.name != '') THEN new.name ELSE '' END) END), ' ', 1);END;
+CREATE TRIGGER peopleLookupWithPhoneticName_update UPDATE OF name, phonetic_name ON people BEGIN DELETE FROM peopleLookupWithPhoneticName WHERE source = new._id;SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, GET_NORMALIZED_STRING(CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') THEN new.phonetic_name ELSE (CASE WHEN (new.name is NOT NULL AND new.name != '') THEN new.name ELSE '' END) END), ' ', 1);END;
+CREATE TRIGGER peopleLookup_insert AFTER INSERT ON people BEGIN SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);END;
+CREATE TRIGGER peopleLookup_update UPDATE OF name ON people BEGIN DELETE FROM peopleLookup WHERE source = new._id;SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);END;
+CREATE TRIGGER people_timesContacted UPDATE OF last_time_contacted ON people BEGIN UPDATE people SET times_contacted = (new.times_contacted + 1) WHERE _id = new._id;END;
+CREATE TRIGGER phones_INSERT_typeAndLabel AFTER INSERT ON phones WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER phones_UPDATE_typeAndLabel AFTER UPDATE ON phones WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER phones_delete DELETE ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER phones_insert INSERT ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;END;
+CREATE TRIGGER phones_update UPDATE ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER timestamp_trigger1 AFTER UPDATE ON phones BEGIN UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') WHERE _id=1;END;
+CREATE TRIGGER timestamp_trigger2 AFTER UPDATE OF name ON people BEGIN UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') WHERE _id=1;END;
+COMMIT;
diff --git a/tests/assets/testSynced/readme.txt b/tests/assets/testSynced/readme.txt
new file mode 100644
index 0000000..e3f39d5
--- /dev/null
+++ b/tests/assets/testSynced/readme.txt
@@ -0,0 +1,3 @@
+The contacts in this example were created on a device that was synchronized to the server.
+Contacts up to ID=6 were created and synchronized. The synch was then disabled and the others
+were created. \ No newline at end of file
diff --git a/tests/assets/testUnsynced/expected_calls.txt b/tests/assets/testUnsynced/expected_calls.txt
new file mode 100644
index 0000000..3d566ec
--- /dev/null
+++ b/tests/assets/testUnsynced/expected_calls.txt
@@ -0,0 +1,11 @@
+1 0 {
+2 _id=1
+3 number=18004664411
+4 date=1249177360040
+5 duration=10
+6 new=1
+7 type=2
+8 name=Jane Doe
+9 numberlabel=null
+10 numbertype=1
+11 }
diff --git a/tests/assets/testUnsynced/expected_contacts.txt b/tests/assets/testUnsynced/expected_contacts.txt
new file mode 100644
index 0000000..32dfdfb
--- /dev/null
+++ b/tests/assets/testUnsynced/expected_contacts.txt
@@ -0,0 +1,70 @@
+1 0 {
+2 _id=1
+3 display_name=Number And Mail
+4 sort_key=Number And Mail
+5 photo_id=null
+6 times_contacted=0
+7 last_time_contacted=0
+8 custom_ringtone=null
+9 send_to_voicemail=0
+10 starred=0
+11 in_visible_group=1
+12 has_phone_number=1
+13 lookup=0r1-4654442E344E2C4632442C3C42
+14 }
+15 1 {
+16 _id=2
+17 display_name=Number
+18 sort_key=Number
+19 photo_id=null
+20 times_contacted=0
+21 last_time_contacted=0
+22 custom_ringtone=null
+23 send_to_voicemail=0
+24 starred=0
+25 in_visible_group=1
+26 has_phone_number=1
+27 lookup=0r2-4654442E344E
+28 }
+29 2 {
+30 _id=3
+31 display_name=Mail
+32 sort_key=Mail
+33 photo_id=null
+34 times_contacted=0
+35 last_time_contacted=0
+36 custom_ringtone=null
+37 send_to_voicemail=0
+38 starred=0
+39 in_visible_group=1
+40 has_phone_number=0
+41 lookup=0r3-442C3C42
+42 }
+43 3 {
+44 _id=4
+45 display_name=698-147-02
+46 sort_key=698-147-02
+47 photo_id=null
+48 times_contacted=0
+49 last_time_contacted=0
+50 custom_ringtone=null
+51 send_to_voicemail=0
+52 starred=0
+53 in_visible_group=1
+54 has_phone_number=1
+55 lookup=0r4-2988298E298C297E2984298A297C2980
+56 }
+57 4 {
+58 _id=5
+59 display_name=mail@dom.com
+60 sort_key=mail@dom.com
+61 photo_id=null
+62 times_contacted=0
+63 last_time_contacted=0
+64 custom_ringtone=null
+65 send_to_voicemail=0
+66 starred=0
+67 in_visible_group=1
+68 has_phone_number=0
+69 lookup=0r5-442C3C42324844304844
+70 }
diff --git a/tests/assets/testUnsynced/expected_data.txt b/tests/assets/testUnsynced/expected_data.txt
new file mode 100644
index 0000000..4571f75
--- /dev/null
+++ b/tests/assets/testUnsynced/expected_data.txt
@@ -0,0 +1,378 @@
+1 0 {
+2 _id=778
+3 raw_contact_id=1
+4 mimetype=vnd.android.cursor.item/name
+5 data1=Number And Mail
+6 data2=Number
+7 data3=Mail
+8 data4=null
+9 data5=And
+10 data6=null
+11 data7=null
+12 data8=null
+13 data9=
+14 data10=1
+15 data11=0
+16 data12=null
+17 data13=null
+18 data14=null
+19 data15=null
+20 is_primary=0
+21 is_super_primary=0
+22 data_version=0
+23 data_sync1=null
+24 data_sync2=null
+25 data_sync3=null
+26 data_sync4=null
+27 }
+28 1 {
+29 _id=779
+30 raw_contact_id=2
+31 mimetype=vnd.android.cursor.item/name
+32 data1=Number
+33 data2=Number
+34 data3=null
+35 data4=null
+36 data5=null
+37 data6=null
+38 data7=null
+39 data8=null
+40 data9=
+41 data10=1
+42 data11=0
+43 data12=null
+44 data13=null
+45 data14=null
+46 data15=null
+47 is_primary=0
+48 is_super_primary=0
+49 data_version=0
+50 data_sync1=null
+51 data_sync2=null
+52 data_sync3=null
+53 data_sync4=null
+54 }
+55 2 {
+56 _id=780
+57 raw_contact_id=3
+58 mimetype=vnd.android.cursor.item/name
+59 data1=Mail
+60 data2=Mail
+61 data3=null
+62 data4=null
+63 data5=null
+64 data6=null
+65 data7=null
+66 data8=null
+67 data9=
+68 data10=1
+69 data11=0
+70 data12=null
+71 data13=null
+72 data14=null
+73 data15=null
+74 is_primary=0
+75 is_super_primary=0
+76 data_version=0
+77 data_sync1=null
+78 data_sync2=null
+79 data_sync3=null
+80 data_sync4=null
+81 }
+82 3 {
+83 _id=781
+84 raw_contact_id=1
+85 mimetype=vnd.android.cursor.item/phone_v2
+86 data1=542-31
+87 data2=2
+88 data3=null
+89 data4=13245
+90 data5=null
+91 data6=null
+92 data7=null
+93 data8=null
+94 data9=null
+95 data10=null
+96 data11=null
+97 data12=null
+98 data13=null
+99 data14=null
+100 data15=null
+101 is_primary=1
+102 is_super_primary=0
+103 data_version=0
+104 data_sync1=null
+105 data_sync2=null
+106 data_sync3=null
+107 data_sync4=null
+108 }
+109 4 {
+110 _id=782
+111 raw_contact_id=2
+112 mimetype=vnd.android.cursor.item/phone_v2
+113 data1=716-5432
+114 data2=2
+115 data3=null
+116 data4=2345617
+117 data5=null
+118 data6=null
+119 data7=null
+120 data8=null
+121 data9=null
+122 data10=null
+123 data11=null
+124 data12=null
+125 data13=null
+126 data14=null
+127 data15=null
+128 is_primary=1
+129 is_super_primary=0
+130 data_version=0
+131 data_sync1=null
+132 data_sync2=null
+133 data_sync3=null
+134 data_sync4=null
+135 }
+136 5 {
+137 _id=783
+138 raw_contact_id=4
+139 mimetype=vnd.android.cursor.item/phone_v2
+140 data1=698-147-02
+141 data2=2
+142 data3=null
+143 data4=20741896
+144 data5=null
+145 data6=null
+146 data7=null
+147 data8=null
+148 data9=null
+149 data10=null
+150 data11=null
+151 data12=null
+152 data13=null
+153 data14=null
+154 data15=null
+155 is_primary=1
+156 is_super_primary=0
+157 data_version=0
+158 data_sync1=null
+159 data_sync2=null
+160 data_sync3=null
+161 data_sync4=null
+162 }
+163 6 {
+164 _id=784
+165 raw_contact_id=1
+166 mimetype=vnd.android.cursor.item/email_v2
+167 data1=gdgjj.fxhnj@ggh.com
+168 data2=1
+169 data3=null
+170 data4=null
+171 data5=null
+172 data6=null
+173 data7=null
+174 data8=null
+175 data9=null
+176 data10=null
+177 data11=null
+178 data12=null
+179 data13=null
+180 data14=null
+181 data15=null
+182 is_primary=1
+183 is_super_primary=0
+184 data_version=0
+185 data_sync1=null
+186 data_sync2=null
+187 data_sync3=null
+188 data_sync4=null
+189 }
+190 7 {
+191 _id=785
+192 raw_contact_id=3
+193 mimetype=vnd.android.cursor.item/email_v2
+194 data1=weyj@xtdt.com
+195 data2=1
+196 data3=null
+197 data4=null
+198 data5=null
+199 data6=null
+200 data7=null
+201 data8=null
+202 data9=null
+203 data10=null
+204 data11=null
+205 data12=null
+206 data13=null
+207 data14=null
+208 data15=null
+209 is_primary=1
+210 is_super_primary=0
+211 data_version=0
+212 data_sync1=null
+213 data_sync2=null
+214 data_sync3=null
+215 data_sync4=null
+216 }
+217 8 {
+218 _id=786
+219 raw_contact_id=5
+220 mimetype=vnd.android.cursor.item/email_v2
+221 data1=mail@dom.com
+222 data2=1
+223 data3=null
+224 data4=null
+225 data5=null
+226 data6=null
+227 data7=null
+228 data8=null
+229 data9=null
+230 data10=null
+231 data11=null
+232 data12=null
+233 data13=null
+234 data14=null
+235 data15=null
+236 is_primary=1
+237 is_super_primary=0
+238 data_version=0
+239 data_sync1=null
+240 data_sync2=null
+241 data_sync3=null
+242 data_sync4=null
+243 }
+244 9 {
+245 _id=787
+246 raw_contact_id=1
+247 mimetype=vnd.android.cursor.item/group_membership
+248 data1=1
+249 data2=null
+250 data3=null
+251 data4=null
+252 data5=null
+253 data6=null
+254 data7=null
+255 data8=null
+256 data9=null
+257 data10=null
+258 data11=null
+259 data12=null
+260 data13=null
+261 data14=null
+262 data15=null
+263 is_primary=0
+264 is_super_primary=0
+265 data_version=0
+266 data_sync1=null
+267 data_sync2=null
+268 data_sync3=null
+269 data_sync4=null
+270 }
+271 10 {
+272 _id=788
+273 raw_contact_id=2
+274 mimetype=vnd.android.cursor.item/group_membership
+275 data1=1
+276 data2=null
+277 data3=null
+278 data4=null
+279 data5=null
+280 data6=null
+281 data7=null
+282 data8=null
+283 data9=null
+284 data10=null
+285 data11=null
+286 data12=null
+287 data13=null
+288 data14=null
+289 data15=null
+290 is_primary=0
+291 is_super_primary=0
+292 data_version=0
+293 data_sync1=null
+294 data_sync2=null
+295 data_sync3=null
+296 data_sync4=null
+297 }
+298 11 {
+299 _id=789
+300 raw_contact_id=3
+301 mimetype=vnd.android.cursor.item/group_membership
+302 data1=1
+303 data2=null
+304 data3=null
+305 data4=null
+306 data5=null
+307 data6=null
+308 data7=null
+309 data8=null
+310 data9=null
+311 data10=null
+312 data11=null
+313 data12=null
+314 data13=null
+315 data14=null
+316 data15=null
+317 is_primary=0
+318 is_super_primary=0
+319 data_version=0
+320 data_sync1=null
+321 data_sync2=null
+322 data_sync3=null
+323 data_sync4=null
+324 }
+325 12 {
+326 _id=790
+327 raw_contact_id=4
+328 mimetype=vnd.android.cursor.item/group_membership
+329 data1=1
+330 data2=null
+331 data3=null
+332 data4=null
+333 data5=null
+334 data6=null
+335 data7=null
+336 data8=null
+337 data9=null
+338 data10=null
+339 data11=null
+340 data12=null
+341 data13=null
+342 data14=null
+343 data15=null
+344 is_primary=0
+345 is_super_primary=0
+346 data_version=0
+347 data_sync1=null
+348 data_sync2=null
+349 data_sync3=null
+350 data_sync4=null
+351 }
+352 13 {
+353 _id=791
+354 raw_contact_id=5
+355 mimetype=vnd.android.cursor.item/group_membership
+356 data1=1
+357 data2=null
+358 data3=null
+359 data4=null
+360 data5=null
+361 data6=null
+362 data7=null
+363 data8=null
+364 data9=null
+365 data10=null
+366 data11=null
+367 data12=null
+368 data13=null
+369 data14=null
+370 data15=null
+371 is_primary=0
+372 is_super_primary=0
+373 data_version=0
+374 data_sync1=null
+375 data_sync2=null
+376 data_sync3=null
+377 data_sync4=null
+378 }
diff --git a/tests/assets/testUnsynced/expected_groups.txt b/tests/assets/testUnsynced/expected_groups.txt
new file mode 100644
index 0000000..ebae5fe
--- /dev/null
+++ b/tests/assets/testUnsynced/expected_groups.txt
@@ -0,0 +1,17 @@
+1 0 {
+2 _id=1
+3 account_name=null
+4 account_type=null
+5 dirty=0
+6 group_visible=1
+7 notes=null
+8 res_package=null
+9 sourceid=null
+10 system_id=Contacts
+11 title=Contacts
+12 version=1
+13 sync1=null
+14 sync2=null
+15 sync3=null
+16 sync4=null
+17 }
diff --git a/tests/assets/testUnsynced/expected_raw_contacts.txt b/tests/assets/testUnsynced/expected_raw_contacts.txt
new file mode 100644
index 0000000..6833760
--- /dev/null
+++ b/tests/assets/testUnsynced/expected_raw_contacts.txt
@@ -0,0 +1,90 @@
+1 0 {
+2 _id=1
+3 account_name=null
+4 account_type=null
+5 deleted=0
+6 dirty=1
+7 sourceid=null
+8 version=1
+9 sync1=null
+10 sync2=null
+11 sync3=null
+12 sync4=null
+13 display_name_source=40
+14 display_name=Number And Mail
+15 display_name_alt=Mail, Number And
+16 sort_key=Number And Mail
+17 sort_key_alt=Mail, Number And
+18 }
+19 1 {
+20 _id=2
+21 account_name=null
+22 account_type=null
+23 deleted=0
+24 dirty=1
+25 sourceid=null
+26 version=1
+27 sync1=null
+28 sync2=null
+29 sync3=null
+30 sync4=null
+31 display_name_source=40
+32 display_name=Number
+33 display_name_alt=Number
+34 sort_key=Number
+35 sort_key_alt=Number
+36 }
+37 2 {
+38 _id=3
+39 account_name=null
+40 account_type=null
+41 deleted=0
+42 dirty=1
+43 sourceid=null
+44 version=1
+45 sync1=null
+46 sync2=null
+47 sync3=null
+48 sync4=null
+49 display_name_source=40
+50 display_name=Mail
+51 display_name_alt=Mail
+52 sort_key=Mail
+53 sort_key_alt=Mail
+54 }
+55 3 {
+56 _id=4
+57 account_name=null
+58 account_type=null
+59 deleted=0
+60 dirty=1
+61 sourceid=null
+62 version=1
+63 sync1=null
+64 sync2=null
+65 sync3=null
+66 sync4=null
+67 display_name_source=20
+68 display_name=698-147-02
+69 display_name_alt=698-147-02
+70 sort_key=698-147-02
+71 sort_key_alt=698-147-02
+72 }
+73 4 {
+74 _id=5
+75 account_name=null
+76 account_type=null
+77 deleted=0
+78 dirty=1
+79 sourceid=null
+80 version=1
+81 sync1=null
+82 sync2=null
+83 sync3=null
+84 sync4=null
+85 display_name_source=10
+86 display_name=mail@dom.com
+87 display_name_alt=mail@dom.com
+88 sort_key=mail@dom.com
+89 sort_key_alt=mail@dom.com
+90 }
diff --git a/tests/assets/testUnsynced/legacy_contacts.sql b/tests/assets/testUnsynced/legacy_contacts.sql
new file mode 100644
index 0000000..6aa6473
--- /dev/null
+++ b/tests/assets/testUnsynced/legacy_contacts.sql
@@ -0,0 +1,122 @@
+BEGIN TRANSACTION;
+PRAGMA user_version = 82;
+CREATE TABLE _deleted_groups (_sync_version TEXT,_sync_id TEXT,_sync_account TEXT,_sync_mark INTEGER);
+CREATE TABLE _deleted_people (_sync_version TEXT,_sync_id TEXT,_sync_account TEXT,_sync_mark INTEGER);
+CREATE TABLE _sync_state (_id INTEGER PRIMARY KEY,_sync_account TEXT,data TEXT,UNIQUE(_sync_account));
+CREATE TABLE _sync_state_metadata (version INTEGER);
+INSERT INTO _sync_state_metadata VALUES(2);
+CREATE TABLE android_metadata (locale TEXT);
+INSERT INTO android_metadata VALUES('en_US');
+CREATE TABLE calls (_id INTEGER PRIMARY KEY AUTOINCREMENT,number TEXT,date INTEGER,duration INTEGER,type INTEGER,new INTEGER,name TEXT,numbertype INTEGER,numberlabel TEXT);
+CREATE TABLE contact_methods (_id INTEGER PRIMARY KEY AUTOINCREMENT,person INTEGER REFERENCES people(_id),kind INTEGER NOT NULL,data TEXT,aux_data TEXT,type INTEGER NOT NULL,label TEXT,isprimary INTEGER NOT NULL DEFAULT 0);
+INSERT INTO contact_methods VALUES(1,1,1,'gdgjj.fxhnj@ggh.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(2,3,1,'weyj@xtdt.com',NULL,1,NULL,1);
+INSERT INTO contact_methods VALUES(3,5,1,'mail@dom.com',NULL,1,NULL,1);
+CREATE TABLE extensions (_id INTEGER PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,value TEXT NOT NULL,person INTEGER REFERENCES people(_id),UNIQUE(person, name));
+CREATE TABLE fave_msg_status (_id INTEGER PRIMARY KEY, msg TEXT, next_retry INTEGER, num_retries INTEGER);
+CREATE TABLE fave_phone_changes (_id INTEGER PRIMARY KEY, old_phone TEXT, new_phone TEXT, change_timestamp TEXT);
+CREATE TABLE faves (_id INTEGER PRIMARY KEY, ui_pos INTEGER, phone TEXT NOT NULL, nickname TEXT NOT NULL, photo TEXT NOT NULL, timestamp TEXT NOT NULL, pending_phone TEXT, pending_nickname TEXT, pending_photo TEXT);
+INSERT INTO faves VALUES(1,1,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(2,2,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(3,3,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(4,4,0,'','',000000000000,NULL,NULL,NULL);
+INSERT INTO faves VALUES(5,5,0,'','',000000000000,NULL,NULL,NULL);
+CREATE TABLE groupmembership (_id INTEGER PRIMARY KEY,person INTEGER REFERENCES people(_id),group_id INTEGER REFERENCES groups(_id),group_sync_account STRING,group_sync_id STRING);
+INSERT INTO groupmembership VALUES(1,1,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(2,2,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(3,3,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(4,4,1,NULL,NULL);
+INSERT INTO groupmembership VALUES(5,5,1,NULL,NULL);
+CREATE TABLE groups (_id INTEGER PRIMARY KEY AUTOINCREMENT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,name TEXT NOT NULL,notes TEXT,should_sync INTEGER NOT NULL DEFAULT 0,system_id TEXT,UNIQUE(name,system_id,_sync_account));
+INSERT INTO groups VALUES(1,NULL,NULL,NULL,NULL,NULL,0,NULL,'Contacts',NULL,0,'Contacts');
+CREATE TABLE organizations (_id INTEGER PRIMARY KEY AUTOINCREMENT,company TEXT,title TEXT,isprimary INTEGER NOT NULL DEFAULT 0,type INTEGER NOT NULL,label TEXT,person INTEGER REFERENCES people(_id));
+CREATE TABLE people (_id INTEGER PRIMARY KEY AUTOINCREMENT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,name TEXT COLLATE LOCALIZED,notes TEXT COLLATE LOCALIZED,times_contacted INTEGER NOT NULL DEFAULT 0,last_time_contacted INTEGER,starred INTEGER NOT NULL DEFAULT 0,primary_phone INTEGER REFERENCES phones(_id),primary_organization INTEGER REFERENCES organizations(_id),primary_email INTEGER REFERENCES contact_methods(_id),photo_version TEXT,custom_ringtone TEXT,send_to_voicemail INTEGER,phonetic_name TEXT COLLATE LOCALIZED);
+INSERT INTO people VALUES(1,NULL,NULL,NULL,NULL,NULL,1,NULL,'Number And Mail',NULL,0,NULL,0,1,NULL,1,NULL,NULL,0,'');
+INSERT INTO people VALUES(2,NULL,NULL,NULL,NULL,NULL,1,NULL,'Number',NULL,0,NULL,0,2,NULL,NULL,NULL,NULL,0,'');
+INSERT INTO people VALUES(3,NULL,NULL,NULL,NULL,NULL,1,NULL,'Mail',NULL,0,NULL,0,NULL,NULL,2,NULL,NULL,0,'');
+INSERT INTO people VALUES(4,NULL,NULL,NULL,NULL,NULL,1,NULL,'',NULL,0,NULL,0,3,NULL,NULL,NULL,NULL,0,'');
+INSERT INTO people VALUES(5,NULL,NULL,NULL,NULL,NULL,1,NULL,'',NULL,0,NULL,0,NULL,NULL,3,NULL,NULL,0,'');
+CREATE TABLE peopleLookup (token TEXT,source INTEGER REFERENCES people(_id),token_index INTEGER);
+INSERT INTO peopleLookup VALUES('4351412b314b0629432f064129393f',1,0);
+INSERT INTO peopleLookup VALUES('29432f',1,1);
+INSERT INTO peopleLookup VALUES('4129393f',1,2);
+INSERT INTO peopleLookup VALUES('4351412b314b',2,0);
+INSERT INTO peopleLookup VALUES('4129393f',3,0);
+INSERT INTO peopleLookup VALUES('',4,0);
+INSERT INTO peopleLookup VALUES('',5,0);
+CREATE TABLE peopleLookupWithPhoneticName (token TEXT,source INTEGER REFERENCES people(_id),token_index INTEGER);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4351412b314b0629432f064129393f',1,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('29432f',1,1);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4129393f',1,2);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4351412b314b',2,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('4129393f',3,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('225d',4,0);
+INSERT INTO peopleLookupWithPhoneticName VALUES('225d',5,0);
+CREATE TABLE phones (_id INTEGER PRIMARY KEY AUTOINCREMENT,person INTEGER REFERENCES people(_id),type INTEGER NOT NULL,number TEXT,number_key TEXT,label TEXT,isprimary INTEGER NOT NULL DEFAULT 0);
+INSERT INTO phones VALUES(1,1,2,'542-31',13245,NULL,1);
+INSERT INTO phones VALUES(2,2,2,'716-5432',2345617,NULL,1);
+INSERT INTO phones VALUES(3,4,2,'698-147-02',20741896,NULL,1);
+CREATE TABLE photos (_id INTEGER PRIMARY KEY AUTOINCREMENT,exists_on_server INTEGER NOT NULL DEFAULT 0,person INTEGER REFERENCES people(_id), local_version TEXT,data BLOB,sync_error TEXT,_sync_account TEXT,_sync_id TEXT,_sync_time TEXT,_sync_version TEXT,_sync_local_id INTEGER,_sync_dirty INTEGER NOT NULL DEFAULT 0,_sync_mark INTEGER,UNIQUE(person) );
+INSERT INTO photos VALUES(1,0,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(2,0,2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(3,0,3,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(4,0,4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL);
+INSERT INTO photos VALUES(5,0,5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,NULL);
+CREATE TABLE settings (_id INTEGER PRIMARY KEY,_sync_account TEXT,key STRING NOT NULL,value STRING );
+CREATE TABLE sqlite_sequence(name,seq);
+INSERT INTO sqlite_sequence VALUES('groups',1);
+INSERT INTO sqlite_sequence VALUES('people',5);
+INSERT INTO sqlite_sequence VALUES('photos',5);
+INSERT INTO sqlite_sequence VALUES('phones',3);
+INSERT INTO sqlite_sequence VALUES('contact_methods',3);
+CREATE TABLE voice_dialer_timestamp (_id INTEGER PRIMARY KEY,timestamp INTEGER);
+INSERT INTO voice_dialer_timestamp VALUES(1,1246834337);
+CREATE INDEX contactMethodsPeopleIndex ON contact_methods (person);
+CREATE INDEX extensionsIndex1 ON extensions (person, name);
+CREATE INDEX groupmembershipIndex1 ON groupmembership (person, group_id);
+CREATE INDEX groupmembershipIndex2 ON groupmembership (group_id, person);
+CREATE INDEX groupmembershipIndex3 ON groupmembership (group_sync_account, group_sync_id);
+CREATE INDEX groupsSyncDirtyIndex ON groups (_sync_dirty);
+CREATE INDEX organizationsIndex1 ON organizations (person);
+CREATE INDEX peopleLookupIndex ON peopleLookup (token,source);
+CREATE INDEX peopleLookupWithPhoneticNameIndex ON peopleLookupWithPhoneticName (token,source);
+CREATE INDEX peopleNameIndex ON people (name);
+CREATE INDEX peopleSyncDirtyIndex ON people (_sync_dirty);
+CREATE INDEX peopleSyncIdIndex ON people (_sync_id);
+CREATE INDEX phonesIndex1 ON phones (person);
+CREATE INDEX phonesIndex2 ON phones (number_key);
+CREATE INDEX photoPersonIndex ON photos (person);
+CREATE INDEX photosSyncDirtyIndex ON photos (_sync_dirty);
+CREATE TRIGGER contact_cleanup DELETE ON people BEGIN DELETE FROM peopleLookup WHERE source = old._id;DELETE FROM peopleLookupWithPhoneticName WHERE source = old._id;DELETE FROM phones WHERE person = old._id;DELETE FROM contact_methods WHERE person = old._id;DELETE FROM organizations WHERE person = old._id;DELETE FROM groupmembership WHERE person = old._id;DELETE FROM extensions WHERE person = old._id;END;
+CREATE TRIGGER contact_methods_INSERT_typeAndLabel AFTER INSERT ON contact_methods WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER contact_methods_UPDATE_typeAndLabel AFTER UPDATE ON contact_methods WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER contact_methods_delete DELETE ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER contact_methods_insert INSERT ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;END;
+CREATE TRIGGER contact_methods_update UPDATE ON contact_methods BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER extensions_delete DELETE ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER extensions_insert INSERT ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER extensions_update AFTER UPDATE ON extensions BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER groupmembership_delete DELETE ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER groupmembership_insert INSERT ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER groupmembership_update AFTER UPDATE ON groupmembership BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER groups_cleanup DELETE ON groups BEGIN UPDATE groupmembership SET group_id = null WHERE group_id = old._id;END;
+CREATE TRIGGER groups_to_deleted DELETE ON groups WHEN old._sync_id is not null BEGIN INSERT INTO _deleted_groups (_sync_id, _sync_account, _sync_version) VALUES (old._sync_id, old._sync_account, old._sync_version);END;
+CREATE TRIGGER organizations_INSERT_typeAndLabel AFTER INSERT ON organizations WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER organizations_UPDATE_typeAndLabel AFTER UPDATE ON organizations WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER organizations_delete DELETE ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER organizations_insert INSERT ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person; END;
+CREATE TRIGGER organizations_update AFTER UPDATE ON organizations BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person; END;
+CREATE TRIGGER peopleDeleteAndPhotos DELETE ON people BEGIN DELETE FROM photos WHERE person=OLD._id; END;
+CREATE TRIGGER peopleLookupWithPhoneticName_insert AFTER INSERT ON people BEGIN SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, GET_NORMALIZED_STRING(CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') THEN new.phonetic_name ELSE (CASE WHEN (new.name is NOT NULL AND new.name != '') THEN new.name ELSE '' END) END), ' ', 1);END;
+CREATE TRIGGER peopleLookupWithPhoneticName_update UPDATE OF name, phonetic_name ON people BEGIN DELETE FROM peopleLookupWithPhoneticName WHERE source = new._id;SELECT _TOKENIZE('peopleLookupWithPhoneticName', new._id, GET_NORMALIZED_STRING(CASE WHEN (new.phonetic_name IS NOT NULL AND new.phonetic_name != '') THEN new.phonetic_name ELSE (CASE WHEN (new.name is NOT NULL AND new.name != '') THEN new.name ELSE '' END) END), ' ', 1);END;
+CREATE TRIGGER peopleLookup_insert AFTER INSERT ON people BEGIN SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);END;
+CREATE TRIGGER peopleLookup_update UPDATE OF name ON people BEGIN DELETE FROM peopleLookup WHERE source = new._id;SELECT _TOKENIZE('peopleLookup', new._id, new.name, ' ', 1);END;
+CREATE TRIGGER people_timesContacted UPDATE OF last_time_contacted ON people BEGIN UPDATE people SET times_contacted = (new.times_contacted + 1) WHERE _id = new._id;END;
+CREATE TRIGGER phones_INSERT_typeAndLabel AFTER INSERT ON phones WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER phones_UPDATE_typeAndLabel AFTER UPDATE ON phones WHEN (NEW.type != 0 AND NEW.label IS NOT NULL) OR (NEW.type = 0 AND NEW.label IS NULL) BEGIN SELECT RAISE (ABORT, 'exactly one of type or label must be set'); END;
+CREATE TRIGGER phones_delete DELETE ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER phones_insert INSERT ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=new.person;END;
+CREATE TRIGGER phones_update UPDATE ON phones BEGIN UPDATE people SET _sync_dirty=1 WHERE people._id=old.person;END;
+CREATE TRIGGER timestamp_trigger1 AFTER UPDATE ON phones BEGIN UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') WHERE _id=1;END;
+CREATE TRIGGER timestamp_trigger2 AFTER UPDATE OF name ON people BEGIN UPDATE voice_dialer_timestamp SET timestamp=strftime('%s', 'now') WHERE _id=1;END;
+COMMIT;
diff --git a/tests/assets/testUnsynced/readme.txt b/tests/assets/testUnsynced/readme.txt
new file mode 100644
index 0000000..00c3ad9
--- /dev/null
+++ b/tests/assets/testUnsynced/readme.txt
@@ -0,0 +1,3 @@
+The contacts in this example were created on a device that is not synchronized with the server
+(by using the four corners trick in the Donut Welcome Screen). The contacts have different fields
+filled: With/Without name/email/phone.