blob: a92acfcdc0e6819d84f7ec246cee60efd5f271a2 [file] [log] [blame]
/*
* Copyright (C) 2019 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 android.content.cts;
import static android.content.ContentResolver.QUERY_ARG_SQL_SELECTION;
import static android.content.ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.database.MatrixCursor;
import android.net.Uri;
import android.os.Bundle;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import java.util.Objects;
@RunWith(AndroidJUnit4.class)
public class ContentProviderOperationTest {
private static final Uri TEST_URI = Uri.parse("content://com.example");
private static final Uri TEST_URI_RESULT = Uri.parse("content://com.example/12");
private static final String TEST_SELECTION = "foo=?";
private static final String[] TEST_SELECTION_ARGS = new String[] { "bar" };
private static final String TEST_METHOD = "test_method";
private static final String TEST_ARG = "test_arg";
private static final ContentValues TEST_VALUES = new ContentValues();
private static final Bundle TEST_EXTRAS = new Bundle();
private static final Bundle TEST_EXTRAS_WITH_SQL = new Bundle();
private static final Bundle TEST_EXTRAS_RESULT = new Bundle();
static {
TEST_VALUES.put("test_key", "test_value");
TEST_EXTRAS.putString("test_key", "test_value");
TEST_EXTRAS_WITH_SQL.putAll(TEST_EXTRAS);
TEST_EXTRAS_WITH_SQL.putString(QUERY_ARG_SQL_SELECTION, TEST_SELECTION);
TEST_EXTRAS_WITH_SQL.putStringArray(QUERY_ARG_SQL_SELECTION_ARGS, TEST_SELECTION_ARGS);
TEST_EXTRAS_RESULT.putString("test_result", "42");
}
private static final ContentProviderResult[] TEST_RESULTS = new ContentProviderResult[] {
new ContentProviderResult(TEST_URI_RESULT),
new ContentProviderResult(84),
new ContentProviderResult(TEST_EXTRAS_RESULT),
new ContentProviderResult(new IllegalArgumentException()),
};
private ContentProvider provider;
private ContentProviderOperation op;
private ContentProviderResult res;
@Before
public void setUp() throws Exception {
provider = mock(ContentProvider.class);
}
@Test
public void testInsert() throws Exception {
op = ContentProviderOperation.newInsert(TEST_URI)
.withValues(TEST_VALUES)
.withExtras(TEST_EXTRAS)
.build();
assertEquals(TEST_URI, op.getUri());
assertTrue(op.isInsert());
assertTrue(op.isWriteOperation());
when(provider.insert(eq(TEST_URI), eq(TEST_VALUES), eqBundle(TEST_EXTRAS)))
.thenReturn(TEST_URI_RESULT);
res = op.apply(provider, null, 0);
assertEquals(TEST_URI_RESULT, res.uri);
}
@Test
public void testUpdate() throws Exception {
op = ContentProviderOperation.newUpdate(TEST_URI)
.withSelection(TEST_SELECTION, TEST_SELECTION_ARGS)
.withValues(TEST_VALUES)
.withExtras(TEST_EXTRAS)
.build();
assertEquals(TEST_URI, op.getUri());
assertTrue(op.isUpdate());
assertTrue(op.isWriteOperation());
when(provider.update(eq(TEST_URI), eq(TEST_VALUES), eqBundle(TEST_EXTRAS_WITH_SQL)))
.thenReturn(1);
res = op.apply(provider, null, 0);
assertEquals(1, (int) res.count);
}
@Test
public void testDelete() throws Exception {
op = ContentProviderOperation.newDelete(TEST_URI)
.withSelection(TEST_SELECTION, TEST_SELECTION_ARGS)
.withExtras(TEST_EXTRAS)
.build();
assertEquals(TEST_URI, op.getUri());
assertTrue(op.isDelete());
assertTrue(op.isWriteOperation());
when(provider.delete(eq(TEST_URI), eqBundle(TEST_EXTRAS_WITH_SQL)))
.thenReturn(1);
res = op.apply(provider, null, 0);
assertEquals(1, (int) res.count);
}
@Test
public void testAssertQuery() throws Exception {
op = ContentProviderOperation.newAssertQuery(TEST_URI)
.withSelection(TEST_SELECTION, TEST_SELECTION_ARGS)
.withExtras(TEST_EXTRAS)
.withValues(TEST_VALUES)
.build();
assertEquals(TEST_URI, op.getUri());
assertTrue(op.isAssertQuery());
assertTrue(op.isReadOperation());
final MatrixCursor cursor = new MatrixCursor(new String[] { "test_key" });
cursor.addRow(new Object[] { "test_value" });
when(provider.query(eq(TEST_URI), eq(new String[] { "test_key" }),
eqBundle(TEST_EXTRAS_WITH_SQL), eq(null)))
.thenReturn(cursor);
op.apply(provider, null, 0);
}
@Test
public void testCall() throws Exception {
op = ContentProviderOperation.newCall(TEST_URI, TEST_METHOD, TEST_ARG)
.withExtras(TEST_EXTRAS)
.build();
assertEquals(TEST_URI, op.getUri());
assertTrue(op.isCall());
when(provider.call(eq(TEST_URI.getAuthority()), eq(TEST_METHOD),
eq(TEST_ARG), eqBundle(TEST_EXTRAS)))
.thenReturn(TEST_EXTRAS_RESULT);
res = op.apply(provider, null, 0);
assertEquals(TEST_EXTRAS_RESULT, res.extras);
}
@Test
public void testBackReferenceSelection() throws Exception {
op = ContentProviderOperation.newDelete(TEST_URI)
.withSelection(null, new String[] { "a", "b", "c", "d" })
.withSelectionBackReference(0, 0)
.withSelectionBackReference(1, 1)
.withSelectionBackReference(2, 2, "test_result")
.build();
final String[] res = op.resolveSelectionArgsBackReferences(TEST_RESULTS,
TEST_RESULTS.length);
assertEquals("12", res[0]);
assertEquals("84", res[1]);
assertEquals("42", res[2]);
assertEquals("d", res[3]);
}
@Test
public void testBackReferenceValue() throws Exception {
final ContentValues values = new ContentValues();
values.put("a", "a");
values.put("b", "b");
values.put("c", "c");
values.put("d", "d");
op = ContentProviderOperation.newUpdate(TEST_URI)
.withValues(values)
.withValueBackReference("a", 0)
.withValueBackReference("b", 1)
.withValueBackReference("c", 2, "test_result")
.build();
final ContentValues res = op.resolveValueBackReferences(TEST_RESULTS,
TEST_RESULTS.length);
assertEquals(12L, (long) res.get("a"));
assertEquals(84L, (long) res.get("b"));
assertEquals("42", res.get("c"));
assertEquals("d", res.get("d"));
}
@Test
public void testBackReferenceExtra() throws Exception {
final Bundle extras = new Bundle();
extras.putString("a", "a");
extras.putString("b", "b");
extras.putString("c", "c");
extras.putString("d", "d");
op = ContentProviderOperation.newCall(TEST_URI, TEST_METHOD, TEST_ARG)
.withExtras(extras)
.withExtraBackReference("a", 0)
.withExtraBackReference("b", 1)
.withExtraBackReference("c", 2, "test_result")
.build();
final Bundle res = op.resolveExtrasBackReferences(TEST_RESULTS,
TEST_RESULTS.length);
assertEquals(12L, (long) res.get("a"));
assertEquals(84L, (long) res.get("b"));
assertEquals("42", res.get("c"));
assertEquals("d", res.get("d"));
}
@Test
public void testExceptionAllowed() throws Exception {
op = ContentProviderOperation.newCall(TEST_URI, TEST_METHOD, TEST_ARG)
.withExtras(TEST_EXTRAS)
.withExceptionAllowed(true)
.build();
assertTrue(op.isExceptionAllowed());
when(provider.call(eq(TEST_URI.getAuthority()), eq(TEST_METHOD),
eq(TEST_ARG), eqBundle(TEST_EXTRAS)))
.thenThrow(new IllegalArgumentException());
res = op.apply(provider, null, 0);
assertTrue((res.exception instanceof IllegalArgumentException));
}
@Test
public void testLayering() throws Exception {
op = ContentProviderOperation.newAssertQuery(TEST_URI)
.withSelection(TEST_SELECTION, TEST_SELECTION_ARGS)
.withExtras(TEST_EXTRAS)
.withExtra("test_key", "other_extra")
.withValues(TEST_VALUES)
.withValue("test_key", "other_value")
.build();
assertEquals("other_extra", op.resolveExtrasBackReferences(null, 0).getString("test_key"));
assertEquals("other_value", op.resolveValueBackReferences(null, 0).getAsString("test_key"));
}
public static Bundle eqBundle(Bundle bundle) {
return ArgumentMatchers.argThat((other) -> {
// Ideally we'd use something like Bundle.kindofEquals() here, but
// it doesn't perform deep equals inside String[] values, so the
// best we can do is a simple string equality check
return Objects.equals(bundle.toString(), other.toString());
});
}
}