diff options
Diffstat (limited to 'src/instrumentationTest/de/test')
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(); + } + +} |