1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.providers.contacts; 18 19 import android.content.ContentProviderOperation; 20 import android.content.ContentUris; 21 import android.content.ContentValues; 22 import android.database.Cursor; 23 import android.net.Uri; 24 import android.provider.ContactsContract.MetadataSync; 25 import android.provider.ContactsContract.MetadataSyncState; 26 import android.provider.ContactsContract.RawContacts; 27 import android.test.MoreAsserts; 28 import android.test.suitebuilder.annotation.MediumTest; 29 import com.android.providers.contacts.ContactsDatabaseHelper.MetadataSyncColumns; 30 import com.android.providers.contacts.testutil.RawContactUtil; 31 import com.google.android.collect.Lists; 32 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.HashSet; 36 import java.util.Set; 37 38 /** 39 * Unit tests for {@link com.android.providers.contacts.ContactMetadataProvider}. 40 * <p/> 41 * Run the test like this: 42 * <code> 43 * adb shell am instrument -e class com.android.providers.contacts.ContactMetadataProviderTest -w \ 44 * com.android.providers.contacts.tests/android.test.InstrumentationTestRunner 45 * </code> 46 */ 47 @MediumTest 48 public class ContactMetadataProviderTest extends BaseContactsProvider2Test { 49 private static String TEST_ACCOUNT_TYPE1 = "test_account_type1"; 50 private static String TEST_ACCOUNT_NAME1 = "test_account_name1"; 51 private static String TEST_DATA_SET1 = "plus"; 52 private static String TEST_BACKUP_ID1 = "1001"; 53 private static String TEST_DATA1 = "{\n" + 54 " \"unique_contact_id\": {\n" + 55 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 56 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 57 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 58 " \"contact_id\": " + TEST_BACKUP_ID1 + ",\n" + 59 " \"data_set\": \"GOOGLE_PLUS\"\n" + 60 " },\n" + 61 " \"contact_prefs\": {\n" + 62 " \"send_to_voicemail\": true,\n" + 63 " \"starred\": true,\n" + 64 " \"pinned\": 2\n" + 65 " }\n" + 66 " }"; 67 private static byte[] TEST_SYNC_STATE1 = "sync state1".getBytes(); 68 private static String TEST_ACCOUNT_TYPE2 = "test_account_type2"; 69 private static String TEST_ACCOUNT_NAME2 = "test_account_name2"; 70 private static String TEST_DATA_SET2 = null; 71 private static String TEST_BACKUP_ID2 = "1002"; 72 private static String TEST_DATA2 = "{\n" + 73 " \"unique_contact_id\": {\n" + 74 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 75 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE2 + ",\n" + 76 " \"account_name\": " + TEST_ACCOUNT_NAME2 + ",\n" + 77 " \"contact_id\": " + TEST_BACKUP_ID2 + ",\n" + 78 " \"data_set\": \"GOOGLE_PLUS\"\n" + 79 " },\n" + 80 " \"contact_prefs\": {\n" + 81 " \"send_to_voicemail\": true,\n" + 82 " \"starred\": true,\n" + 83 " \"pinned\": 2\n" + 84 " }\n" + 85 " }"; 86 private static byte[] TEST_SYNC_STATE2 = "sync state2".getBytes(); 87 private static String SELECTION_BY_TEST_ACCOUNT1 = MetadataSync.ACCOUNT_NAME + "='" + 88 TEST_ACCOUNT_NAME1 + "' AND " + MetadataSync.ACCOUNT_TYPE + "='" + TEST_ACCOUNT_TYPE1 + 89 "' AND " + MetadataSync.DATA_SET + "='" + TEST_DATA_SET1 + "'"; 90 91 private static String SELECTION_BY_TEST_ACCOUNT2 = MetadataSync.ACCOUNT_NAME + "='" + 92 TEST_ACCOUNT_NAME2 + "' AND " + MetadataSync.ACCOUNT_TYPE + "='" + TEST_ACCOUNT_TYPE2 + 93 "' AND " + MetadataSync.DATA_SET + "='" + TEST_DATA_SET2 + "'"; 94 95 private ContactMetadataProvider mContactMetadataProvider; 96 private AccountWithDataSet mTestAccount; 97 private ContentValues defaultValues; 98 99 @Override 100 protected void setUp() throws Exception { 101 super.setUp(); 102 mContactMetadataProvider = addProvider( 103 ContactMetadataProviderTestable.class, MetadataSync.METADATA_AUTHORITY); 104 // Reset the dbHelper to be the one ContactsProvider2 is using. Before this, two providers 105 // are using different dbHelpers. 106 mContactMetadataProvider.setDatabaseHelper(((SynchronousContactsProvider2) 107 mActor.provider).getDatabaseHelper(getContext())); 108 setupData(); 109 } 110 111 public void testInsertWithInvalidUri() { 112 try { 113 mResolver.insert(Uri.withAppendedPath(MetadataSync.METADATA_AUTHORITY_URI, 114 "metadata"), getDefaultValues()); 115 fail("the insert was expected to fail, but it succeeded"); 116 } catch (IllegalArgumentException e) { 117 // this was expected 118 } 119 } 120 121 public void testUpdateWithInvalidUri() { 122 try { 123 mResolver.update(Uri.withAppendedPath(MetadataSync.METADATA_AUTHORITY_URI, 124 "metadata"), getDefaultValues(), null, null); 125 fail("the update was expected to fail, but it succeeded"); 126 } catch (IllegalArgumentException e) { 127 // this was expected 128 } 129 } 130 131 public void testGetMetadataByAccount() { 132 Cursor c = mResolver.query(MetadataSync.CONTENT_URI, null, SELECTION_BY_TEST_ACCOUNT1, 133 null, null); 134 assertEquals(1, c.getCount()); 135 136 ContentValues expectedValues = defaultValues; 137 expectedValues.remove(MetadataSyncColumns.ACCOUNT_ID); 138 c.moveToFirst(); 139 assertCursorValues(c, expectedValues); 140 c.close(); 141 } 142 143 public void testFailOnInsertMetadataForSameAccountIdAndBackupId() { 144 // Insert a new metadata with same account and backupId as defaultValues should fail. 145 String newData = "{\n" + 146 " \"unique_contact_id\": {\n" + 147 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 148 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 149 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 150 " \"contact_id\": " + TEST_BACKUP_ID1 + ",\n" + 151 " \"data_set\": \"GOOGLE_PLUS\"\n" + 152 " },\n" + 153 " \"contact_prefs\": {\n" + 154 " \"send_to_voicemail\": false,\n" + 155 " \"starred\": false,\n" + 156 " \"pinned\": 1\n" + 157 " }\n" + 158 " }"; 159 160 ContentValues newValues = new ContentValues(); 161 newValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 162 newValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 163 newValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 164 newValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, TEST_BACKUP_ID1); 165 newValues.put(MetadataSync.DATA, newData); 166 newValues.put(MetadataSync.DELETED, 0); 167 try { 168 mResolver.insert(MetadataSync.CONTENT_URI, newValues); 169 } catch (Exception e) { 170 // Expected. 171 } 172 } 173 174 public void testInsertAndUpdateMetadataSync() { 175 // Create a raw contact with backupId. 176 String backupId = "backupId10001"; 177 long rawContactId = RawContactUtil.createRawContactWithAccountDataSet( 178 mResolver, mTestAccount); 179 Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, rawContactId); 180 ContentValues values = new ContentValues(); 181 values.put(RawContacts.BACKUP_ID, backupId); 182 assertEquals(1, mResolver.update(rawContactUri, values, null, null)); 183 184 assertStoredValue(rawContactUri, RawContacts._ID, rawContactId); 185 assertStoredValue(rawContactUri, RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 186 assertStoredValue(rawContactUri, RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 187 assertStoredValue(rawContactUri, RawContacts.BACKUP_ID, backupId); 188 assertStoredValue(rawContactUri, RawContacts.DATA_SET, TEST_DATA_SET1); 189 190 String deleted = "0"; 191 String insertJson = "{\n" + 192 " \"unique_contact_id\": {\n" + 193 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 194 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 195 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 196 " \"contact_id\": " + backupId + ",\n" + 197 " \"data_set\": \"GOOGLE_PLUS\"\n" + 198 " },\n" + 199 " \"contact_prefs\": {\n" + 200 " \"send_to_voicemail\": true,\n" + 201 " \"starred\": true,\n" + 202 " \"pinned\": 2\n" + 203 " }\n" + 204 " }"; 205 206 // Insert to MetadataSync table. 207 ContentValues insertedValues = new ContentValues(); 208 insertedValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, backupId); 209 insertedValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 210 insertedValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 211 insertedValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 212 insertedValues.put(MetadataSync.DATA, insertJson); 213 insertedValues.put(MetadataSync.DELETED, deleted); 214 Uri metadataUri = mResolver.insert(MetadataSync.CONTENT_URI, insertedValues); 215 216 long metadataId = ContentUris.parseId(metadataUri); 217 assertEquals(true, metadataId > 0); 218 219 // Check if RawContact table is updated after inserting metadata. 220 assertStoredValue(rawContactUri, RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 221 assertStoredValue(rawContactUri, RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 222 assertStoredValue(rawContactUri, RawContacts.BACKUP_ID, backupId); 223 assertStoredValue(rawContactUri, RawContacts.DATA_SET, TEST_DATA_SET1); 224 assertStoredValue(rawContactUri, RawContacts.SEND_TO_VOICEMAIL, "1"); 225 assertStoredValue(rawContactUri, RawContacts.STARRED, "1"); 226 assertStoredValue(rawContactUri, RawContacts.PINNED, "2"); 227 228 // Update the MetadataSync table. 229 String updatedJson = "{\n" + 230 " \"unique_contact_id\": {\n" + 231 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 232 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 233 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 234 " \"contact_id\": " + backupId + ",\n" + 235 " \"data_set\": \"GOOGLE_PLUS\"\n" + 236 " },\n" + 237 " \"contact_prefs\": {\n" + 238 " \"send_to_voicemail\": false,\n" + 239 " \"starred\": false,\n" + 240 " \"pinned\": 1\n" + 241 " }\n" + 242 " }"; 243 ContentValues updatedValues = new ContentValues(); 244 updatedValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, backupId); 245 updatedValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 246 updatedValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 247 updatedValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 248 updatedValues.put(MetadataSync.DATA, updatedJson); 249 updatedValues.put(MetadataSync.DELETED, deleted); 250 mResolver.insert(MetadataSync.CONTENT_URI, updatedValues); 251 252 // Check if the insert (actually update) is correct. 253 assertStoredValue(rawContactUri, RawContacts.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 254 assertStoredValue(rawContactUri, RawContacts.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 255 assertStoredValue(rawContactUri, RawContacts.DATA_SET, TEST_DATA_SET1); 256 assertStoredValue(rawContactUri, RawContacts.SEND_TO_VOICEMAIL, "0"); 257 assertStoredValue(rawContactUri, RawContacts.STARRED, "0"); 258 assertStoredValue(rawContactUri, RawContacts.PINNED, "1"); 259 } 260 261 public void testInsertMetadata() { 262 String backupId = "newBackupId"; 263 String deleted = "0"; 264 String insertJson = "{\n" + 265 " \"unique_contact_id\": {\n" + 266 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 267 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 268 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 269 " \"contact_id\": " + backupId + ",\n" + 270 " \"data_set\": \"GOOGLE_PLUS\"\n" + 271 " },\n" + 272 " \"contact_prefs\": {\n" + 273 " \"send_to_voicemail\": true,\n" + 274 " \"starred\": true,\n" + 275 " \"pinned\": 2\n" + 276 " }\n" + 277 " }"; 278 279 // Insert to MetadataSync table. 280 ContentValues insertedValues = new ContentValues(); 281 insertedValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, backupId); 282 insertedValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 283 insertedValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 284 insertedValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 285 insertedValues.put(MetadataSync.DATA, insertJson); 286 insertedValues.put(MetadataSync.DELETED, deleted); 287 Uri metadataUri = mResolver.insert(MetadataSync.CONTENT_URI, insertedValues); 288 289 long metadataId = ContentUris.parseId(metadataUri); 290 assertEquals(true, metadataId > 0); 291 } 292 293 public void testFailUpdateDeletedMetadata() { 294 String backupId = "backupId001"; 295 String newData = "{\n" + 296 " \"unique_contact_id\": {\n" + 297 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 298 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 299 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 300 " \"contact_id\": " + backupId + ",\n" + 301 " \"data_set\": \"GOOGLE_PLUS\"\n" + 302 " },\n" + 303 " \"contact_prefs\": {\n" + 304 " \"send_to_voicemail\": false,\n" + 305 " \"starred\": false,\n" + 306 " \"pinned\": 1\n" + 307 " }\n" + 308 " }"; 309 310 ContentValues newValues = new ContentValues(); 311 newValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 312 newValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 313 newValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 314 newValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, backupId); 315 newValues.put(MetadataSync.DATA, newData); 316 newValues.put(MetadataSync.DELETED, 1); 317 318 try { 319 mResolver.insert(MetadataSync.CONTENT_URI, newValues); 320 fail("the update was expected to fail, but it succeeded"); 321 } catch (IllegalArgumentException e) { 322 // Expected 323 } 324 } 325 326 public void testInsertWithNullData() { 327 ContentValues newValues = new ContentValues(); 328 String data = null; 329 String backupId = "backupId002"; 330 newValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 331 newValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 332 newValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 333 newValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, backupId); 334 newValues.put(MetadataSync.DATA, data); 335 newValues.put(MetadataSync.DELETED, 0); 336 337 try { 338 mResolver.insert(MetadataSync.CONTENT_URI, newValues); 339 } catch (IllegalArgumentException e) { 340 // Expected. 341 } 342 } 343 344 public void testDeleteMetadata() { 345 //insert another metadata for TEST_ACCOUNT 346 insertMetadata(TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1, "2", TEST_DATA1, 0); 347 Cursor c = mResolver.query(MetadataSync.CONTENT_URI, null, SELECTION_BY_TEST_ACCOUNT1, 348 null, null); 349 assertEquals(2, c.getCount()); 350 int numOfDeletion = mResolver.delete(MetadataSync.CONTENT_URI, SELECTION_BY_TEST_ACCOUNT1, 351 null); 352 assertEquals(2, numOfDeletion); 353 c = mResolver.query(MetadataSync.CONTENT_URI, null, SELECTION_BY_TEST_ACCOUNT1, 354 null, null); 355 assertEquals(0, c.getCount()); 356 } 357 358 public void testBulkInsert() { 359 Cursor c = mResolver.query(MetadataSync.CONTENT_URI, new String[]{MetadataSync._ID}, 360 SELECTION_BY_TEST_ACCOUNT1, null, null); 361 assertEquals(1, c.getCount()); 362 363 ContentValues values1 = getMetadataContentValues( 364 TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1, "123", TEST_DATA1, 0); 365 ContentValues values2 = getMetadataContentValues( 366 TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1, "456", TEST_DATA1, 0); 367 ContentValues[] values = new ContentValues[] {values1, values2}; 368 369 mResolver.bulkInsert(MetadataSync.CONTENT_URI, values); 370 c = mResolver.query(MetadataSync.CONTENT_URI, new String[] {MetadataSync._ID}, 371 SELECTION_BY_TEST_ACCOUNT1, null, null); 372 assertEquals(3, c.getCount()); 373 } 374 375 public void testBatchOperations() throws Exception { 376 // Two mentadata_sync entries in the beginning, one for TEST_ACCOUNT1 and another for 377 // TEST_ACCOUNT2 378 Cursor c = mResolver.query(MetadataSync.CONTENT_URI, new String[] {MetadataSync._ID}, 379 null, null, null); 380 assertEquals(2, c.getCount()); 381 382 String updatedData = "{\n" + 383 " \"unique_contact_id\": {\n" + 384 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 385 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 386 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 387 " \"contact_id\": " + TEST_BACKUP_ID1 + ",\n" + 388 " \"data_set\": \"GOOGLE_PLUS\"\n" + 389 " },\n" + 390 " \"contact_prefs\": {\n" + 391 " \"send_to_voicemail\": true,\n" + 392 " \"starred\": false,\n" + 393 " \"pinned\": 5\n" + 394 " }\n" + 395 " }"; 396 397 String newBackupId = "2222"; 398 String newData = "{\n" + 399 " \"unique_contact_id\": {\n" + 400 " \"account_type\": \"CUSTOM_ACCOUNT\",\n" + 401 " \"custom_account_type\": " + TEST_ACCOUNT_TYPE1 + ",\n" + 402 " \"account_name\": " + TEST_ACCOUNT_NAME1 + ",\n" + 403 " \"contact_id\": " + newBackupId + ",\n" + 404 " \"data_set\": \"GOOGLE_PLUS\"\n" + 405 " },\n" + 406 " \"contact_prefs\": {\n" + 407 " \"send_to_voicemail\": true,\n" + 408 " \"starred\": false,\n" + 409 " \"pinned\": 5\n" + 410 " }\n" + 411 " }"; 412 413 ArrayList<ContentProviderOperation> ops = Lists.newArrayList(); 414 ops.add(ContentProviderOperation.newInsert(MetadataSync.CONTENT_URI) 415 .withValue(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1) 416 .withValue(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1) 417 .withValue(MetadataSync.DATA_SET, TEST_DATA_SET1) 418 .withValue(MetadataSync.RAW_CONTACT_BACKUP_ID, TEST_BACKUP_ID1) 419 .withValue(MetadataSync.DATA, updatedData) 420 .withValue(MetadataSync.DELETED, 0) 421 .build()); 422 423 ops.add(ContentProviderOperation.newInsert(MetadataSync.CONTENT_URI) 424 .withValue(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1) 425 .withValue(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1) 426 .withValue(MetadataSync.DATA_SET, TEST_DATA_SET1) 427 .withValue(MetadataSync.RAW_CONTACT_BACKUP_ID, newBackupId) 428 .withValue(MetadataSync.DATA, newData) 429 .withValue(MetadataSync.DELETED, 0) 430 .build()); 431 432 ops.add(ContentProviderOperation.newDelete(MetadataSync.CONTENT_URI) 433 .withSelection(SELECTION_BY_TEST_ACCOUNT2, null) 434 .build()); 435 436 // Batch three operations: update the metadata_entry of TEST_ACCOUNT1; insert one new 437 // metadata_entry for TEST_ACCOUNT1; delete metadata_entry of TEST_ACCOUNT2 438 mResolver.applyBatch(MetadataSync.METADATA_AUTHORITY, ops); 439 440 // After the batch operations, there should be two metadata_entry for TEST_ACCOUNT1 with 441 // new data value and no metadata_entry for TEST_ACCOUNT2. 442 c = mResolver.query(MetadataSync.CONTENT_URI, new String[] {MetadataSync.DATA}, 443 SELECTION_BY_TEST_ACCOUNT1, null, null); 444 assertEquals(2, c.getCount()); 445 Set<String> actualData = new HashSet<>(); 446 while (c.moveToNext()) { 447 actualData.add(c.getString(0)); 448 } 449 c.close(); 450 MoreAsserts.assertContentsInAnyOrder(actualData, updatedData, newData); 451 452 c = mResolver.query(MetadataSync.CONTENT_URI, new String[] {MetadataSync._ID}, 453 SELECTION_BY_TEST_ACCOUNT2, null, null); 454 assertEquals(0, c.getCount()); 455 } 456 457 public void testQueryMetadataSyncState() { 458 String selection = MetadataSyncState.ACCOUNT_NAME + "=?1 AND " + 459 MetadataSyncState.ACCOUNT_TYPE + "=?2 AND " + MetadataSyncState.DATA_SET + "=?3"; 460 final String[] args = new String[]{TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1}; 461 final String[] projection = new String[]{MetadataSyncState.STATE}; 462 Cursor c = mResolver.query(MetadataSyncState.CONTENT_URI, projection, selection, args, 463 null); 464 assertEquals(1, c.getCount()); 465 c.moveToFirst(); 466 assertTrue(Arrays.equals(TEST_SYNC_STATE1, c.getBlob(0))); 467 c.close(); 468 } 469 470 public void testUpdateMetadataSyncState() { 471 mResolver.update(MetadataSyncState.CONTENT_URI, getSyncStateValues(TEST_ACCOUNT_NAME1, 472 TEST_ACCOUNT_TYPE1, TEST_DATA_SET1, TEST_SYNC_STATE2), null, null); 473 String selection = MetadataSyncState.ACCOUNT_NAME + "=?1 AND " + 474 MetadataSyncState.ACCOUNT_TYPE + "=?2 AND " + MetadataSyncState.DATA_SET + "=?3"; 475 final String[] args = new String[]{TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1}; 476 final String[] projection = new String[] {MetadataSyncState.STATE}; 477 Cursor c = mResolver.query(MetadataSyncState.CONTENT_URI, projection, selection, args, 478 null); 479 480 assertEquals(1, c.getCount()); 481 c.moveToFirst(); 482 assertTrue(Arrays.equals(TEST_SYNC_STATE2, c.getBlob(0))); 483 c.close(); 484 } 485 486 public void testUpdateMetadataSyncState_NonExisting() { 487 // Delete the existing one first. 488 String selection = MetadataSyncState.ACCOUNT_NAME + "=?1 AND " + 489 MetadataSyncState.ACCOUNT_TYPE + "=?2 AND " + MetadataSyncState.DATA_SET + "=?3"; 490 final String[] args = new String[]{TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1}; 491 492 mResolver.delete(MetadataSyncState.CONTENT_URI, selection, args); 493 494 mResolver.update(MetadataSyncState.CONTENT_URI, getSyncStateValues(TEST_ACCOUNT_NAME1, 495 TEST_ACCOUNT_TYPE1, TEST_DATA_SET1, TEST_SYNC_STATE2), null, null); 496 final String[] projection = new String[] {MetadataSyncState.STATE}; 497 Cursor c = mResolver.query(MetadataSyncState.CONTENT_URI, projection, selection, args, 498 null); 499 500 assertEquals(1, c.getCount()); 501 c.moveToFirst(); 502 assertTrue(Arrays.equals(TEST_SYNC_STATE2, c.getBlob(0))); 503 c.close(); 504 } 505 506 public void testDeleteMetadataSyncState() { 507 String selection = MetadataSyncState.ACCOUNT_NAME + "=?1 AND " + 508 MetadataSyncState.ACCOUNT_TYPE + "=?2 AND " + MetadataSyncState.DATA_SET + "=?3"; 509 final String[] args = new String[]{TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1}; 510 final String[] projection = new String[]{MetadataSyncState.STATE}; 511 Cursor c = mResolver.query(MetadataSyncState.CONTENT_URI, projection, selection, args, 512 null); 513 assertEquals(1, c.getCount()); 514 c.close(); 515 516 mResolver.delete(MetadataSyncState.CONTENT_URI, selection, args); 517 c = mResolver.query(MetadataSyncState.CONTENT_URI, projection, selection, args, 518 null); 519 assertEquals(0, c.getCount()); 520 c.close(); 521 } 522 523 private void setupData() { 524 mTestAccount = new AccountWithDataSet(TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, 525 TEST_DATA_SET1); 526 long rawContactId1 = RawContactUtil.createRawContactWithAccountDataSet( 527 mResolver, mTestAccount); 528 createAccount(TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1); 529 insertMetadata(getDefaultValues()); 530 insertMetadataSyncState(TEST_ACCOUNT_NAME1, TEST_ACCOUNT_TYPE1, TEST_DATA_SET1, 531 TEST_SYNC_STATE1); 532 533 // Insert another entry for another account 534 createAccount(TEST_ACCOUNT_NAME2, TEST_ACCOUNT_TYPE2, TEST_DATA_SET2); 535 insertMetadata(TEST_ACCOUNT_NAME2, TEST_ACCOUNT_TYPE2, TEST_DATA_SET2, TEST_BACKUP_ID2, 536 TEST_DATA2, 0); 537 insertMetadataSyncState(TEST_ACCOUNT_NAME2, TEST_ACCOUNT_TYPE2, TEST_DATA_SET2, 538 TEST_SYNC_STATE2); 539 } 540 541 private ContentValues getDefaultValues() { 542 defaultValues = new ContentValues(); 543 defaultValues.put(MetadataSync.ACCOUNT_NAME, TEST_ACCOUNT_NAME1); 544 defaultValues.put(MetadataSync.ACCOUNT_TYPE, TEST_ACCOUNT_TYPE1); 545 defaultValues.put(MetadataSync.DATA_SET, TEST_DATA_SET1); 546 defaultValues.put(MetadataSync.RAW_CONTACT_BACKUP_ID, TEST_BACKUP_ID1); 547 defaultValues.put(MetadataSync.DATA, TEST_DATA1); 548 defaultValues.put(MetadataSync.DELETED, 0); 549 return defaultValues; 550 } 551 552 private long insertMetadata(String accountName, String accountType, String dataSet, 553 String backupId, String data, int deleted) { 554 return insertMetadata(getMetadataContentValues( 555 accountName, accountType, dataSet, backupId, data, deleted)); 556 } 557 558 private ContentValues getMetadataContentValues(String accountName, String accountType, 559 String dataSet, String backupId, String data, int deleted) { 560 ContentValues values = new ContentValues(); 561 values.put(MetadataSync.ACCOUNT_NAME, accountName); 562 values.put(MetadataSync.ACCOUNT_TYPE, accountType); 563 values.put(MetadataSync.DATA_SET, dataSet); 564 values.put(MetadataSync.RAW_CONTACT_BACKUP_ID, backupId); 565 values.put(MetadataSync.DATA, data); 566 values.put(MetadataSync.DELETED, deleted); 567 return values; 568 } 569 570 private long insertMetadata(ContentValues values) { 571 return ContentUris.parseId(mResolver.insert(MetadataSync.CONTENT_URI, values)); 572 } 573 574 private long insertMetadataSyncState(String accountName, String accountType, 575 String dataSet, byte[] state) { 576 return ContentUris.parseId(mResolver.insert(MetadataSyncState.CONTENT_URI, 577 getSyncStateValues(accountName, accountType, dataSet, state))); 578 } 579 580 private ContentValues getSyncStateValues(String accountName, String accountType, 581 String dataSet, byte[] state) { 582 ContentValues values = new ContentValues(); 583 values.put(MetadataSyncState.ACCOUNT_NAME, accountName); 584 values.put(MetadataSyncState.ACCOUNT_TYPE, accountType); 585 values.put(MetadataSyncState.DATA_SET, dataSet); 586 values.put(MetadataSyncState.STATE, state); 587 return values; 588 } 589 } 590