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