/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.talkback.labeling; import android.annotation.TargetApi; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.content.res.Configuration; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.RemoteException; import android.test.ProviderTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; import com.android.utils.LogUtils; import com.android.utils.labeling.LabelsTable; import java.util.Locale; /** * Tests for {@link com.android.talkback.labeling.LabelProvider}. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public class LabelProviderTest extends ProviderTestCase2<LabelProvider> { private static final Uri INVALID_AUTHORITY_URI = new Uri.Builder() .scheme("content") .authority("invalid.authority") .path(LabelProvider.LABELS_PATH) .build(); private static final Uri INVALID_PATH_URI = new Uri.Builder() .scheme("content") .authority(LabelProvider.AUTHORITY) .path("invalid/path") .build(); private static final Uri LABEL_NEGATIVE_1_URI = ContentUris.withAppendedId(LabelProvider.LABELS_CONTENT_URI, -1L); private static final Uri LABEL_1_URI = ContentUris.withAppendedId(LabelProvider.LABELS_CONTENT_URI, 1L); private Locale mOriginalLocale; private int mOriginalLogLevel; public LabelProviderTest() { super(LabelProvider.class, LabelProvider.AUTHORITY); } @Override protected void setUp() throws Exception { super.setUp(); // Run the entire test with TalkBack locale set to ar_EG (Arabic/Egypt) locale. mOriginalLocale = getMockContext().getResources().getConfiguration().locale; setLocale(new Locale("ar", "EG")); mOriginalLogLevel = LogUtils.LOG_LEVEL; LogUtils.setLogLevel(Log.VERBOSE); } @Override protected void tearDown() throws Exception { super.tearDown(); setLocale(mOriginalLocale); LogUtils.LOG_LEVEL = mOriginalLogLevel; } private void setLocale(Locale locale) { Locale.setDefault(locale); Resources resources = getMockContext().getResources(); Configuration config = resources.getConfiguration(); config.locale = locale; resources.updateConfiguration(config, resources.getDisplayMetrics()); } /** * Tests URI matching in {@link com.android.talkback.labeling.LabelProvider}. * <p> * Note: This behavior seems to change slightly between framework versions, * e.g. between version 17 and 18. This test checks to see if the * {@link android.content.UriMatcher} works as expected in the provider code. */ @SmallTest public void testUriMatcher() { try { LabelProvider.sUriMatcher.match(null); fail("Expected exception."); } catch (NullPointerException expected) { // Expected } assertEquals(UriMatcher.NO_MATCH, LabelProvider.sUriMatcher.match(INVALID_AUTHORITY_URI)); assertEquals(UriMatcher.NO_MATCH, LabelProvider.sUriMatcher.match(INVALID_PATH_URI)); assertEquals(LabelProvider.LABELS, LabelProvider.sUriMatcher.match(LabelProvider.LABELS_CONTENT_URI)); assertEquals(UriMatcher.NO_MATCH, LabelProvider.sUriMatcher.match(LABEL_NEGATIVE_1_URI)); assertEquals(LabelProvider.LABELS_ID, LabelProvider.sUriMatcher.match(LABEL_1_URI)); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#insert(android.net.Uri, android.content.ContentValues)} with an invalid * URI argument. */ @SmallTest public void testInsert_invalidUri() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final Uri resultUri; try { resultUri = client.insert(INVALID_PATH_URI, new ContentValues()); } finally { client.release(); } assertNull(resultUri); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#insert(android.net.Uri, android.content.ContentValues)} with {@code null} * content values. */ @SmallTest public void testInsert_nullContentValues() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final Uri resultUri; try { resultUri = client.insert(LabelProvider.LABELS_CONTENT_URI, null); } finally { client.release(); } assertNull(resultUri); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#insert(android.net.Uri, android.content.ContentValues)} with empty content * values. */ @SmallTest public void testInsert_emptyContentValues() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = new ContentValues(); final Uri resultUri; try { resultUri = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); } finally { client.release(); } assertNull(resultUri); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#insert(android.net.Uri, android.content.ContentValues)} with an extra * content value. */ @SmallTest public void testInsert_extraContentValues() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); contentValues.put("invalid_key", 100); final Uri resultUri; try { resultUri = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); } finally { client.release(); } assertNull(resultUri); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#insert(android.net.Uri, android.content.ContentValues)} with specified * label ID. */ @SmallTest public void testInsert_specifiedlabelId() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); contentValues.put(LabelsTable.KEY_ID, 1L); final Uri resultUri; try { resultUri = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); } finally { client.release(); } assertNull(resultUri); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#insert(android.net.Uri, android.content.ContentValues)} with valid content * values. */ @SmallTest public void testInsert_success() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); final Uri resultUri; try { resultUri = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); } finally { client.release(); } final Uri expectedUri = ContentUris.withAppendedId(LabelProvider.LABELS_CONTENT_URI, 1L); assertEquals(expectedUri, resultUri); } /** * Tests the {@link android.content.ContentProvider} query method * {@link com.android.talkback.labeling.LabelProvider#query(android.net.Uri, String[], String, String[], String)} with * an invalid URI argument. */ @SmallTest public void testQuery_invalidUri() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final Cursor resultCursor; try { resultCursor = client.query( INVALID_PATH_URI, new String[] {}, "", new String[] {}, null); } finally { client.release(); } assertNull(resultCursor); } /** * Tests the {@link android.content.ContentProvider} query method * {@link com.android.talkback.labeling.LabelProvider#query(android.net.Uri, String[], String, String[], String)} with * the labels content URI argument. */ @SmallTest public void testQuery_labels() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final Cursor resultCursor; try { resultCursor = client.query(LabelProvider.LABELS_CONTENT_URI, LabelsTable.ALL_COLUMNS, null, null, null); } finally { client.release(); } assertNotNull(resultCursor); } /** * Tests the {@link android.content.ContentProvider} query method * {@link com.android.talkback.labeling.LabelProvider#query(android.net.Uri, String[], String, String[], String)} with * the labels ID content URI argument. */ @SmallTest public void testQuery_labelsId() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final Cursor resultCursor; try { resultCursor = client.query(LABEL_1_URI, LabelsTable.ALL_COLUMNS, null, null, null); } finally { client.release(); } assertNotNull(resultCursor); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#update(android.net.Uri, android.content.ContentValues, String, String[])} * with an invalid URI parameter. */ @SmallTest public void testUpdate_invalidUri() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final int affectedRows; try { affectedRows = client.update(INVALID_PATH_URI, getValidLabelContentValues(), null, null); } finally { client.release(); } assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#update(android.net.Uri, android.content.ContentValues, String, String[])} * with the labels URI parameter (not supported). */ @SmallTest public void testUpdate_labelsUri() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final int affectedRows; try { affectedRows = client.update(LabelProvider.LABELS_CONTENT_URI, getValidLabelContentValues(), null, null); } finally { client.release(); } assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#update(android.net.Uri, android.content.ContentValues, String, String[])} * with an invalid label ID. */ @SmallTest public void testUpdate_invalidId() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final int affectedRows; try { affectedRows = client.update(LABEL_NEGATIVE_1_URI, getValidLabelContentValues(), null, null); } finally { client.release(); } assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#update(android.net.Uri, android.content.ContentValues, String, String[])} * with valid arguments. * <p> * Note: This test depends on {@link com.android.talkback.labeling.LabelProvider#insert} functionality. */ @SmallTest public void testUpdate_success() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); final Uri insertResult = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); final int affectedRows; try { affectedRows = client.update(LABEL_1_URI, contentValues, null, null); } finally { client.release(); } assertEquals(LABEL_1_URI, insertResult); assertEquals(1, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#update(android.net.Uri, android.content.ContentValues, String, String[])} * with a selection argument. * <p> * Note: This test depends on {@link LabelProviderTest#testUpdate_success}. */ @SmallTest public void testUpdate_selection() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); final Uri insertResult = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); final String selection = String.format("%s = ?", LabelsTable.KEY_ID); final String[] selectionArgs = { Integer.toString(2) }; final int affectedRows; try { affectedRows = client.update(LABEL_1_URI, contentValues, selection, selectionArgs); } finally { client.release(); } assertEquals(LABEL_1_URI, insertResult); assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#delete(android.net.Uri, String, String[])} * with an invalid URI parameter. */ @SmallTest public void testDelete_invalidUri() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final int affectedRows; try { affectedRows = client.delete(INVALID_PATH_URI, null, null); } finally { client.release(); } assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#delete(android.net.Uri, String, String[])} * with the labels URI parameter (not supported). */ @SmallTest public void testDelete_labelsUri() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final int affectedRows; try { affectedRows = client.delete(LabelProvider.LABELS_CONTENT_URI, null, null); } finally { client.release(); } assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#delete(android.net.Uri, String, String[])} * with an invalid label ID. */ @SmallTest public void testDelete_invalidId() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final int affectedRows; try { affectedRows = client.delete(LABEL_NEGATIVE_1_URI, null, null); } finally { client.release(); } assertEquals(0, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#delete(android.net.Uri, String, String[])} with valid * arguments. * <p> * Note: This test depends on {@link com.android.talkback.labeling.LabelProvider#insert} functionality. */ @SmallTest public void testDelete_success() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); final Uri insertResult = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); final int affectedRows; try { affectedRows = client.delete(LABEL_1_URI, null, null); } finally { client.release(); } assertEquals(LABEL_1_URI, insertResult); assertEquals(1, affectedRows); } /** * Tests {@link com.android.talkback.labeling.LabelProvider#delete(android.net.Uri, String, String[])} with a * selection argument. * <p> * Note: This test depends on {@link LabelProviderTest#testDelete_success}. */ @SmallTest public void testDelete_selection() throws RemoteException { final ContentProviderClient client = getContentProviderClient(); final ContentValues contentValues = getValidLabelContentValues(); final Uri insertResult = client.insert(LabelProvider.LABELS_CONTENT_URI, contentValues); final String selection = String.format("%s = ?", LabelsTable.KEY_ID); final String[] selectionArgs = { Integer.toString(2) }; final int affectedRows; try { affectedRows = client.delete(LABEL_1_URI, selection, selectionArgs); } finally { client.release(); } assertEquals(LABEL_1_URI, insertResult); assertEquals(0, affectedRows); } private ContentProviderClient getContentProviderClient() { final ContentResolver resolver = getMockContentResolver(); return resolver.acquireContentProviderClient(LabelProvider.LABELS_CONTENT_URI); } private ContentValues getValidLabelContentValues() { final ContentValues contentValues = new ContentValues(); contentValues.put(LabelsTable.KEY_PACKAGE_NAME, "packageName"); contentValues.put(LabelsTable.KEY_VIEW_NAME, "viewName"); contentValues.put(LabelsTable.KEY_TEXT, "text"); contentValues.put(LabelsTable.KEY_LOCALE, "locale"); contentValues.put(LabelsTable.KEY_PACKAGE_VERSION, 2); contentValues.put(LabelsTable.KEY_SCREENSHOT_PATH, "screenshothPath"); contentValues.put(LabelsTable.KEY_TIMESTAMP, 3L); return contentValues; } }