package org.fdroid.fdroid.data;
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.TestUtils;
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
import org.fdroid.fdroid.mock.MockApk;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowContentResolver;
import java.util.ArrayList;
import java.util.List;
import static org.fdroid.fdroid.Assert.assertInvalidUri;
import static org.fdroid.fdroid.Assert.assertValidUri;
// TODO: Use sdk=24 when Robolectric supports this
@Config(constants = BuildConfig.class, sdk = 23)
@RunWith(RobolectricGradleTestRunner.class)
public class ProviderUriTests {
private ShadowContentResolver resolver;
@Before
public void setup() {
resolver = Shadows.shadowOf(RuntimeEnvironment.application.getContentResolver());
}
@After
public void teardown() {
FDroidProvider.clearDbHelperSingleton();
}
@Test
public void invalidInstalledAppProviderUris() {
ShadowContentResolver.registerProvider(InstalledAppProvider.getAuthority(), new InstalledAppProvider());
assertInvalidUri(resolver, InstalledAppProvider.getAuthority());
assertInvalidUri(resolver, "blah");
}
@Test
public void validInstalledAppProviderUris() {
ShadowContentResolver.registerProvider(InstalledAppProvider.getAuthority(), new InstalledAppProvider());
String[] projection = new String[] {InstalledAppTable.Cols._ID};
assertValidUri(resolver, InstalledAppProvider.getContentUri(), projection);
assertValidUri(resolver, InstalledAppProvider.getAppUri("org.example.app"), projection);
assertValidUri(resolver, InstalledAppProvider.getSearchUri("blah"), projection);
assertValidUri(resolver, InstalledAppProvider.getSearchUri("\"blah\""), projection);
assertValidUri(resolver, InstalledAppProvider.getSearchUri("blah & sneh"), projection);
assertValidUri(resolver, InstalledAppProvider.getSearchUri("http://blah.example.com?sneh=\"sneh\""), projection);
}
@Test
public void invalidRepoProviderUris() {
ShadowContentResolver.registerProvider(RepoProvider.getAuthority(), new RepoProvider());
assertInvalidUri(resolver, RepoProvider.getAuthority());
assertInvalidUri(resolver, "blah");
}
@Test
public void validRepoProviderUris() {
ShadowContentResolver.registerProvider(RepoProvider.getAuthority(), new RepoProvider());
String[] projection = new String[] {Schema.RepoTable.Cols._ID};
assertValidUri(resolver, RepoProvider.getContentUri(), projection);
assertValidUri(resolver, RepoProvider.getContentUri(10000L), projection);
assertValidUri(resolver, RepoProvider.allExceptSwapUri(), projection);
}
@Test
public void invalidAppProviderUris() {
ShadowContentResolver.registerProvider(AppProvider.getAuthority(), new AppProvider());
assertInvalidUri(resolver, AppProvider.getAuthority());
assertInvalidUri(resolver, "blah");
}
@Test
public void validAppProviderUris() {
ShadowContentResolver.registerProvider(AppProvider.getAuthority(), new AppProvider());
String[] projection = new String[] {Schema.AppMetadataTable.Cols._ID};
assertValidUri(resolver, AppProvider.getContentUri(), "content://org.fdroid.fdroid.data.AppProvider", projection);
assertValidUri(resolver, AppProvider.getSearchUri("'searching!'"), "content://org.fdroid.fdroid.data.AppProvider/search/'searching!'", projection);
assertValidUri(resolver, AppProvider.getSearchUri("/"), "content://org.fdroid.fdroid.data.AppProvider/search/%2F", projection);
assertValidUri(resolver, AppProvider.getSearchUri(""), "content://org.fdroid.fdroid.data.AppProvider", projection);
assertValidUri(resolver, AppProvider.getSearchUri(null), "content://org.fdroid.fdroid.data.AppProvider", projection);
assertValidUri(resolver, AppProvider.getInstalledUri(), "content://org.fdroid.fdroid.data.AppProvider/installed", projection);
assertValidUri(resolver, AppProvider.getCanUpdateUri(), "content://org.fdroid.fdroid.data.AppProvider/canUpdate", projection);
App app = new App();
app.repoId = 1;
app.packageName = "org.fdroid.fdroid";
assertValidUri(resolver, AppProvider.getSpecificAppUri(app.packageName, app.repoId), "content://org.fdroid.fdroid.data.AppProvider/app/1/org.fdroid.fdroid", projection);
}
@Test
public void validTempAppProviderUris() {
ShadowContentResolver.registerProvider(TempAppProvider.getAuthority(), new TempAppProvider());
String[] projection = new String[]{Schema.AppMetadataTable.Cols._ID};
// Required so that the `assertValidUri` calls below will indeed have a real temp_fdroid_app
// table to query.
TempAppProvider.Helper.init(TestUtils.createContextWithContentResolver(resolver));
List<String> packageNames = new ArrayList<>(2);
packageNames.add("org.fdroid.fdroid");
packageNames.add("com.example.com");
assertValidUri(resolver, TempAppProvider.getAppsUri(packageNames, 1), "content://org.fdroid.fdroid.data.TempAppProvider/apps/1/org.fdroid.fdroid%2Ccom.example.com", projection);
assertValidUri(resolver, TempAppProvider.getContentUri(), "content://org.fdroid.fdroid.data.TempAppProvider", projection);
}
@Test
public void invalidApkProviderUris() {
ShadowContentResolver.registerProvider(ApkProvider.getAuthority(), new ApkProvider());
assertInvalidUri(resolver, ApkProvider.getAuthority());
assertInvalidUri(resolver, "blah");
}
@Test
public void validApkProviderUris() {
ShadowContentResolver.registerProvider(ApkProvider.getAuthority(), new ApkProvider());
String[] projection = new String[] {Schema.ApkTable.Cols._ID};
List<Apk> apks = new ArrayList<>(10);
for (int i = 0; i < 10; i++) {
apks.add(new MockApk("com.example." + i, i));
}
assertValidUri(resolver, ApkProvider.getContentUri(), "content://org.fdroid.fdroid.data.ApkProvider", projection);
assertValidUri(resolver, ApkProvider.getAppUri("org.fdroid.fdroid"), "content://org.fdroid.fdroid.data.ApkProvider/app/org.fdroid.fdroid", projection);
assertValidUri(resolver, ApkProvider.getApkFromAnyRepoUri(new MockApk("org.fdroid.fdroid", 100)), "content://org.fdroid.fdroid.data.ApkProvider/apk-any-repo/100/org.fdroid.fdroid", projection);
assertValidUri(resolver, ApkProvider.getContentUri(apks), projection);
assertValidUri(resolver, ApkProvider.getApkFromAnyRepoUri("org.fdroid.fdroid", 100), "content://org.fdroid.fdroid.data.ApkProvider/apk-any-repo/100/org.fdroid.fdroid", projection);
assertValidUri(resolver, ApkProvider.getRepoUri(1000), "content://org.fdroid.fdroid.data.ApkProvider/repo/1000", projection);
}
@Test(expected = IllegalArgumentException.class)
public void invalidApkUrisWithTooManyApks() {
String[] projection = Schema.ApkTable.Cols.ALL;
List<Apk> manyApks = new ArrayList<>(ApkProvider.MAX_APKS_TO_QUERY - 5);
for (int i = 0; i < ApkProvider.MAX_APKS_TO_QUERY - 1; i++) {
manyApks.add(new MockApk("com.example." + i, i));
}
assertValidUri(resolver, ApkProvider.getContentUri(manyApks), projection);
manyApks.add(new MockApk("org.fdroid.fdroid.1", 1));
manyApks.add(new MockApk("org.fdroid.fdroid.2", 2));
// Technically, it is a valid URI, because it doesn't
// throw an UnsupportedOperationException. However it
// is still not okay (we run out of bindable parameters
// in the sqlite query.
assertValidUri(resolver, ApkProvider.getContentUri(manyApks), projection);
}
}