summaryrefslogtreecommitdiff
path: root/src/instrumentationTest/de/test/antennapod
diff options
context:
space:
mode:
authordaniel oeh <daniel.oeh@gmail.com>2013-09-11 15:09:11 +0200
committerdaniel oeh <daniel.oeh@gmail.com>2013-09-11 15:09:11 +0200
commitcef7772a90b7221de20e0a3176a8fc7d40ec9044 (patch)
tree53307e00a26e105f0cfa73518783187467f3f565 /src/instrumentationTest/de/test/antennapod
parent6043f79128586bc2925b81a852f0758a53f7990c (diff)
parent30c681d1cf5e0d33b716f6c8885ab92f46efbaa3 (diff)
downloadAntennaPod-cef7772a90b7221de20e0a3176a8fc7d40ec9044.zip
Merge branch 'release-0975'0.9.7.5
Diffstat (limited to 'src/instrumentationTest/de/test/antennapod')
-rw-r--r--src/instrumentationTest/de/test/antennapod/AntennaPodTestRunner.java18
-rw-r--r--src/instrumentationTest/de/test/antennapod/service/download/HttpDownloaderTest.java128
-rw-r--r--src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java11
-rw-r--r--src/instrumentationTest/de/test/antennapod/storage/DBTasksTest.java252
-rw-r--r--src/instrumentationTest/de/test/antennapod/storage/DBWriterTest.java738
-rw-r--r--src/instrumentationTest/de/test/antennapod/syndication/handler/FeedHandlerTest.java170
-rw-r--r--src/instrumentationTest/de/test/antennapod/syndication/handler/TestFeeds.java346
-rw-r--r--src/instrumentationTest/de/test/antennapod/util/FilenameGeneratorTest.java59
8 files changed, 1722 insertions, 0 deletions
diff --git a/src/instrumentationTest/de/test/antennapod/AntennaPodTestRunner.java b/src/instrumentationTest/de/test/antennapod/AntennaPodTestRunner.java
new file mode 100644
index 000000000..7aaa14909
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/AntennaPodTestRunner.java
@@ -0,0 +1,18 @@
+package instrumentationTest.de.test.antennapod;
+
+import android.test.InstrumentationTestRunner;
+import android.test.suitebuilder.TestSuiteBuilder;
+import android.util.Log;
+
+import instrumentationTest.de.test.antennapod.service.download.HttpDownloaderTest;
+import instrumentationTest.de.test.antennapod.util.FilenameGeneratorTest;
+import junit.framework.TestSuite;
+
+public class AntennaPodTestRunner extends InstrumentationTestRunner {
+
+ @Override
+ public TestSuite getAllTests() {
+ return new TestSuiteBuilder(AntennaPodTestRunner.class).includeAllPackagesUnderHere().build();
+ //return new TestSuiteBuilder(AntennaPodTestRunner.class).includeAllPackagesUnderHere().excludePackages("instrumentationTest.de.test.antennapod.syndication.handler").build();
+ }
+}
diff --git a/src/instrumentationTest/de/test/antennapod/service/download/HttpDownloaderTest.java b/src/instrumentationTest/de/test/antennapod/service/download/HttpDownloaderTest.java
new file mode 100644
index 000000000..8df35ce67
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/service/download/HttpDownloaderTest.java
@@ -0,0 +1,128 @@
+package instrumentationTest.de.test.antennapod.service.download;
+
+import java.io.File;
+
+import android.test.InstrumentationTestCase;
+import de.danoeh.antennapod.feed.FeedFile;
+import de.danoeh.antennapod.service.download.*;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+public class HttpDownloaderTest extends InstrumentationTestCase {
+ private static final String TAG = "HttpDownloaderTest";
+ private static final String DOWNLOAD_DIR = "testdownloads";
+
+ private static boolean successful = true;
+
+ private File destDir;
+
+ public HttpDownloaderTest() {
+ super();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ File[] contents = destDir.listFiles();
+ for (File f : contents) {
+ assertTrue(f.delete());
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ destDir = getInstrumentation().getTargetContext().getExternalFilesDir(DOWNLOAD_DIR);
+ assertNotNull(destDir);
+ assertTrue(destDir.exists());
+ }
+
+ private FeedFileImpl setupFeedFile(String downloadUrl, String title) {
+ FeedFileImpl feedfile = new FeedFileImpl(downloadUrl);
+ String fileUrl = new File(destDir, title).getAbsolutePath();
+ File file = new File(fileUrl);
+ Log.d(TAG, "Deleting file: " + file.delete());
+ feedfile.setFile_url(fileUrl);
+ return feedfile;
+ }
+
+ private void download(String url, String title, boolean expectedResult) {
+ FeedFile feedFile = setupFeedFile(url, title);
+ DownloadRequest request = new DownloadRequest(feedFile.getFile_url(), url, title, 0, feedFile.getTypeAsInt());
+ Downloader downloader = new HttpDownloader(request);
+ downloader.call();
+ DownloadStatus status = downloader.getResult();
+ assertNotNull(status);
+ assertTrue(status.isSuccessful() == expectedResult);
+ assertTrue(status.isDone());
+ // the file should not exist if the download has failed
+ assertTrue(new File(feedFile.getFile_url()).exists() == expectedResult);
+ }
+
+ public void testPassingHttp() {
+ download("http://httpbin.org/status/200", "test200", true);
+ }
+
+ public void testPassingHttps() {
+ download("https://httpbin.org/status/200", "test200", true);
+ }
+
+ public void testRedirect() {
+ download("http://httpbin.org/redirect/4", "testRedirect", true);
+ }
+
+ public void testRelativeRedirect() {
+ download("http://httpbin.org/relative-redirect/4", "testRelativeRedirect", true);
+ }
+
+ public void testGzip() {
+ download("http://httpbin.org/gzip", "testGzip", true);
+ }
+
+ public void test404() {
+ download("http://httpbin.org/status/404", "test404", false);
+ }
+
+ public void testCancel() {
+ final String url = "http://httpbin.org/delay/3";
+ FeedFileImpl feedFile = setupFeedFile(url, "delay");
+ final Downloader downloader = new HttpDownloader(new DownloadRequest(feedFile.getFile_url(), url, "delay", 0, feedFile.getTypeAsInt()));
+ Thread t = new Thread() {
+ @Override
+ public void run() {
+ downloader.call();
+ }
+ };
+ t.start();
+ downloader.cancel();
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ DownloadStatus result = downloader.getResult();
+ assertTrue(result.isDone());
+ assertFalse(result.isSuccessful());
+ assertTrue(result.isCancelled());
+ assertFalse(new File(feedFile.getFile_url()).exists());
+ }
+
+ private static class FeedFileImpl extends FeedFile {
+ public FeedFileImpl(String download_url) {
+ super(null, download_url, false);
+ }
+
+
+ @Override
+ public String getHumanReadableIdentifier() {
+ return download_url;
+ }
+
+ @Override
+ public int getTypeAsInt() {
+ return 0;
+ }
+ }
+
+}
diff --git a/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java b/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java
new file mode 100644
index 000000000..0fb733b67
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/storage/DBReaderTest.java
@@ -0,0 +1,11 @@
+package instrumentationTest.de.test.antennapod.storage;
+
+import android.test.InstrumentationTestCase;
+
+/**
+ * Test class for DBReader
+ */
+public class DBReaderTest extends InstrumentationTestCase {
+
+
+}
diff --git a/src/instrumentationTest/de/test/antennapod/storage/DBTasksTest.java b/src/instrumentationTest/de/test/antennapod/storage/DBTasksTest.java
new file mode 100644
index 000000000..7631a5787
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/storage/DBTasksTest.java
@@ -0,0 +1,252 @@
+package instrumentationTest.de.test.antennapod.storage;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import android.test.InstrumentationTestCase;
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.feed.FeedMedia;
+import de.danoeh.antennapod.preferences.UserPreferences;
+import de.danoeh.antennapod.storage.DBReader;
+import de.danoeh.antennapod.storage.DBTasks;
+import de.danoeh.antennapod.storage.PodDBAdapter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Test class for DBTasks
+ */
+public class DBTasksTest extends InstrumentationTestCase {
+ private static final String TEST_FOLDER = "testDBTasks";
+ private static final int EPISODE_CACHE_SIZE = 5;
+
+ private File destFolder;
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ final Context context = getInstrumentation().getTargetContext();
+ assertTrue(PodDBAdapter.deleteDatabase(context));
+
+ for (File f : destFolder.listFiles()) {
+ assertTrue(f.delete());
+ }
+ assertTrue(destFolder.delete());
+
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+ assertTrue(destFolder.exists());
+ assertTrue(destFolder.canWrite());
+
+ final Context context = getInstrumentation().getTargetContext();
+ context.deleteDatabase(PodDBAdapter.DATABASE_NAME);
+ // make sure database is created
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.close();
+
+ SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(getInstrumentation().getTargetContext().getApplicationContext()).edit();
+ prefEdit.putString(UserPreferences.PREF_EPISODE_CACHE_SIZE, Integer.toString(EPISODE_CACHE_SIZE));
+ prefEdit.commit();
+ }
+
+ public void testPerformAutoCleanupShouldDelete() throws IOException {
+ final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
+
+ Feed feed = new Feed("url", new Date(), "title");
+ List<FeedItem> items = new ArrayList<FeedItem>();
+ feed.setItems(items);
+ List<File> files = new ArrayList<File>();
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), true, feed);
+
+ File f = new File(destFolder, "file " + i);
+ assertTrue(f.createNewFile());
+ files.add(f);
+ item.setMedia(new FeedMedia(0, item, 1, 0, 1L, "m", f.getAbsolutePath(), "url", true, new Date(NUM_ITEMS - i)));
+ items.add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getTargetContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : items) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+ DBTasks.performAutoCleanup(getInstrumentation().getTargetContext());
+ for (int i = 0; i < files.size(); i++) {
+ if (i < EPISODE_CACHE_SIZE) {
+ assertTrue(files.get(i).exists());
+ } else {
+ assertFalse(files.get(i).exists());
+ }
+ }
+ }
+
+ public void testPerformAutoCleanupShouldNotDeleteBecauseUnread() throws IOException {
+ final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
+
+ Feed feed = new Feed("url", new Date(), "title");
+ List<FeedItem> items = new ArrayList<FeedItem>();
+ feed.setItems(items);
+ List<File> files = new ArrayList<File>();
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), false, feed);
+
+ File f = new File(destFolder, "file " + i);
+ assertTrue(f.createNewFile());
+ assertTrue(f.exists());
+ files.add(f);
+ item.setMedia(new FeedMedia(0, item, 1, 0, 1L, "m", f.getAbsolutePath(), "url", true, new Date(NUM_ITEMS - i)));
+ items.add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getTargetContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : items) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+ DBTasks.performAutoCleanup(getInstrumentation().getTargetContext());
+ for (File file : files) {
+ assertTrue(file.exists());
+ }
+ }
+
+ public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue() throws IOException {
+ final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2;
+
+ Feed feed = new Feed("url", new Date(), "title");
+ List<FeedItem> items = new ArrayList<FeedItem>();
+ feed.setItems(items);
+ List<File> files = new ArrayList<File>();
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), true, feed);
+
+ File f = new File(destFolder, "file " + i);
+ assertTrue(f.createNewFile());
+ assertTrue(f.exists());
+ files.add(f);
+ item.setMedia(new FeedMedia(0, item, 1, 0, 1L, "m", f.getAbsolutePath(), "url", true, new Date(NUM_ITEMS - i)));
+ items.add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getTargetContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.setQueue(items);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : items) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+ DBTasks.performAutoCleanup(getInstrumentation().getTargetContext());
+ for (File file : files) {
+ assertTrue(file.exists());
+ }
+ }
+
+ public void testUpdateFeedNewFeed() {
+ final Context context = getInstrumentation().getTargetContext();
+ final int NUM_ITEMS = 10;
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(), false, feed));
+ }
+ Feed newFeed = DBTasks.updateFeed(context, feed);
+
+ assertTrue(newFeed == feed);
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertFalse(item.isRead());
+ assertTrue(item.getId() != 0);
+ }
+ }
+
+ public void testUpdateFeedUpdatedFeed() {
+ final Context context = getInstrumentation().getTargetContext();
+ final int NUM_ITEMS_OLD = 10;
+ final int NUM_ITEMS_NEW = 10;
+
+ final Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS_OLD; i++) {
+ feed.getItems().add(new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), true, feed));
+ }
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ // ensure that objects have been saved in db, then reset
+ assertTrue(feed.getId() != 0);
+ final long feedID = feed.getId();
+ feed.setId(0);
+ List<Long> itemIDs = new ArrayList<Long>();
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ itemIDs.add(item.getId());
+ item.setId(0);
+ }
+
+ for (int i = NUM_ITEMS_OLD; i < NUM_ITEMS_NEW + NUM_ITEMS_OLD; i++) {
+ feed.getItems().add(0, new FeedItem(0, "item " + i, "id " + i, "link " + i, new Date(i), true, feed));
+ }
+
+ final Feed newFeed = DBTasks.updateFeed(context, feed);
+ assertTrue(feed != newFeed);
+
+ updatedFeedTest(newFeed, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
+
+ final Feed feedFromDB = DBReader.getFeed(context, newFeed.getId());
+ assertNotNull(feedFromDB);
+ assertTrue(feedFromDB.getId() == newFeed.getId());
+ updatedFeedTest(feedFromDB, feedID, itemIDs, NUM_ITEMS_OLD, NUM_ITEMS_NEW);
+ }
+
+ private void updatedFeedTest(final Feed newFeed, long feedID, List<Long> itemIDs, final int NUM_ITEMS_OLD, final int NUM_ITEMS_NEW) {
+ assertTrue(newFeed.getId() == feedID);
+ assertTrue(newFeed.getItems().size() == NUM_ITEMS_NEW + NUM_ITEMS_OLD);
+ Collections.reverse(newFeed.getItems());
+ Date lastDate = new Date(0);
+ for (int i = 0; i < NUM_ITEMS_OLD; i++) {
+ FeedItem item = newFeed.getItems().get(i);
+ assertTrue(item.getFeed() == newFeed);
+ assertTrue(item.getId() == itemIDs.get(i));
+ assertTrue(item.isRead());
+ assertTrue(item.getPubDate().getTime() >= lastDate.getTime());
+ lastDate = item.getPubDate();
+ }
+ for (int i = NUM_ITEMS_OLD; i < NUM_ITEMS_NEW + NUM_ITEMS_OLD; i++) {
+ FeedItem item = newFeed.getItems().get(i);
+ assertTrue(item.getFeed() == newFeed);
+ assertTrue(item.getId() != 0);
+ assertFalse(item.isRead());
+ assertTrue(item.getPubDate().getTime() >= lastDate.getTime());
+ lastDate = item.getPubDate();
+ }
+ }
+}
diff --git a/src/instrumentationTest/de/test/antennapod/storage/DBWriterTest.java b/src/instrumentationTest/de/test/antennapod/storage/DBWriterTest.java
new file mode 100644
index 000000000..0483a3084
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/storage/DBWriterTest.java
@@ -0,0 +1,738 @@
+package instrumentationTest.de.test.antennapod.storage;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.feed.FeedImage;
+import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.feed.FeedMedia;
+import de.danoeh.antennapod.storage.DBReader;
+import de.danoeh.antennapod.storage.DBWriter;
+import de.danoeh.antennapod.storage.PodDBAdapter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Test class for DBWriter
+ */
+public class DBWriterTest extends InstrumentationTestCase {
+ private static final String TAG = "DBWriterTest";
+ private static final String TEST_FOLDER = "testDBWriter";
+ private static final long TIMEOUT = 5L;
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ final Context context = getInstrumentation().getTargetContext();
+ assertTrue(PodDBAdapter.deleteDatabase(getInstrumentation().getTargetContext()));
+
+ File testDir = context.getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(testDir);
+ for (File f : testDir.listFiles()) {
+ f.delete();
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ final Context context = getInstrumentation().getTargetContext();
+ context.deleteDatabase(PodDBAdapter.DATABASE_NAME);
+ // make sure database is created
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.close();
+ }
+
+ public void testDeleteFeedMediaOfItemFileExists() throws IOException, ExecutionException, InterruptedException {
+ File dest = new File(getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile");
+
+ assertTrue(dest.createNewFile());
+
+ Feed feed = new Feed("url", new Date(), "title");
+ List<FeedItem> items = new ArrayList<FeedItem>();
+ feed.setItems(items);
+ FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), true, feed);
+
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", dest.getAbsolutePath(), "download_url", true, null);
+ item.setMedia(media);
+
+ items.add(item);
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getTargetContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+ assertTrue(media.getId() != 0);
+ assertTrue(item.getId() != 0);
+
+ DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId()).get();
+ media = DBReader.getFeedMedia(getInstrumentation().getTargetContext(), media.getId());
+ assertNotNull(media);
+ assertFalse(dest.exists());
+ assertFalse(media.isDownloaded());
+ assertNull(media.getFile_url());
+ }
+
+ public void testDeleteFeed() throws IOException, ExecutionException, InterruptedException, TimeoutException {
+ File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+
+ // create Feed image
+ File imgFile = new File(destFolder, "image");
+ assertTrue(imgFile.createNewFile());
+ FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
+ image.setFeed(feed);
+ feed.setImage(image);
+
+ List<File> itemFiles = new ArrayList<File>();
+ // create items with downloaded media files
+ for (int i = 0; i < 10; i++) {
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ File enc = new File(destFolder, "file " + i);
+ assertTrue(enc.createNewFile());
+ itemFiles.add(enc);
+
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null);
+ item.setMedia(media);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ assertTrue(feed.getImage().getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+
+ DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ // check if files still exist
+ assertFalse(imgFile.exists());
+ for (File f : itemFiles) {
+ assertFalse(f.exists());
+ }
+
+ adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ Cursor c = adapter.getFeedCursor(feed.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getImageOfFeedCursor(image.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ for (FeedItem item : feed.getItems()) {
+ c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ }
+ }
+
+ public void testDeleteFeedNoImage() throws ExecutionException, InterruptedException, IOException, TimeoutException {
+ File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+
+ feed.setImage(null);
+
+ List<File> itemFiles = new ArrayList<File>();
+ // create items with downloaded media files
+ for (int i = 0; i < 10; i++) {
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ File enc = new File(destFolder, "file " + i);
+ assertTrue(enc.createNewFile());
+
+ itemFiles.add(enc);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null);
+ item.setMedia(media);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+
+ DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ // check if files still exist
+ for (File f : itemFiles) {
+ assertFalse(f.exists());
+ }
+
+ adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ Cursor c = adapter.getFeedCursor(feed.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ for (FeedItem item : feed.getItems()) {
+ c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ }
+ }
+
+ public void testDeleteFeedNoItems() throws IOException, ExecutionException, InterruptedException, TimeoutException {
+ File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(null);
+
+ // create Feed image
+ File imgFile = new File(destFolder, "image");
+ assertTrue(imgFile.createNewFile());
+ FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
+ image.setFeed(feed);
+ feed.setImage(image);
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ assertTrue(feed.getImage().getId() != 0);
+
+ DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ // check if files still exist
+ assertFalse(imgFile.exists());
+
+ adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ Cursor c = adapter.getFeedCursor(feed.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getImageOfFeedCursor(image.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ }
+
+ public void testDeleteFeedNoFeedMedia() throws IOException, ExecutionException, InterruptedException, TimeoutException {
+ File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+
+ // create Feed image
+ File imgFile = new File(destFolder, "image");
+ assertTrue(imgFile.createNewFile());
+ FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
+ image.setFeed(feed);
+ feed.setImage(image);
+
+ // create items
+ for (int i = 0; i < 10; i++) {
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ assertTrue(feed.getImage().getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+
+ DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ // check if files still exist
+ assertFalse(imgFile.exists());
+
+ adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ Cursor c = adapter.getFeedCursor(feed.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getImageOfFeedCursor(image.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ for (FeedItem item : feed.getItems()) {
+ c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
+ assertTrue(c.getCount() == 0);
+ c.close();
+ }
+ }
+
+ public void testDeleteFeedWithQueueItems() throws ExecutionException, InterruptedException, TimeoutException {
+ File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+
+ // create Feed image
+ File imgFile = new File(destFolder, "image");
+ FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
+ image.setFeed(feed);
+ feed.setImage(image);
+
+ List<File> itemFiles = new ArrayList<File>();
+ // create items with downloaded media files
+ for (int i = 0; i < 10; i++) {
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ File enc = new File(destFolder, "file " + i);
+ itemFiles.add(enc);
+
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", false, null);
+ item.setMedia(media);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ assertTrue(feed.getImage().getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+
+
+ List<FeedItem> queue = new ArrayList<FeedItem>();
+ queue.addAll(feed.getItems());
+ adapter.open();
+ adapter.setQueue(queue);
+
+ Cursor queueCursor = adapter.getQueueIDCursor();
+ assertTrue(queueCursor.getCount() == queue.size());
+ queueCursor.close();
+
+ adapter.close();
+ DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ adapter.open();
+
+ Cursor c = adapter.getFeedCursor(feed.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getImageOfFeedCursor(image.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ for (FeedItem item : feed.getItems()) {
+ c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ }
+ c = adapter.getQueueCursor();
+ assertTrue(c.getCount() == 0);
+ c.close();
+ adapter.close();
+ }
+
+ public void testDeleteFeedNoDownloadedFiles() throws ExecutionException, InterruptedException, TimeoutException {
+ File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
+ assertNotNull(destFolder);
+
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+
+ // create Feed image
+ File imgFile = new File(destFolder, "image");
+ FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
+ image.setFeed(feed);
+ feed.setImage(image);
+
+ List<File> itemFiles = new ArrayList<File>();
+ // create items with downloaded media files
+ for (int i = 0; i < 10; i++) {
+ FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ File enc = new File(destFolder, "file " + i);
+ itemFiles.add(enc);
+
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", false, null);
+ item.setMedia(media);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ assertTrue(feed.getImage().getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ assertTrue(item.getMedia().getId() != 0);
+ }
+
+ DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ adapter = new PodDBAdapter(getInstrumentation().getContext());
+ adapter.open();
+ Cursor c = adapter.getFeedCursor(feed.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getImageOfFeedCursor(image.getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ for (FeedItem item : feed.getItems()) {
+ c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
+ assertTrue(c.getCount() == 0);
+ c.close();
+ c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
+ assertTrue(c.getCount() == 0);
+ c.close();
+ }
+ }
+
+ private FeedMedia playbackHistorySetup(Date playbackCompletionDate) {
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), true, feed);
+ FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate);
+ feed.getItems().add(item);
+ item.setMedia(media);
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+ assertTrue(media.getId() != 0);
+ return media;
+ }
+
+ public void testAddItemToPlaybackHistoryNotPlayedYet() throws ExecutionException, InterruptedException {
+ final Context context = getInstrumentation().getTargetContext();
+
+ FeedMedia media = playbackHistorySetup(null);
+ DBWriter.addItemToPlaybackHistory(context, media).get();
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ media = DBReader.getFeedMedia(context, media.getId());
+ adapter.close();
+
+ assertNotNull(media);
+ assertNotNull(media.getPlaybackCompletionDate());
+ }
+
+ public void testAddItemToPlaybackHistoryAlreadyPlayed() throws ExecutionException, InterruptedException {
+ final long OLD_DATE = 0;
+ final Context context = getInstrumentation().getTargetContext();
+
+ FeedMedia media = playbackHistorySetup(new Date(OLD_DATE));
+ DBWriter.addItemToPlaybackHistory(getInstrumentation().getTargetContext(), media).get();
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ media = DBReader.getFeedMedia(context, media.getId());
+ adapter.close();
+
+ assertNotNull(media);
+ assertNotNull(media.getPlaybackCompletionDate());
+ assertFalse(OLD_DATE == media.getPlaybackCompletionDate().getTime());
+ }
+
+ private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException {
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), true, feed);
+ feed.getItems().add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+ List<Future<?>> futures = new ArrayList<Future<?>>();
+ for (FeedItem item : feed.getItems()) {
+ futures.add(DBWriter.addQueueItem(context, item.getId()));
+ }
+ for (Future<?> f : futures) {
+ f.get(TIMEOUT, TimeUnit.SECONDS);
+ }
+ return feed;
+ }
+
+ public void testAddQueueItemSingleItem() throws InterruptedException, ExecutionException, TimeoutException {
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(item.getId() != 0);
+ DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor cursor = adapter.getQueueIDCursor();
+ assertTrue(cursor.moveToFirst());
+ assertTrue(cursor.getLong(0) == item.getId());
+ cursor.close();
+ adapter.close();
+ }
+
+ public void testAddQueueItemSingleItemAlreadyInQueue() throws InterruptedException, ExecutionException, TimeoutException {
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), true, feed);
+ feed.getItems().add(item);
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(item.getId() != 0);
+ DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor cursor = adapter.getQueueIDCursor();
+ assertTrue(cursor.moveToFirst());
+ assertTrue(cursor.getLong(0) == item.getId());
+ cursor.close();
+ adapter.close();
+
+ DBWriter.addQueueItem(context, item.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ cursor = adapter.getQueueIDCursor();
+ assertTrue(cursor.moveToFirst());
+ assertTrue(cursor.getLong(0) == item.getId());
+ assertTrue(cursor.getCount() == 1);
+ cursor.close();
+ adapter.close();
+ }
+
+ public void testAddQueueItemMultipleItems() throws InterruptedException, ExecutionException, TimeoutException {
+ final Context context = getInstrumentation().getTargetContext();
+ final int NUM_ITEMS = 10;
+
+ Feed feed = queueTestSetupMultipleItems(NUM_ITEMS);
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor cursor = adapter.getQueueIDCursor();
+ assertTrue(cursor.moveToFirst());
+ assertTrue(cursor.getCount() == NUM_ITEMS);
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ assertTrue(cursor.moveToPosition(i));
+ assertTrue(cursor.getLong(0) == feed.getItems().get(i).getId());
+ }
+ cursor.close();
+ adapter.close();
+ }
+
+ public void testClearQueue() throws InterruptedException, ExecutionException, TimeoutException {
+ final Context context = getInstrumentation().getTargetContext();
+ final int NUM_ITEMS = 10;
+
+ Feed feed = queueTestSetupMultipleItems(NUM_ITEMS);
+ DBWriter.clearQueue(context).get(TIMEOUT, TimeUnit.SECONDS);
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor cursor = adapter.getQueueIDCursor();
+ assertFalse(cursor.moveToFirst());
+ cursor.close();
+ adapter.close();
+ }
+
+ public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
+ final int NUM_ITEMS = 10;
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), true, feed);
+ feed.getItems().add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+ for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) {
+ final long id = feed.getItems().get(removeIndex).getId();
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setQueue(feed.getItems());
+ adapter.close();
+
+ DBWriter.removeQueueItem(context, id, false).get(TIMEOUT, TimeUnit.SECONDS);
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor queue = adapter.getQueueIDCursor();
+ assertTrue(queue.getCount() == NUM_ITEMS - 1);
+ for (int i = 0; i < queue.getCount(); i++) {
+ assertTrue(queue.moveToPosition(i));
+ final long queueID = queue.getLong(0);
+ assertTrue(queueID != id); // removed item is no longer in queue
+ boolean idFound = false;
+ for (FeedItem item : feed.getItems()) { // items that were not removed are still in the queue
+ idFound = idFound | (item.getId() == queueID);
+ }
+ assertTrue(idFound);
+ }
+
+ queue.close();
+ adapter.close();
+ }
+ }
+
+ public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
+ final int NUM_ITEMS = 10;
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), true, feed);
+ feed.getItems().add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+ for (int from = 0; from < NUM_ITEMS; from++) {
+ for (int to = 0; to < NUM_ITEMS; to++) {
+ if (from == to) {
+ continue;
+ }
+ Log.d(TAG, String.format("testMoveQueueItem: From=%d, To=%d", from, to));
+ final long fromID = feed.getItems().get(from).getId();
+
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setQueue(feed.getItems());
+ adapter.close();
+
+ DBWriter.moveQueueItem(context, from, to, false).get(TIMEOUT, TimeUnit.SECONDS);
+ adapter = new PodDBAdapter(context);
+ adapter.open();
+ Cursor queue = adapter.getQueueIDCursor();
+ assertTrue(queue.getCount() == NUM_ITEMS);
+ assertTrue(queue.moveToPosition(from));
+ assertFalse(queue.getLong(0) == fromID);
+ assertTrue(queue.moveToPosition(to));
+ assertTrue(queue.getLong(0) == fromID);
+
+ queue.close();
+ adapter.close();
+ }
+ }
+ }
+
+ public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException {
+ final Context context = getInstrumentation().getTargetContext();
+ final int NUM_ITEMS = 10;
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), false, feed);
+ feed.getItems().add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+
+ DBWriter.markFeedRead(context, feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
+ List<FeedItem> loadedItems = DBReader.getFeedItemList(context, feed);
+ for (FeedItem item : loadedItems) {
+ assertTrue(item.isRead());
+ }
+ }
+
+ public void testMarkAllItemsReadSameFeed() {
+ final Context context = getInstrumentation().getTargetContext();
+ final int NUM_ITEMS = 10;
+ Feed feed = new Feed("url", new Date(), "title");
+ feed.setItems(new ArrayList<FeedItem>());
+ for (int i = 0; i < NUM_ITEMS; i++) {
+ FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), false, feed);
+ feed.getItems().add(item);
+ }
+
+ PodDBAdapter adapter = new PodDBAdapter(context);
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+
+ assertTrue(feed.getId() != 0);
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+
+ DBWriter.markAllItemsRead(context);
+ List<FeedItem> loadedItems = DBReader.getFeedItemList(context, feed);
+ for (FeedItem item : loadedItems) {
+ assertTrue(item.isRead());
+ }
+ }
+
+}
diff --git a/src/instrumentationTest/de/test/antennapod/syndication/handler/FeedHandlerTest.java b/src/instrumentationTest/de/test/antennapod/syndication/handler/FeedHandlerTest.java
new file mode 100644
index 000000000..95c3a3dba
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/syndication/handler/FeedHandlerTest.java
@@ -0,0 +1,170 @@
+package instrumentationTest.de.test.antennapod.syndication.handler;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+
+import android.test.AndroidTestCase;
+import android.util.Log;
+import de.danoeh.antennapod.feed.Feed;
+import de.danoeh.antennapod.feed.FeedItem;
+import de.danoeh.antennapod.syndication.handler.FeedHandler;
+
+/** Enqueues a list of Feeds and tests if they are parsed correctly */
+public class FeedHandlerTest extends AndroidTestCase {
+ private static final String TAG = "FeedHandlerTest";
+ private static final String FEEDS_DIR = "testfeeds";
+
+ private ArrayList<Feed> feeds;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ feeds = new ArrayList<Feed>();
+ for (int i = 0; i < TestFeeds.urls.length; i++) {
+ Feed f = new Feed(TestFeeds.urls[i], new Date());
+ f.setFile_url(new File(getContext().getExternalFilesDir(FEEDS_DIR)
+ .getAbsolutePath(), "R" + i).getAbsolutePath());
+ feeds.add(f);
+ }
+ }
+
+ private InputStream getInputStream(String url)
+ throws MalformedURLException, IOException {
+ HttpURLConnection connection = (HttpURLConnection) (new URL(url))
+ .openConnection();
+ int rc = connection.getResponseCode();
+ if (rc == HttpURLConnection.HTTP_OK) {
+ return connection.getInputStream();
+ } else {
+ return null;
+ }
+ }
+
+ private boolean downloadFeed(Feed feed) throws IOException {
+ int num_retries = 20;
+ boolean successful = false;
+
+ for (int i = 0; i < num_retries; i++) {
+ InputStream in = null;
+ BufferedOutputStream out = null;
+ try {
+ in = getInputStream(feed.getDownload_url());
+ if (in == null) {
+ return false;
+ }
+ out = new BufferedOutputStream(new FileOutputStream(
+ feed.getFile_url()));
+ byte[] buffer = new byte[8 * 1024];
+ int count = 0;
+ while ((count = in.read(buffer)) != -1) {
+ out.write(buffer, 0, count);
+ }
+ out.flush();
+ successful = true;
+ return true;
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (successful) {
+ break;
+ }
+ }
+ }
+ if (!successful) {
+ Log.e(TAG, "Download failed after " + num_retries + " retries");
+ throw new IOException();
+ } else {
+ return true;
+ }
+ }
+
+ private boolean isFeedValid(Feed feed) {
+ Log.i(TAG, "Checking if " + feed.getDownload_url() + " is valid");
+ boolean result = false;
+ if (feed.getTitle() == null) {
+ Log.e(TAG, "Feed has no title");
+ return false;
+ }
+ if (!hasValidFeedItems(feed)) {
+ Log.e(TAG, "Feed has invalid items");
+ return false;
+ }
+ if (feed.getLink() == null) {
+ Log.e(TAG, "Feed has no link");
+ return false;
+ }
+ if (feed.getLink() != null && feed.getLink().length() == 0) {
+ Log.e(TAG, "Feed has empty link");
+ return false;
+ }
+ if (feed.getIdentifyingValue() == null) {
+ Log.e(TAG, "Feed has no identifying value");
+ return false;
+ }
+ if (feed.getIdentifyingValue() != null
+ && feed.getIdentifyingValue().length() == 0) {
+ Log.e(TAG, "Feed has empty identifying value");
+ return false;
+ }
+ return true;
+ }
+
+ private boolean hasValidFeedItems(Feed feed) {
+ for (FeedItem item : feed.getItems()) {
+ if (item.getTitle() == null) {
+ Log.e(TAG, "Item has no title");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void testParseFeeds() {
+ Log.i(TAG, "Testing RSS feeds");
+ while (!feeds.isEmpty()) {
+ Feed feed = feeds.get(0);
+ parseFeed(feed);
+ feeds.remove(0);
+ }
+
+ Log.i(TAG, "RSS Test completed");
+ }
+
+ private void parseFeed(Feed feed) {
+ try {
+ Log.i(TAG, "Testing feed with url " + feed.getDownload_url());
+ FeedHandler handler = new FeedHandler();
+ if (downloadFeed(feed)) {
+ handler.parseFeed(feed);
+ assertTrue(isFeedValid(feed));
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Error when trying to test " + feed.getDownload_url());
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ for (Feed feed : feeds) {
+ File f = new File(feed.getFile_url());
+ f.delete();
+ }
+ }
+
+}
diff --git a/src/instrumentationTest/de/test/antennapod/syndication/handler/TestFeeds.java b/src/instrumentationTest/de/test/antennapod/syndication/handler/TestFeeds.java
new file mode 100644
index 000000000..61990cccb
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/syndication/handler/TestFeeds.java
@@ -0,0 +1,346 @@
+package instrumentationTest.de.test.antennapod.syndication.handler;
+
+public class TestFeeds {
+
+ public static final String[] urls = {
+ "http://savoirsenmultimedia.ens.fr/podcast.php?id=30",
+ "http://bitlove.org/apollo40/ps3newsroom/feed",
+ "http://bitlove.org/beapirate/hauptstadtpiraten/feed",
+ "http://bitlove.org/benni/besondereumstaende/feed",
+ "http://bitlove.org/bennihahn/unicast/feed",
+ "http://bitlove.org/berndbloggt/wirschweifenab/feed",
+ "http://bitlove.org/bildungsangst/spoiler-alert-mp3/feed",
+ "http://bitlove.org/bildungsangst/spoiler-alert-ogg/feed",
+ "http://bitlove.org/bildungsangst/troja-alert-mp3/feed",
+ "http://bitlove.org/bildungsangst/troja-alert-ogg/feed",
+ "http://bitlove.org/binaergewitter/talk/feed",
+ "http://bitlove.org/binaergewitter/talk-ogg/feed",
+ "http://bitlove.org/bitgamers/bitgamerscast/feed",
+ "http://bitlove.org/boingsworld/boingsworld/feed",
+ "http://bitlove.org/boris/bam/feed",
+ "http://bitlove.org/bruhndsoweiter/anycast-aac/feed",
+ "http://bitlove.org/bruhndsoweiter/anycast-mp3/feed",
+ "http://bitlove.org/bruhndsoweiter/schnackennet-m4a/feed",
+ "http://bitlove.org/bruhndsoweiter/schnackennet-mp3/feed",
+ "http://bitlove.org/bruhndsoweiter/schnackennet-ogg/feed",
+ "http://bitlove.org/byteweise/bytecast/feed",
+ "http://bitlove.org/byteweise/byteweiseaac/feed",
+ "http://bitlove.org/c3d2/news/feed",
+ "http://bitlove.org/c3d2/pentacast/feed",
+ "http://bitlove.org/c3d2/pentamedia/feed",
+ "http://bitlove.org/c3d2/pentamusic/feed",
+ "http://bitlove.org/c3d2/pentaradio/feed",
+ "http://bitlove.org/campuscast_cc/campuscast_cc/feed",
+ "http://bitlove.org/carlito/schnittmuster/feed",
+ "http://bitlove.org/carlito/yaycomics/feed",
+ "http://bitlove.org/cccb/chaosradio/feed",
+ "http://bitlove.org/ccculm/chaosseminar-mp4-high/feed",
+ "http://bitlove.org/ccculm/chaosseminar-theora/feed",
+ "http://bitlove.org/channelcast/channelcast/feed",
+ "http://bitlove.org/chgrasse/freequency/feed",
+ "http://bitlove.org/chgrasse/kiezradio/feed",
+ "http://bitlove.org/christiansteiner/secondunit/feed",
+ "http://bitlove.org/cinext/cinext/feed",
+ "http://bitlove.org/ckater/schoeneecken/feed",
+ "http://bitlove.org/ckater/schoeneecken-mp3/feed",
+ "http://bitlove.org/cocoaheads/austria/feed",
+ "http://bitlove.org/compod/compod/feed",
+ "http://bitlove.org/consolmedia/consolpodcast/feed",
+ "http://bitlove.org/couchblog/computerfix/feed",
+ "http://bitlove.org/culinaricast/podcast/feed",
+ "http://bitlove.org/d3v/die-drei-vogonen/feed",
+ "http://bitlove.org/danielbuechele/luftpost/feed",
+ "http://bitlove.org/deimhart/mp3/feed",
+ "http://bitlove.org/deimhart/ogg/feed",
+ "http://bitlove.org/derbastard/podcast/feed",
+ "http://bitlove.org/derpoppe/poppeandpeople/feed",
+ "http://bitlove.org/derpoppe/stammtischphilosophen/feed",
+ "http://bitlove.org/devradio/devradio-music-mp3/feed",
+ "http://bitlove.org/devradio/devradio-music-ogg/feed",
+ "http://bitlove.org/devradio/devradio-nomusic-mp3/feed",
+ "http://bitlove.org/devradio/devradio-nomusic-ogg/feed",
+ "http://bitlove.org/die-halde/die-halde/feed",
+ "http://bitlove.org/dirtyminutesleft/m4a/feed",
+ "http://bitlove.org/dirtyminutesleft/mp3/feed",
+ "http://bitlove.org/dominik/knutsens/feed",
+ "http://bitlove.org/dominik/schnittchen/feed",
+ "http://bitlove.org/driveeo/podcast/feed",
+ "http://bitlove.org/einfachben/freibeuterhafen/feed",
+ "http://bitlove.org/eintr8podcast/aac/feed",
+ "http://bitlove.org/eintr8podcast/eptv/feed",
+ "http://bitlove.org/eintr8podcast/mp3/feed",
+ "http://bitlove.org/eteubert/satoripress-m4a/feed",
+ "http://bitlove.org/fabu/indie-fresse/feed",
+ "http://bitlove.org/faldrian/bofh-mp3/feed",
+ "http://bitlove.org/faldrian/bofh-oga/feed",
+ "http://bitlove.org/faldrian/faldriansfeierabend/feed",
+ "http://bitlove.org/filmtonpodcast/filmtonpodcast/feed",
+ "http://bitlove.org/firmadorsch/fahrradio/feed",
+ "http://bitlove.org/frequenz9/feed/feed",
+ "http://bitlove.org/gamefusion/feeds/feed",
+ "http://bitlove.org/gamesandmacs/podcast/feed",
+ "http://bitlove.org/geekweek/techpodcast/feed",
+ "http://bitlove.org/germanstudent/apfelnet/feed",
+ "http://bitlove.org/germanstudent/bruellaffencouch-enhanced/feed",
+ "http://bitlove.org/germanstudent/bruellaffencouch-mp3/feed",
+ "http://bitlove.org/germanstudent/kauderwelschavantgarde/feed",
+ "http://bitlove.org/germanstudent/podccast-enhanced/feed",
+ "http://bitlove.org/germanstudent/podccast-mp3/feed",
+ "http://bitlove.org/geschichtendose/love/feed",
+ "http://bitlove.org/gfm/atzbach/feed",
+ "http://bitlove.org/gfm/rumsendende/feed",
+ "http://bitlove.org/grizze/vtlive/feed",
+ "http://bitlove.org/hackerfunk/hf-mp3/feed",
+ "http://bitlove.org/hackerfunk/hf-ogg/feed",
+ "http://bitlove.org/hasencore/podcast/feed",
+ "http://bitlove.org/hoaxmaster/hoaxilla/feed",
+ "http://bitlove.org/hoaxmaster/psychotalk/feed",
+ "http://bitlove.org/hoaxmaster/skeptoskop/feed",
+ "http://bitlove.org/hoersuppe/vorcast/feed",
+ "http://bitlove.org/holgi/wrint/feed",
+ "http://bitlove.org/ich-bin-radio/fir/feed",
+ "http://bitlove.org/ich-bin-radio/rsff/feed",
+ "http://bitlove.org/incerio/podcast/feed",
+ "http://bitlove.org/janlelis/rubykraut/feed",
+ "http://bitlove.org/jed/feed1/feed",
+ "http://bitlove.org/jupiterbroadcasting/coderradio/feed",
+ "http://bitlove.org/jupiterbroadcasting/fauxshowhd/feed",
+ "http://bitlove.org/jupiterbroadcasting/fauxshowmobile/feed",
+ "http://bitlove.org/jupiterbroadcasting/lashd/feed",
+ "http://bitlove.org/jupiterbroadcasting/lasmobile/feed",
+ "http://bitlove.org/jupiterbroadcasting/scibytehd/feed",
+ "http://bitlove.org/jupiterbroadcasting/scibytemobile/feed",
+ "http://bitlove.org/jupiterbroadcasting/techsnap60/feed",
+ "http://bitlove.org/jupiterbroadcasting/techsnapmobile/feed",
+ "http://bitlove.org/jupiterbroadcasting/unfilterhd/feed",
+ "http://bitlove.org/jupiterbroadcasting/unfiltermobile/feed",
+ "http://bitlove.org/kassettenkind/trollfunk/feed",
+ "http://bitlove.org/klangkammermedia/abgekuppelt/feed",
+ "http://bitlove.org/klangkammermedia/derbalkoncast/feed",
+ "http://bitlove.org/klangkammermedia/wortundstille/feed",
+ "http://bitlove.org/kurzpod/kurzpod/feed",
+ "http://bitlove.org/kurzpod/kurzpodm4a/feed",
+ "http://bitlove.org/kurzpod/ogg/feed",
+ "http://bitlove.org/langpod/lp/feed",
+ "http://bitlove.org/legrex/videli-noch/feed",
+ "http://bitlove.org/lisnewsnetcasts/listen/feed",
+ "http://bitlove.org/logenzuschlag/cinecast/feed",
+ "http://bitlove.org/maha/1337kultur/feed",
+ "http://bitlove.org/maha/klabautercast/feed",
+ "http://bitlove.org/map/fanboys/feed",
+ "http://bitlove.org/map/fanboys-mp3/feed",
+ "http://bitlove.org/map/retrozirkel/feed",
+ "http://bitlove.org/map/retrozirkel-mp3/feed",
+ "http://bitlove.org/markus/robotiklabor/feed",
+ "http://bitlove.org/martinschmidt/freiklettern/feed",
+ "http://bitlove.org/mespotine/mespotine_sessions/feed",
+ "http://bitlove.org/meszner/aether/feed",
+ "http://bitlove.org/meszner/kulturwissenschaften/feed",
+ "http://bitlove.org/metaebene/cre/feed",
+ "http://bitlove.org/metaebene/der-lautsprecher/feed",
+ "http://bitlove.org/metaebene/kolophon/feed",
+ "http://bitlove.org/metaebene/logbuch-netzpolitik/feed",
+ "http://bitlove.org/metaebene/mobilemacs/feed",
+ "http://bitlove.org/metaebene/newz-of-the-world/feed",
+ "http://bitlove.org/metaebene/not-safe-for-work/feed",
+ "http://bitlove.org/metaebene/raumzeit/feed",
+ "http://bitlove.org/metaebene/raumzeit-mp3/feed",
+ "http://bitlove.org/metagamer/metagamer/feed",
+ "http://bitlove.org/mfromm/collaborativerockers/feed",
+ "http://bitlove.org/mfromm/explorism/feed",
+ "http://bitlove.org/mfromm/transientesichten/feed",
+ "http://bitlove.org/mhpod/pofacs/feed",
+ "http://bitlove.org/mintcast/podcast/feed",
+ "http://bitlove.org/mitgezwitschert/brandung/feed",
+ "http://bitlove.org/moepmoeporg/anonnewsde/feed",
+ "http://bitlove.org/moepmoeporg/contentcast/feed",
+ "http://bitlove.org/moepmoeporg/dieseminarren/feed",
+ "http://bitlove.org/moepmoeporg/emcast/feed",
+ "http://bitlove.org/moepmoeporg/fhainalex/feed",
+ "http://bitlove.org/moepmoeporg/fruehstueck/feed",
+ "http://bitlove.org/moepmoeporg/galanoir/feed",
+ "http://bitlove.org/moepmoeporg/julespodcasts/feed",
+ "http://bitlove.org/moepmoeporg/knorkpod/feed",
+ "http://bitlove.org/moepmoeporg/lecast/feed",
+ "http://bitlove.org/moepmoeporg/moepspezial/feed",
+ "http://bitlove.org/moepmoeporg/podsprech/feed",
+ "http://bitlove.org/moepmoeporg/pottcast/feed",
+ "http://bitlove.org/moepmoeporg/riotburnz/feed",
+ "http://bitlove.org/moepmoeporg/schachcast/feed",
+ "http://bitlove.org/moepmoeporg/sundaymoaning/feed",
+ "http://bitlove.org/motofunk/anekdotkast/feed",
+ "http://bitlove.org/motofunk/motofunk/feed",
+ "http://bitlove.org/netzpolitik/netzpolitik-podcast/feed",
+ "http://bitlove.org/netzpolitik/netzpolitik-tv/feed",
+ "http://bitlove.org/nischenkultur/soziopod/feed",
+ "http://bitlove.org/nitramred/staatsbuergerkunde/feed",
+ "http://bitlove.org/nitramred/staatsbuergerkunde-mp3/feed",
+ "http://bitlove.org/nsemak/elementarfragen/feed",
+ "http://bitlove.org/nsemak/mikrodilettanten/feed",
+ "http://bitlove.org/oaad/oaad/feed",
+ "http://bitlove.org/ohrkrampfteam/ohr/feed",
+ "http://bitlove.org/omegatau/all/feed",
+ "http://bitlove.org/omegatau/english-only/feed",
+ "http://bitlove.org/omegatau/german-only/feed",
+ "http://bitlove.org/onatcer/oal/feed",
+ "http://bitlove.org/panikcast/panikcast/feed",
+ "http://bitlove.org/panxatony/macnemotv/feed",
+ "http://bitlove.org/pattex/megamagisch_m4a/feed",
+ "http://bitlove.org/pattex/megamagisch_mp3/feed",
+ "http://bitlove.org/pausengespraeche/pausengespraeche/feed",
+ "http://bitlove.org/pck/ez-und-geschlecht/feed",
+ "http://bitlove.org/pck/gender-kolleg-marburg/feed",
+ "http://bitlove.org/pck/genderzentrum_mr/feed",
+ "http://bitlove.org/pck/hh/feed",
+ "http://bitlove.org/pck/hh_mp3/feed",
+ "http://bitlove.org/pck/hh_ogg/feed",
+ "http://bitlove.org/pck/intercast/feed",
+ "http://bitlove.org/pck/peachnerdznohero/feed",
+ "http://bitlove.org/pck/peachnerdznohero_mp3/feed",
+ "http://bitlove.org/philip/einfach-schwul/feed",
+ "http://bitlove.org/philip/faselcast2/feed",
+ "http://bitlove.org/philipbanse/kuechenradio/feed",
+ "http://bitlove.org/philipbanse/medienradio/feed",
+ "http://bitlove.org/philipbanse/studienwahl_tv_audio/feed",
+ "http://bitlove.org/philipbanse/studienwahl_tv_video/feed",
+ "http://bitlove.org/podsafepilot/pmp/feed",
+ "http://bitlove.org/podsafepilot/psid/feed",
+ "http://bitlove.org/pratfm/strunt/feed",
+ "http://bitlove.org/pressrecord/podcast/feed",
+ "http://bitlove.org/qbi/datenkanal-mp3/feed",
+ "http://bitlove.org/qbi/datenkanal-ogg/feed",
+ "http://bitlove.org/quotidianitaet/quotidianitaet/feed",
+ "http://bitlove.org/radiotux/radiotux-all/feed",
+ "http://bitlove.org/randgruppenfunk/mediale_subkultur/feed",
+ "http://bitlove.org/ranzzeit/ranz/feed",
+ "http://bitlove.org/relet/lifeartificial_partone/feed",
+ "http://bitlove.org/retinacast/pilotenpruefung/feed",
+ "http://bitlove.org/retinacast/podcast/feed",
+ "http://bitlove.org/retinacast/podcast-aac/feed",
+ "http://bitlove.org/retinacast/retinauten/feed",
+ "http://bitlove.org/retinacast/rtc/feed",
+ "http://bitlove.org/revolutionarts/mehrspielerquote/feed",
+ "http://bitlove.org/ronsens/machtdose/feed",
+ "http://bitlove.org/rooby/fressefreiheit/feed",
+ "http://bitlove.org/rundumpodcast/rundum/feed",
+ "http://bitlove.org/ryuu/riesencast/feed",
+ "http://bitlove.org/ryuu/ryuus_labercast/feed",
+ "http://bitlove.org/schmalsprech/schmalsprech_m4a/feed",
+ "http://bitlove.org/schmalsprech/schmalsprech_mp3/feed",
+ "http://bitlove.org/schmidtlepp/houroflauer/feed",
+ "http://bitlove.org/schmidtlepp/lauerinformiert/feed",
+ "http://bitlove.org/sebastiansimon/wertungsfrei/feed",
+ "http://bitlove.org/sebseb7/vimeo/feed",
+ "http://bitlove.org/sirtomate/comichoehle/feed",
+ "http://bitlove.org/smartphone7/windowsphonepodcast/feed",
+ "http://bitlove.org/smcpodcast/feed/feed",
+ "http://bitlove.org/sneakpod/cocktailpodcast/feed",
+ "http://bitlove.org/sneakpod/sneakpod/feed",
+ "http://bitlove.org/socialhack/hoerensagen/feed",
+ "http://bitlove.org/socialhack/netzkinder/feed",
+ "http://bitlove.org/socialhack/netzkinder_mp3/feed",
+ "http://bitlove.org/socialhack/netzkinder_ogg/feed",
+ "http://bitlove.org/socialhack/talking_anthropology/feed",
+ "http://bitlove.org/sprechwaisen/sw/feed",
+ "http://bitlove.org/sublab/aboutradio/feed",
+ "http://bitlove.org/sysops/elektrisch/feed",
+ "http://bitlove.org/sysops/hd/feed",
+ "http://bitlove.org/taschencasts/taschencasts/feed",
+ "http://bitlove.org/tcmanila/ae-podcast/feed",
+ "http://bitlove.org/teezeit/kulturbuechse/feed",
+ "http://bitlove.org/teezeit/kulturbuechse-mp3/feed",
+ "http://bitlove.org/teezeit/teezeittalkradio/feed",
+ "http://bitlove.org/teezeit/teezeittalkradio-mp3/feed",
+ "http://bitlove.org/tinkengil/playtogether/feed",
+ "http://bitlove.org/tobi_s/alleswirdgut/feed",
+ "http://bitlove.org/toby/einschlafenenhanced/feed",
+ "http://bitlove.org/toby/einschlafenpodcast/feed",
+ "http://bitlove.org/toby/pubkameraden/feed",
+ "http://bitlove.org/toby/pubkameradenaac/feed",
+ "http://bitlove.org/tom/radioanstalt/feed",
+ "http://bitlove.org/tvallgaeu/beitraege/feed",
+ "http://bitlove.org/tvallgaeu/freizeit/feed",
+ "http://bitlove.org/tvallgaeu/sendung/feed",
+ "http://bitlove.org/ubahnverleih/teepodcast/feed",
+ "http://bitlove.org/umunsherum/sammelcast/feed",
+ "http://bitlove.org/umunsherum/spielonauten/feed",
+ "http://bitlove.org/umunsherum/unteruns/feed",
+ "http://bitlove.org/umunsherum/wasmachstdu/feed",
+ "http://bitlove.org/uwe/nettesfrettchen/feed",
+ "http://bitlove.org/webdev/wdr/feed",
+ "http://bitlove.org/weezerle/brandung/feed",
+ "http://bitlove.org/weezerle/guestcast/feed",
+ "http://bitlove.org/weezerle/stupalog/feed",
+ "http://bitlove.org/wikigeeks/mp3/feed",
+ "http://bitlove.org/workingdraft/revisionen/feed",
+ "http://bitlove.org/wunderlich/podcast/feed",
+ "http://www.guardian.co.uk/global-development/series/global-development-podcast/rss",
+ "http://rss.sciam.com/sciam/60secsciencepodcast",
+ "http://rss.sciam.com/sciam/60-second-mind",
+ "http://rss.sciam.com/sciam/60-second-space",
+ "http://rss.sciam.com/sciam/60-second-health",
+ "http://rss.sciam.com/sciam/60-second-tech",
+ "http://risky.biz/feeds/risky-business",
+ "http://risky.biz/feeds/rb2",
+ "http://podcast.hr-online.de/lateline/podcast.xml",
+ "http://bitlove.org/nsemak/mikrodilettanten/feed",
+ "http://bitlove.org/moepmoeporg/riotburnz/feed",
+ "http://bitlove.org/moepmoeporg/schachcast/feed",
+ "http://bitlove.org/moepmoeporg/sundaymoaning/feed",
+ "http://bitlove.org/motofunk/anekdotkast/feed",
+ "http://bitlove.org/motofunk/motofunk/feed",
+ "http://podcast.homerj.de/podcasts.xml",
+ "http://www.dradio.de/rss/podcast/sendungen/wissenschaftundbildung/",
+ "http://www.dradio.de/rss/podcast/sendungen/wirtschaftundverbraucher/",
+ "http://www.dradio.de/rss/podcast/sendungen/literatur/",
+ "http://www.dradio.de/rss/podcast/sendungen/sport/",
+ "http://www.dradio.de/rss/podcast/sendungen/wirtschaftundgesellschaft/",
+ "http://www.dradio.de/rss/podcast/sendungen/filmederwoche/",
+ "http://www.blacksweetstories.com/feed/podcast/",
+ "http://feeds.5by5.tv/buildanalyze",
+ "http://bitlove.org/ranzzeit/ranz/feed",
+ "http://bitlove.org/importthis/mp3/feed",
+ "http://bitlove.org/astro/youtube/feed",
+ "http://bitlove.org/channelcast/channelcast/feed",
+ "http://bitlove.org/cccb/chaosradio/feed",
+ "http://bitlove.org/astro/bitlove-show/feed",
+ "http://feeds.thisamericanlife.org/talpodcast",
+ "http://www.casasola.de/137b/1337motiv/1337motiv.xml",
+ "http://alternativlos.org/ogg.rss", "http://www.bitsundso.de/feed",
+ "http://www.gamesundso.de/feed/",
+ "http://feeds.feedburner.com/cre-podcast",
+ "http://feeds.feedburner.com/NotSafeForWorkPodcast",
+ "http://feeds.feedburner.com/mobile-macs-podcast",
+ "http://www.gamesundso.de/feed/",
+ "http://feeds.feedburner.com/DerLautsprecher",
+ "http://feeds.feedburner.com/raumzeit-podcast",
+ "http://feeds.feedburner.com/TheLunaticFringe",
+ "http://feeds.feedburner.com/Kuechenradioorg",
+ "http://feeds.feedburner.com/Medienradio_Podcast_RSS",
+ "http://feeds.feedburner.com/wrint/wrint",
+ "http://retrozirkel.de/episodes.mp3.rss",
+ "http://trackback.fritz.de/?feed=podcast",
+ "http://feeds.feedburner.com/linuxoutlaws-ogg",
+ "http://www.mevio.com/feeds/noagenda.xml",
+ "http://podcast.hr2.de/derTag/podcast.xml",
+ "http://feeds.feedburner.com/thechangelog",
+ "http://leoville.tv/podcasts/floss.xml",
+ "http://www.radiotux.de/index.php?/feeds/index.rss2",
+ "http://megamagis.ch/episodes.mp3.rss",
+ "http://www.eurogamer.net/rss/eurogamer_podcast_itunes.rss",
+ "http://bobsonbob.de/?feed=rss2",
+ "http://www.blacksweetstories.com/feed/podcast/",
+ "http://www.eurogamer.net/rss/eurogamer_podcast_itunes.rss",
+ "http://diehoppeshow.de/podcast/feed.xml",
+ "http://feeds.feedburner.com/ThisIsMyNextPodcast?format=xml",
+ "http://bitlove.org/343max/maerchenstunde/feed",
+ "http://bitlove.org/343max/wmr-aac/feed",
+ "http://bitlove.org/343max/wmr-mp3/feed",
+ "http://bitlove.org/343max/wmr-oga/feed",
+ "http://bitlove.org/adamc1999/noagenda/feed",
+ "http://bitlove.org/alexbrueckel/normalzeit_podcast/feed",
+ "http://bitlove.org/alexbrueckel/normalzeit_podcast_mp3/feed",
+ "http://bitlove.org/alexbrueckel/tisch3-podcast/feed",
+ "http://bitlove.org/alexolma/iphoneblog/feed",
+ "http://www.cczwei.de/rss_tvissues.php" };
+}
diff --git a/src/instrumentationTest/de/test/antennapod/util/FilenameGeneratorTest.java b/src/instrumentationTest/de/test/antennapod/util/FilenameGeneratorTest.java
new file mode 100644
index 000000000..552d34941
--- /dev/null
+++ b/src/instrumentationTest/de/test/antennapod/util/FilenameGeneratorTest.java
@@ -0,0 +1,59 @@
+package instrumentationTest.de.test.antennapod.util;
+
+import java.io.File;
+import java.io.IOException;
+
+import de.danoeh.antennapod.util.FileNameGenerator;
+import android.test.AndroidTestCase;
+
+public class FilenameGeneratorTest extends AndroidTestCase {
+
+ private static final String VALID1 = "abc abc";
+ private static final String INVALID1 = "ab/c: <abc";
+ private static final String INVALID2 = "abc abc ";
+
+ public FilenameGeneratorTest() {
+ super();
+ }
+
+ public void testGenerateFileName() throws IOException {
+ String result = FileNameGenerator.generateFileName(VALID1);
+ assertEquals(result, VALID1);
+ createFiles(result);
+ }
+
+ public void testGenerateFileName1() throws IOException {
+ String result = FileNameGenerator.generateFileName(INVALID1);
+ assertEquals(result, VALID1);
+ createFiles(result);
+ }
+
+ public void testGenerateFileName2() throws IOException {
+ String result = FileNameGenerator.generateFileName(INVALID2);
+ assertEquals(result, VALID1);
+ createFiles(result);
+ }
+
+ /**
+ * Tests if files can be created.
+ *
+ * @throws IOException
+ */
+ private void createFiles(String name) throws IOException {
+ File cache = getContext().getExternalCacheDir();
+ File testFile = new File(cache, name);
+ testFile.mkdir();
+ assertTrue(testFile.exists());
+ testFile.delete();
+ assertTrue(testFile.createNewFile());
+
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ File f = new File(getContext().getExternalCacheDir(), VALID1);
+ f.delete();
+ }
+
+}