Merge branch 'jsonLoader' into 'master'
* jsonLoader: (28 commits) fix checkstyle complaints force DBHelperTest.canAddAdditionalRepos() to run on CI clean up whitespace in repo descriptions rename parseXmlRepos to parseAdditionalReposXml rename item lists to repoItems rename defaultReposFile to additionalReposFile separate defaultRepos from initialRepos, which includes additionalRepos rename REPO_XML_ARG_COUNT to REPO_XML_ITEM_COUNT fix additional_repos.xml handling to be properly parsed move comments to javadoc priority is NOT ignored, just additional_repos.xml is not allowed to set fix DBHelperTest to actually load and parse additional_repos.xml changed the tests: now testing only DBHelper.parseXmlRepos() removed stars from imports finished additional repos test some minor style changes minor style changes implemented creating xml file on oem partition; not sure whether it works cause gradle runs forever (>20min) started implementing test removed priority from additional_repos.xml ... closes fdroid/fdroidclient!705
This commit is contained in:
commit
255fe37dc1
@ -42,8 +42,17 @@ import org.fdroid.fdroid.data.Schema.CatJoinTable;
|
||||
import org.fdroid.fdroid.data.Schema.InstalledAppTable;
|
||||
import org.fdroid.fdroid.data.Schema.PackageTable;
|
||||
import org.fdroid.fdroid.data.Schema.RepoTable;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlPullParserFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -56,8 +65,7 @@ import java.util.List;
|
||||
public class DBHelper extends SQLiteOpenHelper {
|
||||
|
||||
private static final String TAG = "DBHelper";
|
||||
|
||||
public static final int REPO_XML_ARG_COUNT = 8;
|
||||
public static final int REPO_XML_ITEM_COUNT = 8;
|
||||
|
||||
private static DBHelper instance;
|
||||
private static final String DATABASE_NAME = "fdroid";
|
||||
@ -257,27 +265,135 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
db.execSQL(CREATE_TABLE_APK_ANTI_FEATURE_JOIN);
|
||||
ensureIndexes(db);
|
||||
|
||||
String[] defaultRepos = context.getResources().getStringArray(R.array.default_repos);
|
||||
if (defaultRepos.length % 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 < defaultRepos.length / REPO_XML_ARG_COUNT; i++) {
|
||||
int offset = i * REPO_XML_ARG_COUNT;
|
||||
List<String> initialRepos = DBHelper.loadInitialRepos(context);
|
||||
|
||||
for (int i = 0; i < initialRepos.size(); i += REPO_XML_ITEM_COUNT) {
|
||||
insertRepo(
|
||||
db,
|
||||
defaultRepos[offset], // name
|
||||
defaultRepos[offset + 1], // address
|
||||
defaultRepos[offset + 2], // description
|
||||
defaultRepos[offset + 3], // version
|
||||
defaultRepos[offset + 4], // enabled
|
||||
defaultRepos[offset + 5], // priority
|
||||
defaultRepos[offset + 6], // pushRequests
|
||||
defaultRepos[offset + 7] // pubkey
|
||||
initialRepos.get(i), // name
|
||||
initialRepos.get(i + 1), // address
|
||||
initialRepos.get(i + 2), // description
|
||||
initialRepos.get(i + 3), // version
|
||||
initialRepos.get(i + 4), // enabled
|
||||
initialRepos.get(i + 5), // priority
|
||||
initialRepos.get(i + 6), // pushRequests
|
||||
initialRepos.get(i + 7) // pubkey
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Additional Repos first, then Default Repos. This way, Default
|
||||
* Repos will be shown after the OEM-added ones on the Manage Repos
|
||||
* screen. This throws a hard {@code Exception} on parse errors since
|
||||
* Default Repos are built into the APK. So it should fail as hard and fast
|
||||
* as possible so the developer catches the problem.
|
||||
* <p>
|
||||
* Additional Repos ({@code additional_repos.xml}) come from the ROM,
|
||||
* while Default Repos ({@code default_repos.xml} is built into the APK.
|
||||
* <p>
|
||||
* This also cleans up the whitespace in the description item, since the
|
||||
* XML parsing will include the linefeeds and indenting in the description.
|
||||
*/
|
||||
public static List<String> loadInitialRepos(Context context) throws IllegalArgumentException {
|
||||
String packageName = context.getPackageName();
|
||||
List<String> initialRepos = DBHelper.loadAdditionalRepos(packageName);
|
||||
List<String> defaultRepos = Arrays.asList(context.getResources().getStringArray(R.array.default_repos));
|
||||
initialRepos.addAll(defaultRepos);
|
||||
|
||||
if (initialRepos.size() % REPO_XML_ITEM_COUNT != 0) {
|
||||
throw new IllegalArgumentException("default_repos.xml has wrong item count: " +
|
||||
initialRepos.size() + " % REPO_XML_ARG_COUNT(" + REPO_XML_ITEM_COUNT + ") != 0");
|
||||
}
|
||||
|
||||
final int descriptionIndex = 2;
|
||||
for (int i = descriptionIndex; i < initialRepos.size(); i += REPO_XML_ITEM_COUNT) {
|
||||
String description = initialRepos.get(i);
|
||||
initialRepos.set(i, description.replaceAll("\\s+", " "));
|
||||
}
|
||||
|
||||
return initialRepos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for additional, initial repositories from the device's filesystem.
|
||||
* These can be added as part of the ROM ({@code /system} or included later
|
||||
* by vendors/OEMs ({@code /vendor}, {@code /odm}, {@code /oem}). These are
|
||||
* always added at a lower priority than the repos embedded in the APK via
|
||||
* {@code default_repos.xml}.
|
||||
* <p>
|
||||
* ROM has the lowest priority, then Vendor, ODM, and OEM.
|
||||
*/
|
||||
private static List<String> loadAdditionalRepos(String packageName) {
|
||||
List<String> repoItems = new LinkedList<>();
|
||||
for (String root : Arrays.asList("/system", "/vendor", "/odm", "/oem")) {
|
||||
File additionalReposFile = new File(root + "/etc/" + packageName + "/additional_repos.xml");
|
||||
try {
|
||||
if (additionalReposFile.isFile()) {
|
||||
repoItems.addAll(DBHelper.parseAdditionalReposXml(additionalReposFile));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error loading " + additionalReposFile + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
return repoItems;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse {@code additional_repos.xml} into a list of items. Walk through
|
||||
* all TEXT pieces of the xml file and put them into a single list of repo
|
||||
* elements. Each repo is defined as eight elements in that list.
|
||||
* {@code additional_repos.xml} has seven elements per repo because it is
|
||||
* not allowed to set the priority since that would give it the power to
|
||||
* override {@code default_repos.xml}.
|
||||
*/
|
||||
public static List<String> parseAdditionalReposXml(File additionalReposFile)
|
||||
throws IOException, XmlPullParserException {
|
||||
List<String> repoItems = new LinkedList<>();
|
||||
InputStream xmlInputStream = new FileInputStream(additionalReposFile);
|
||||
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
|
||||
factory.setNamespaceAware(true);
|
||||
XmlPullParser parser = factory.newPullParser();
|
||||
parser.setInput(xmlInputStream, "UTF-8");
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
boolean isItem = false;
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
String tagname = parser.getName();
|
||||
switch (eventType) {
|
||||
case XmlPullParser.START_TAG:
|
||||
if ("item".equals(tagname)) {
|
||||
isItem = true;
|
||||
}
|
||||
break;
|
||||
case XmlPullParser.END_TAG:
|
||||
isItem = false;
|
||||
break;
|
||||
case XmlPullParser.TEXT:
|
||||
if (isItem) {
|
||||
repoItems.add(parser.getText());
|
||||
}
|
||||
break;
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
xmlInputStream.close();
|
||||
|
||||
final int priorityIndex = 5;
|
||||
for (int i = priorityIndex; i < repoItems.size(); i += REPO_XML_ITEM_COUNT) {
|
||||
repoItems.add(i, "0");
|
||||
}
|
||||
|
||||
if (repoItems.size() % REPO_XML_ITEM_COUNT == 0) {
|
||||
return repoItems;
|
||||
}
|
||||
|
||||
Log.e(TAG, "Ignoring " + additionalReposFile + ", wrong number of items: "
|
||||
+ repoItems.size() + " % " + (REPO_XML_ITEM_COUNT - 1) + " != 0");
|
||||
return new LinkedList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
resetTransient(context);
|
||||
@ -600,10 +716,10 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
String[] defaultRepos = context.getResources().getStringArray(R.array.default_repos);
|
||||
String fdroidPubKey = defaultRepos[7];
|
||||
String fdroidAddress = defaultRepos[1];
|
||||
String fdroidArchiveAddress = defaultRepos[REPO_XML_ARG_COUNT + 1];
|
||||
String gpPubKey = defaultRepos[REPO_XML_ARG_COUNT * 2 + 7];
|
||||
String gpAddress = defaultRepos[REPO_XML_ARG_COUNT * 2 + 1];
|
||||
String gpArchiveAddress = defaultRepos[REPO_XML_ARG_COUNT * 3 + 1];
|
||||
String fdroidArchiveAddress = defaultRepos[REPO_XML_ITEM_COUNT + 1];
|
||||
String gpPubKey = defaultRepos[REPO_XML_ITEM_COUNT * 2 + 7];
|
||||
String gpAddress = defaultRepos[REPO_XML_ITEM_COUNT * 2 + 1];
|
||||
String gpArchiveAddress = defaultRepos[REPO_XML_ITEM_COUNT * 3 + 1];
|
||||
|
||||
updateRepoPriority(db, fdroidPubKey, fdroidAddress, 1);
|
||||
updateRepoPriority(db, fdroidPubKey, fdroidArchiveAddress, 2);
|
||||
@ -854,8 +970,8 @@ public class DBHelper extends SQLiteOpenHelper {
|
||||
}
|
||||
|
||||
String[] defaultRepos = context.getResources().getStringArray(R.array.default_repos);
|
||||
for (int i = 0; i < defaultRepos.length / REPO_XML_ARG_COUNT; i++) {
|
||||
int offset = i * REPO_XML_ARG_COUNT;
|
||||
for (int i = 0; i < defaultRepos.length / REPO_XML_ITEM_COUNT; i++) {
|
||||
int offset = i * REPO_XML_ITEM_COUNT;
|
||||
insertNameAndDescription(db,
|
||||
defaultRepos[offset], // name
|
||||
defaultRepos[offset + 1], // address
|
||||
|
314
app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java
Normal file
314
app/src/test/java/org/fdroid/fdroid/data/DBHelperTest.java
Normal file
@ -0,0 +1,314 @@
|
||||
package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.fdroid.fdroid.TestUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DBHelperTest {
|
||||
static final String TAG = "DBHelperTest";
|
||||
|
||||
private List<String> getReposFromXml(String xml) throws IOException, XmlPullParserException {
|
||||
File additionalReposXml = File.createTempFile("." + context.getPackageName() + "-DBHelperTest_",
|
||||
"_additional_repos.xml");
|
||||
Log.i(TAG, "additionalReposXml: " + additionalReposXml);
|
||||
|
||||
FileOutputStream outputStream = new FileOutputStream(additionalReposXml);
|
||||
outputStream.write(xml.getBytes());
|
||||
outputStream.close();
|
||||
|
||||
// Now parse that xml file
|
||||
return DBHelper.parseAdditionalReposXml(additionalReposXml);
|
||||
}
|
||||
|
||||
protected Context context;
|
||||
|
||||
@Before
|
||||
public final void setupBase() {
|
||||
context = InstrumentationRegistry.getContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseAdditionalReposXmlAllOneLineTest() throws IOException, XmlPullParserException {
|
||||
String oneRepoXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
|
||||
"<resources>" +
|
||||
"<string-array name=\"default_repos\">\n" +
|
||||
"<!-- name -->" +
|
||||
"<item>F-Droid</item>" +
|
||||
"<!-- address -->" +
|
||||
"<item>https://f-droid.org/repo</item>" +
|
||||
"<!-- description -->" +
|
||||
"<item>The official F-Droid repository. Applications in this repository are mostly built" +
|
||||
"directory from the source code. Some are official binaries built by the original" +
|
||||
"application developers - these will be replaced by source-built versions over time." +
|
||||
"</item>" +
|
||||
"<!-- version -->" +
|
||||
"<item>13</item>" +
|
||||
"<!-- enabled -->" +
|
||||
"<item>1</item>" +
|
||||
"<!-- push requests -->" +
|
||||
"<item>ignore</item>" +
|
||||
"<!-- pubkey -->" +
|
||||
"<item>" +
|
||||
"3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b30090603550406130255" +
|
||||
"</item>" +
|
||||
"</string-array>" +
|
||||
"</resources>";
|
||||
List<String> repos = getReposFromXml(oneRepoXml);
|
||||
assertEquals("Should contain one repo's worth of items", DBHelper.REPO_XML_ITEM_COUNT, repos.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseAdditionalReposXmlIncludedPriorityTest() throws IOException, XmlPullParserException {
|
||||
String wrongXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
|
||||
"<resources>" +
|
||||
"<string-array name=\"default_repos\">\n" +
|
||||
"<!-- name -->" +
|
||||
"<item>F-Droid</item>" +
|
||||
"<!-- address -->" +
|
||||
"<item>https://f-droid.org/repo</item>" +
|
||||
"<!-- description -->" +
|
||||
"<item>The official F-Droid repository. Applications in this repository are mostly built" +
|
||||
"directory from the source code. Some are official binaries built by the original" +
|
||||
"application developers - these will be replaced by source-built versions over time." +
|
||||
"</item>" +
|
||||
"<!-- version -->" +
|
||||
"<item>13</item>" +
|
||||
"<!-- enabled -->" +
|
||||
"<item>1</item>" +
|
||||
"<!-- priority -->" +
|
||||
"<item>1</item>" +
|
||||
"<!-- push requests -->" +
|
||||
"<item>ignore</item>" +
|
||||
"<!-- pubkey -->" +
|
||||
"<item>" +
|
||||
"3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b3009060355040613025" +
|
||||
"</item>" +
|
||||
"</string-array>" +
|
||||
"</resources>";
|
||||
getReposFromXml(wrongXml);
|
||||
List<String> repos = getReposFromXml(wrongXml);
|
||||
assertEquals("Should be empty", 0, repos.size());
|
||||
}
|
||||
|
||||
@Test(expected = XmlPullParserException.class)
|
||||
public void parseAdditionalReposXmlDoubleTagTest() throws IOException, XmlPullParserException {
|
||||
String wrongXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
+ "<resources>"
|
||||
+ "<string-array name=\"additional_repos\">"
|
||||
+ "<!-- address -->"
|
||||
+ "<item><item>https://www.oem0.com/yeah/repo</item>"
|
||||
+ "<!-- description -->"
|
||||
+ "<item>I'm the first oem repo.</item>"
|
||||
+ "<!-- version -->"
|
||||
+ "<item>22</item>"
|
||||
+ "<!-- enabled -->"
|
||||
+ "<item>1</item>"
|
||||
+ "<!-- push requests -->"
|
||||
+ "<item>ignore</item>"
|
||||
+ "<!-- pubkey -->"
|
||||
+ "<item>fffff2313aaaaabcccc111</item>"
|
||||
+ "</string-array>"
|
||||
+ "</resources>";
|
||||
getReposFromXml(wrongXml);
|
||||
fail("Invalid xml read successfully --> Wrong");
|
||||
}
|
||||
|
||||
@Test(expected = XmlPullParserException.class)
|
||||
public void parseAdditionalReposXmlMissingStartTagTest() throws IOException, XmlPullParserException {
|
||||
String wrongXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
+ "<item>https://www.oem0.com/yeah/repo</item>"
|
||||
+ "<!-- description -->"
|
||||
+ "<item>I'm the first oem repo.</item>"
|
||||
+ "<!-- version -->"
|
||||
+ "<item>22</item>"
|
||||
+ "<!-- enabled -->"
|
||||
+ "<item>1</item>"
|
||||
+ "<!-- push requests -->"
|
||||
+ "<item>ignore</item>"
|
||||
+ "<!-- pubkey -->"
|
||||
+ "<item>fffff2313aaaaabcccc111</item>"
|
||||
+ "</string-array>"
|
||||
+ "</resources>";
|
||||
getReposFromXml(wrongXml);
|
||||
fail("Invalid xml read successfully --> Wrong");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseAdditionalReposXmlWrongCountTest() throws IOException, XmlPullParserException {
|
||||
String wrongXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
+ "<resources>"
|
||||
+ "<string-array name=\"default_repos\"><item>foo</item></string-array>"
|
||||
+ "</resources>";
|
||||
List<String> repos = getReposFromXml(wrongXml);
|
||||
assertEquals("Should be empty", 0, repos.size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse valid xml but make sure that only <item> tags are parsed
|
||||
*/
|
||||
@Test
|
||||
public void parseAdditionalReposXmlSloppyTest() throws IOException, XmlPullParserException {
|
||||
InputStream input = TestUtils.class.getClassLoader().getResourceAsStream("ugly_additional_repos.xml");
|
||||
String validXml = IOUtils.toString(input, "UTF-8");
|
||||
|
||||
List<String> repos = getReposFromXml(validXml);
|
||||
assertEquals(2 * DBHelper.REPO_XML_ITEM_COUNT, repos.size());
|
||||
assertEquals("Repo Name", repos.get(8));
|
||||
assertEquals("https://www.oem0.com/yeah/repo", repos.get(9));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void parseAdditionalReposXmlPositiveTest() throws IOException {
|
||||
InputStream input = TestUtils.class.getClassLoader().getResourceAsStream("additional_repos.xml");
|
||||
String reposXmlContent = IOUtils.toString(input, "UTF-8");
|
||||
|
||||
List<String> additionalRepos;
|
||||
try {
|
||||
additionalRepos = getReposFromXml(reposXmlContent);
|
||||
} catch (IOException io) {
|
||||
fail("IOException. Failed parsing xml string into repos.");
|
||||
return;
|
||||
} catch (XmlPullParserException xppe) {
|
||||
fail("XmlPullParserException. Failed parsing xml string into repos.");
|
||||
return;
|
||||
}
|
||||
|
||||
// We should have loaded these repos
|
||||
List<String> oem0 = Arrays.asList(
|
||||
"oem0Name",
|
||||
"https://www.oem0.com/yeah/repo",
|
||||
"I'm the first oem repo.",
|
||||
"22",
|
||||
"1",
|
||||
"0", // priority is inserted by DBHelper.parseAdditionalReposXml()
|
||||
"ignore",
|
||||
"fffff2313aaaaabcccc111");
|
||||
List<String> oem1 = Arrays.asList(
|
||||
"oem1MyNameIs",
|
||||
"https://www.mynameis.com/rapper/repo",
|
||||
"Who is the first repo?",
|
||||
"22",
|
||||
"0",
|
||||
"0", // priority is inserted by DBHelper.parseAdditionalReposXml()
|
||||
"ignore",
|
||||
"ddddddd2313aaaaabcccc111");
|
||||
List<String> shouldBeRepos = new LinkedList<>();
|
||||
shouldBeRepos.addAll(oem0);
|
||||
shouldBeRepos.addAll(oem1);
|
||||
|
||||
assertEquals(additionalRepos.size(), shouldBeRepos.size());
|
||||
for (int i = 0; i < additionalRepos.size(); i++) {
|
||||
assertEquals(shouldBeRepos.get(i), additionalRepos.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("LineLength")
|
||||
@Test
|
||||
public void canAddAdditionalRepos() throws IOException {
|
||||
File oemEtcDir = new File("/oem/etc");
|
||||
File oemEtcPackageDir = new File(oemEtcDir, context.getPackageName());
|
||||
if (!oemEtcPackageDir.canWrite() || !oemEtcDir.canWrite()) {
|
||||
if (oemEtcDir.canWrite() || new File("/").canWrite()) {
|
||||
oemEtcPackageDir.mkdirs();
|
||||
}
|
||||
if (TextUtils.isEmpty(System.getenv("CI")) && !oemEtcPackageDir.isDirectory()) {
|
||||
Log.e(TAG, "Cannot create " + oemEtcDir + ", skipping test!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
File additionalReposXmlFile = new File(oemEtcPackageDir, "additional_repos.xml");
|
||||
FileOutputStream outputStream = new FileOutputStream(additionalReposXmlFile);
|
||||
outputStream.write(("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
|
||||
+ "<resources>"
|
||||
+ "<string-array name=\"default_repos\">"
|
||||
+ "<!-- name -->"
|
||||
+ "<item>oem0Name</item>"
|
||||
+ "<!-- address -->"
|
||||
+ "<item>https://www.oem0.com/yeah/repo</item>"
|
||||
+ "<!-- description -->"
|
||||
+ "<item>I'm the first oem repo.</item>"
|
||||
+ "<!-- version -->"
|
||||
+ "<item>22</item>"
|
||||
+ "<!-- enabled -->"
|
||||
+ "<item>1</item>"
|
||||
+ "<!-- push requests -->"
|
||||
+ "<item>ignore</item>"
|
||||
+ "<!-- pubkey -->"
|
||||
+ "<item>fffff2313aaaaabcccc111</item>"
|
||||
|
||||
+ "<!-- name -->"
|
||||
+ "<item>oem1MyNameIs</item>"
|
||||
+ "<!-- address -->"
|
||||
+ "<item>https://www.mynameis.com/rapper/repo</item>"
|
||||
+ "<!-- description -->"
|
||||
+ "<item>Who is the first repo?</item>"
|
||||
+ "<!-- version -->"
|
||||
+ "<item>22</item>"
|
||||
+ "<!-- enabled -->"
|
||||
+ "<item>0</item>"
|
||||
+ "<!-- push requests -->"
|
||||
+ "<item>ignore</item>"
|
||||
+ "<!-- pubkey -->"
|
||||
+ "<item>ddddddd2313aaaaabcccc111</item>"
|
||||
+ "</string-array>"
|
||||
+ "</resources>").getBytes());
|
||||
outputStream.close();
|
||||
|
||||
try {
|
||||
List<String> initialRepos = DBHelper.loadInitialRepos(context);
|
||||
|
||||
// Construct the repos that we should have loaded
|
||||
List<String> oem0 = Arrays.asList("oem0Name", "https://www.oem0.com/yeah/repo", "I'm the first oem repo.",
|
||||
"22", "1", "0", "ignore", "fffff2313aaaaabcccc111");
|
||||
List<String> oem1 = Arrays.asList("oem1MyNameIs", "https://www.mynameis.com/rapper/repo", "Who is the first repo?",
|
||||
"22", "0", "0", "ignore", "ddddddd2313aaaaabcccc111");
|
||||
List<String> fdroid0 = Arrays.asList("F-Droid", "https://f-droid.org/repo", "The official F-Droid repository. Applications in this repository are mostly built directory from the source code. Some are official binaries built by the original application developers - these will be replaced by source-built versions over time.",
|
||||
"13", "1", "1", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef");
|
||||
List<String> fdroid1 = Arrays.asList("F-Droid Archive", "https://f-droid.org/archive", "The archive repository of the F-Droid client. This contains older versions of applications from the main repository.",
|
||||
"13", "0", "2", "ignore", "3082035e30820246a00302010202044c49cd00300d06092a864886f70d01010505003071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b73301e170d3130303732333137313032345a170d3337313230383137313032345a3071310b300906035504061302554b3110300e06035504081307556e6b6e6f776e3111300f0603550407130857657468657262793110300e060355040a1307556e6b6e6f776e3110300e060355040b1307556e6b6e6f776e311930170603550403131043696172616e2047756c746e69656b7330820122300d06092a864886f70d01010105000382010f003082010a028201010096d075e47c014e7822c89fd67f795d23203e2a8843f53ba4e6b1bf5f2fd0e225938267cfcae7fbf4fe596346afbaf4070fdb91f66fbcdf2348a3d92430502824f80517b156fab00809bdc8e631bfa9afd42d9045ab5fd6d28d9e140afc1300917b19b7c6c4df4a494cf1f7cb4a63c80d734265d735af9e4f09455f427aa65a53563f87b336ca2c19d244fcbba617ba0b19e56ed34afe0b253ab91e2fdb1271f1b9e3c3232027ed8862a112f0706e234cf236914b939bcf959821ecb2a6c18057e070de3428046d94b175e1d89bd795e535499a091f5bc65a79d539a8d43891ec504058acb28c08393b5718b57600a211e803f4a634e5c57f25b9b8c4422c6fd90203010001300d06092a864886f70d0101050500038201010008e4ef699e9807677ff56753da73efb2390d5ae2c17e4db691d5df7a7b60fc071ae509c5414be7d5da74df2811e83d3668c4a0b1abc84b9fa7d96b4cdf30bba68517ad2a93e233b042972ac0553a4801c9ebe07bf57ebe9a3b3d6d663965260e50f3b8f46db0531761e60340a2bddc3426098397fda54044a17e5244549f9869b460ca5e6e216b6f6a2db0580b480ca2afe6ec6b46eedacfa4aa45038809ece0c5978653d6c85f678e7f5a2156d1bedd8117751e64a4b0dcd140f3040b021821a8d93aed8d01ba36db6c82372211fed714d9a32607038cdfd565bd529ffc637212aaa2c224ef22b603eccefb5bf1e085c191d4b24fe742b17ab3f55d4e6f05ef");
|
||||
List<String> fdroid2 = Arrays.asList("Guardian Project", "https://guardianproject.info/fdroid/repo", "The official app repository of The Guardian Project. Applications in this repository are official binaries build by the original application developers and signed by the same key as the APKs that are released in the Google Play store.",
|
||||
"13", "0", "3", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f");
|
||||
List<String> fdroid3 = Arrays.asList("Guardian Project Archive", "https://guardianproject.info/fdroid/archive", "The official repository of The Guardian Project apps for use with F-Droid client. This contains older versions of applications from the main repository.",
|
||||
"13", "0", "4", "ignore", "308205d8308203c0020900a397b4da7ecda034300d06092a864886f70d01010505003081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f301e170d3134303632363139333931385a170d3431313131303139333931385a3081ad310b30090603550406130255533111300f06035504080c084e657720596f726b3111300f06035504070c084e657720596f726b31143012060355040b0c0b4644726f6964205265706f31193017060355040a0c10477561726469616e2050726f6a656374311d301b06035504030c14677561726469616e70726f6a6563742e696e666f3128302606092a864886f70d0109011619726f6f7440677561726469616e70726f6a6563742e696e666f30820222300d06092a864886f70d01010105000382020f003082020a0282020100b3cd79121b9b883843be3c4482e320809106b0a23755f1dd3c7f46f7d315d7bb2e943486d61fc7c811b9294dcc6b5baac4340f8db2b0d5e14749e7f35e1fc211fdbc1071b38b4753db201c314811bef885bd8921ad86facd6cc3b8f74d30a0b6e2e6e576f906e9581ef23d9c03e926e06d1f033f28bd1e21cfa6a0e3ff5c9d8246cf108d82b488b9fdd55d7de7ebb6a7f64b19e0d6b2ab1380a6f9d42361770d1956701a7f80e2de568acd0bb4527324b1e0973e89595d91c8cc102d9248525ae092e2c9b69f7414f724195b81427f28b1d3d09a51acfe354387915fd9521e8c890c125fc41a12bf34d2a1b304067ab7251e0e9ef41833ce109e76963b0b256395b16b886bca21b831f1408f836146019e7908829e716e72b81006610a2af08301de5d067c9e114a1e5759db8a6be6a3cc2806bcfe6fafd41b5bc9ddddb3dc33d6f605b1ca7d8a9e0ecdd6390d38906649e68a90a717bea80fa220170eea0c86fc78a7e10dac7b74b8e62045a3ecca54e035281fdc9fe5920a855fde3c0be522e3aef0c087524f13d973dff3768158b01a5800a060c06b451ec98d627dd052eda804d0556f60dbc490d94e6e9dea62ffcafb5beffbd9fc38fb2f0d7050004fe56b4dda0a27bc47554e1e0a7d764e17622e71f83a475db286bc7862deee1327e2028955d978272ea76bf0b88e70a18621aba59ff0c5993ef5f0e5d6b6b98e68b70203010001300d06092a864886f70d0101050500038202010079c79c8ef408a20d243d8bd8249fb9a48350dc19663b5e0fce67a8dbcb7de296c5ae7bbf72e98a2020fb78f2db29b54b0e24b181aa1c1d333cc0303685d6120b03216a913f96b96eb838f9bff125306ae3120af838c9fc07ebb5100125436bd24ec6d994d0bff5d065221871f8410daf536766757239bf594e61c5432c9817281b985263bada8381292e543a49814061ae11c92a316e7dc100327b59e3da90302c5ada68c6a50201bda1fcce800b53f381059665dbabeeb0b50eb22b2d7d2d9b0aa7488ca70e67ac6c518adb8e78454a466501e89d81a45bf1ebc350896f2c3ae4b6679ecfbf9d32960d4f5b493125c7876ef36158562371193f600bc511000a67bdb7c664d018f99d9e589868d103d7e0994f166b2ba18ff7e67d8c4da749e44dfae1d930ae5397083a51675c409049dfb626a96246c0015ca696e94ebb767a20147834bf78b07fece3f0872b057c1c519ff882501995237d8206b0b3832f78753ebd8dcbd1d3d9f5ba733538113af6b407d960ec4353c50eb38ab29888238da843cd404ed8f4952f59e4bbc0035fc77a54846a9d419179c46af1b4a3b7fc98e4d312aaa29b9b7d79e739703dc0fa41c7280d5587709277ffa11c3620f5fba985b82c238ba19b17ebd027af9424be0941719919f620dd3bb3c3f11638363708aa11f858e153cf3a69bce69978b90e4a273836100aa1e617ba455cd00426847f");
|
||||
|
||||
List<String> shouldBeRepos = new LinkedList<>();
|
||||
shouldBeRepos.addAll(oem0);
|
||||
shouldBeRepos.addAll(oem1);
|
||||
shouldBeRepos.addAll(fdroid0);
|
||||
shouldBeRepos.addAll(fdroid1);
|
||||
shouldBeRepos.addAll(fdroid2);
|
||||
shouldBeRepos.addAll(fdroid3);
|
||||
|
||||
for (int i = 0; i < initialRepos.size(); i++) {
|
||||
assertEquals(shouldBeRepos.get(i), initialRepos.get(i));
|
||||
}
|
||||
} finally {
|
||||
for (Repo repo : RepoProvider.Helper.all(context, new String[]{Schema.RepoTable.Cols._ID})) {
|
||||
RepoProvider.Helper.remove(context, repo.getId());
|
||||
}
|
||||
additionalReposXmlFile.delete();
|
||||
DBHelper.clearDbHelperSingleton();
|
||||
}
|
||||
}
|
||||
}
|
@ -157,16 +157,16 @@ public class RepoProviderTest extends FDroidProviderTest {
|
||||
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) {
|
||||
if (reposFromXml.length % DBHelper.REPO_XML_ITEM_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;
|
||||
for (int i = 0; i < reposFromXml.length / DBHelper.REPO_XML_ITEM_COUNT; i++) {
|
||||
int offset = i * DBHelper.REPO_XML_ITEM_COUNT;
|
||||
assertRepo(
|
||||
defaultRepos.get(i),
|
||||
reposFromXml[offset + 1], // address
|
||||
reposFromXml[offset + 2], // description
|
||||
reposFromXml[offset + 2].replaceAll("\\s+", " "), // description
|
||||
Utils.calcFingerprint(reposFromXml[offset + 7]), // pubkey
|
||||
reposFromXml[offset] // name
|
||||
);
|
||||
|
34
app/src/test/resources/additional_repos.xml
Normal file
34
app/src/test/resources/additional_repos.xml
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="additional_repos">
|
||||
<!-- name -->
|
||||
<item>oem0Name</item>
|
||||
<!-- address -->
|
||||
<item>https://www.oem0.com/yeah/repo</item>
|
||||
<!-- description -->
|
||||
<item>I'm the first oem repo.</item>
|
||||
<!-- version -->
|
||||
<item>22</item>
|
||||
<!-- enabled -->
|
||||
<item>1</item>
|
||||
<!-- push requests -->
|
||||
<item>ignore</item>
|
||||
<!-- pubkey -->
|
||||
<item>fffff2313aaaaabcccc111</item>
|
||||
|
||||
<!-- name -->
|
||||
<item>oem1MyNameIs</item>
|
||||
<!-- address -->
|
||||
<item>https://www.mynameis.com/rapper/repo</item>
|
||||
<!-- description -->
|
||||
<item>Who is the first repo?</item>
|
||||
<!-- version -->
|
||||
<item>22</item>
|
||||
<!-- enabled -->
|
||||
<item>0</item>
|
||||
<!-- push requests -->
|
||||
<item>ignore</item>
|
||||
<!-- pubkey -->
|
||||
<item>ddddddd2313aaaaabcccc111</item>
|
||||
</string-array>
|
||||
</resources>
|
31
app/src/test/resources/ugly_additional_repos.xml
Normal file
31
app/src/test/resources/ugly_additional_repos.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="additional_repos">
|
||||
<!-- name -->
|
||||
<item>FTW</item>
|
||||
<!-- address -->
|
||||
<item>https://f-droid.org/repo</item>
|
||||
<!-- description -->
|
||||
<item>I'm the first oem repo.</item>
|
||||
<!-- version -->
|
||||
<item>22</item>
|
||||
<!-- enabled -->
|
||||
<item>1</item>
|
||||
<!-- push requests -->
|
||||
<item>prompt</item>
|
||||
<!-- pubkey -->
|
||||
<item>fffff2313aaaaabcccc111</item>
|
||||
|
||||
|
||||
<ite>SHOULD BE IGNORED</ite>
|
||||
<item>Repo Name</item>
|
||||
<item>https://www.oem0.com/yeah/repo</item>
|
||||
<item>I'm the second oem repo.</item>
|
||||
<item>22</item>
|
||||
<item>1</item>
|
||||
<item_>SHOULD BE IGNORED</item_>
|
||||
<ITEM>SHOULD BE IGNORED</ITEM>
|
||||
<item>always</item>
|
||||
<item>fffff2313aaaaabcccc111</item>
|
||||
</string-array>
|
||||
</resources>
|
Loading…
x
Reference in New Issue
Block a user