/*
* Copyright (C) 2016 Blue Jay Wireless
* Copyright (C) 2014-2016 Hans-Christoph Steiner <hans@eds.org>
* Copyright (C) 2014-2016 Peter Serwylo <peter@serwylo.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
package org.fdroid.fdroid.data;
import android.app.Application;
import android.content.ContentValues;
import android.net.Uri;
import android.support.annotation.Nullable;
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.R;
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.data.Schema.RepoTable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
// TODO: Use sdk=24 when Robolectric supports this
@Config(constants = BuildConfig.class, application = Application.class, sdk = 23)
@RunWith(RobolectricGradleTestRunner.class)
public class RepoProviderTest extends FDroidProviderTest {
private static final String[] COLS = RepoTable.Cols.ALL;
@Test
public void findByUrl() {
Repo fdroidRepo = RepoProvider.Helper.findByAddress(context, "https://f-droid.org/repo");
Repo fdroidArchiveRepo = RepoProvider.Helper.findByAddress(context, "https://f-droid.org/archive");
String[] noRepos = {
"https://not-a-repo.example.com",
"https://f-droid.org",
"https://f-droid.org/",
};
for (String url : noRepos) {
assertNull(RepoProvider.Helper.findByUrl(context, Uri.parse(url), COLS));
}
String[] fdroidRepoUrls = {
"https://f-droid.org/repo/index.jar",
"https://f-droid.org/repo/index.jar?random-junk-in-query=yes",
"https://f-droid.org/repo/index.jar?random-junk-in-query=yes&more-junk",
"https://f-droid.org/repo/icons/org.fdroid.fdroid.100.png",
"https://f-droid.org/repo/icons-640/org.fdroid.fdroid.100.png",
};
assertUrlsBelongToRepo(fdroidRepoUrls, fdroidRepo);
String[] fdroidArchiveUrls = {
"https://f-droid.org/archive/index.jar",
"https://f-droid.org/archive/index.jar?random-junk-in-query=yes",
"https://f-droid.org/archive/index.jar?random-junk-in-query=yes&more-junk",
"https://f-droid.org/archive/icons/org.fdroid.fdroid.100.png",
"https://f-droid.org/archive/icons-640/org.fdroid.fdroid.100.png",
};
assertUrlsBelongToRepo(fdroidArchiveUrls, fdroidArchiveRepo);
}
private void assertUrlsBelongToRepo(String[] urls, Repo expectedRepo) {
for (String url : urls) {
Repo actualRepo = RepoProvider.Helper.findByUrl(context, Uri.parse(url), COLS);
assertNotNull("No repo matching URL " + url, actualRepo);
assertEquals("Invalid repo for URL [" + url + "]. Expected [" + expectedRepo.address + "] but got [" + actualRepo.address + "]", expectedRepo.id, actualRepo.id);
}
}
/**
* The {@link DBHelper} class populates the default repos when it first creates a database.
* The names/URLs/signing certificates for these repos are all hard coded in the source/res.
*/
@Test
public void defaultRepos() {
List<Repo> defaultRepos = RepoProvider.Helper.all(context);
assertEquals(defaultRepos.size(), 4); // based on app/src/main/res/default_repo.xml
String[] reposFromXml = context.getResources().getStringArray(R.array.default_repos);
if (reposFromXml.length % DBHelper.REPO_XML_ARG_COUNT != 0) {
throw new IllegalArgumentException(
"default_repo.xml array does not have the right number of elements");
}
for (int i = 0; i < reposFromXml.length / DBHelper.REPO_XML_ARG_COUNT; i++) {
int offset = i * DBHelper.REPO_XML_ARG_COUNT;
assertRepo(
defaultRepos.get(i),
reposFromXml[offset + 1], // address
reposFromXml[offset + 2], // description
Utils.calcFingerprint(reposFromXml[offset + 7]), // pubkey
reposFromXml[offset] // name
);
}
}
@Test
public void canAddRepo() {
assertEquals(4, RepoProvider.Helper.all(context).size());
Repo mock1 = insertRepo(
"https://mock-repo-1.example.com/fdroid/repo",
"Just a made up repo",
"ABCDEF1234567890",
"Mock Repo 1"
);
Repo mock2 = insertRepo(
"http://mock-repo-2.example.com/fdroid/repo",
"Mock repo without a name",
"0123456789ABCDEF"
);
assertEquals(6, RepoProvider.Helper.all(context).size());
assertRepo(
mock1,
"https://mock-repo-1.example.com/fdroid/repo",
"Just a made up repo",
"ABCDEF1234567890",
"Mock Repo 1"
);
assertRepo(
mock2,
"http://mock-repo-2.example.com/fdroid/repo",
"Mock repo without a name",
"0123456789ABCDEF",
"mock-repo-2.example.com/fdroid/repo"
);
}
private static void assertRepo(Repo actualRepo, String expectedAddress, String expectedDescription,
String expectedFingerprint, String expectedName) {
assertEquals(expectedAddress, actualRepo.address);
assertEquals(expectedDescription, actualRepo.description);
assertEquals(expectedFingerprint, actualRepo.fingerprint);
assertEquals(expectedName, actualRepo.name);
}
@Test
public void canDeleteRepo() {
Repo mock1 = insertRepo(
"https://mock-repo-1.example.com/fdroid/repo",
"Just a made up repo",
"ABCDEF1234567890",
"Mock Repo 1"
);
Repo mock2 = insertRepo(
"http://mock-repo-2.example.com/fdroid/repo",
"Mock repo without a name",
"0123456789ABCDEF"
);
List<Repo> beforeDelete = RepoProvider.Helper.all(context);
assertEquals(6, beforeDelete.size()); // Expect six repos, because of the four default ones.
assertEquals(mock1.id, beforeDelete.get(4).id);
assertEquals(mock2.id, beforeDelete.get(5).id);
RepoProvider.Helper.remove(context, mock1.getId());
List<Repo> afterDelete = RepoProvider.Helper.all(context);
assertEquals(5, afterDelete.size());
assertEquals(mock2.id, afterDelete.get(4).id);
}
protected Repo insertRepo(String address, String description, String fingerprint) {
return insertRepo(address, description, fingerprint, null);
}
protected Repo insertRepo(String address, String description, String fingerprint, @Nullable String name) {
ContentValues values = new ContentValues();
values.put(RepoTable.Cols.ADDRESS, address);
values.put(RepoTable.Cols.DESCRIPTION, description);
values.put(RepoTable.Cols.FINGERPRINT, fingerprint);
values.put(RepoTable.Cols.NAME, name);
RepoProvider.Helper.insert(context, values);
return RepoProvider.Helper.findByAddress(context, address);
}
}