diff options
Diffstat (limited to 'app/src/androidTest/java/de/test/antennapod/storage')
4 files changed, 1587 insertions, 0 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java new file mode 100644 index 000000000..a96c9a6d3 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBReaderTest.java @@ -0,0 +1,408 @@ +package de.test.antennapod.storage; + +import android.content.Context; +import android.test.InstrumentationTestCase; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.storage.FeedItemStatistics; +import de.danoeh.antennapod.core.storage.PodDBAdapter; +import de.danoeh.antennapod.core.util.flattr.FlattrStatus; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Random; + +import static de.test.antennapod.storage.DBTestUtils.saveFeedlist; + +/** + * Test class for DBReader + */ +public class DBReaderTest extends InstrumentationTestCase { + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + final Context context = getInstrumentation().getTargetContext(); + assertTrue(PodDBAdapter.deleteDatabase(context)); + } + + @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(); + } + + private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) { + final Context context = getInstrumentation().getTargetContext(); + Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null, + null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null); + feed.setItems(new ArrayList<FeedItem>()); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setCompleteFeed(feed); + adapter.close(); + + assertTrue(feed.getId() != 0); + List<Feed> expiredFeeds = DBReader.getExpiredFeedsList(context, expirationTime); + assertNotNull(expiredFeeds); + if (shouldReturn) { + assertTrue(expiredFeeds.size() == 1); + assertTrue(expiredFeeds.get(0).getId() == feed.getId()); + } else { + assertTrue(expiredFeeds.isEmpty()); + } + } + + public void testGetExpiredFeedsListShouldReturnFeed() { + final long expirationTime = 1000 * 60 * 60; // 1 hour + expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime - 1, expirationTime, true); + } + + public void testGetExpiredFeedsListShouldNotReturnFeed() { + final long expirationTime = 1000 * 60 * 60; // 1 hour + expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime / 2, expirationTime, false); + } + + + public void testGetFeedList() { + final Context context = getInstrumentation().getTargetContext(); + List<Feed> feeds = saveFeedlist(context, 10, 0, false); + List<Feed> savedFeeds = DBReader.getFeedList(context); + assertNotNull(savedFeeds); + assertEquals(feeds.size(), savedFeeds.size()); + for (int i = 0; i < feeds.size(); i++) { + assertTrue(savedFeeds.get(i).getId() == feeds.get(i).getId()); + } + } + + public void testGetFeedListSortOrder() { + final Context context = getInstrumentation().getTargetContext(); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + + Feed feed1 = new Feed(0, new Date(), "A", "link", "d", null, null, null, "rss", "A", null, "", "", true); + Feed feed2 = new Feed(0, new Date(), "b", "link", "d", null, null, null, "rss", "b", null, "", "", true); + Feed feed3 = new Feed(0, new Date(), "C", "link", "d", null, null, null, "rss", "C", null, "", "", true); + Feed feed4 = new Feed(0, new Date(), "d", "link", "d", null, null, null, "rss", "d", null, "", "", true); + adapter.setCompleteFeed(feed1); + adapter.setCompleteFeed(feed2); + adapter.setCompleteFeed(feed3); + adapter.setCompleteFeed(feed4); + assertTrue(feed1.getId() != 0); + assertTrue(feed2.getId() != 0); + assertTrue(feed3.getId() != 0); + assertTrue(feed4.getId() != 0); + + adapter.close(); + + List<Feed> saved = DBReader.getFeedList(context); + assertNotNull(saved); + assertEquals("Wrong size: ", 4, saved.size()); + + assertEquals("Wrong id of feed 1: ", feed1.getId(), saved.get(0).getId()); + assertEquals("Wrong id of feed 2: ", feed2.getId(), saved.get(1).getId()); + assertEquals("Wrong id of feed 3: ", feed3.getId(), saved.get(2).getId()); + assertEquals("Wrong id of feed 4: ", feed4.getId(), saved.get(3).getId()); + } + + public void testFeedListDownloadUrls() { + final Context context = getInstrumentation().getTargetContext(); + List<Feed> feeds = saveFeedlist(context, 10, 0, false); + List<String> urls = DBReader.getFeedListDownloadUrls(context); + assertNotNull(urls); + assertTrue(urls.size() == feeds.size()); + for (int i = 0; i < urls.size(); i++) { + assertEquals(urls.get(i), feeds.get(i).getDownload_url()); + } + } + + public void testLoadFeedDataOfFeedItemlist() { + final Context context = getInstrumentation().getTargetContext(); + final int numFeeds = 10; + final int numItems = 1; + List<Feed> feeds = saveFeedlist(context, numFeeds, numItems, false); + List<FeedItem> items = new ArrayList<FeedItem>(); + for (Feed f : feeds) { + for (FeedItem item : f.getItems()) { + item.setFeed(null); + item.setFeedId(f.getId()); + items.add(item); + } + } + DBReader.loadFeedDataOfFeedItemlist(context, items); + for (int i = 0; i < numFeeds; i++) { + for (int j = 0; j < numItems; j++) { + FeedItem item = feeds.get(i).getItems().get(j); + assertNotNull(item.getFeed()); + assertTrue(item.getFeed().getId() == feeds.get(i).getId()); + assertTrue(item.getFeedId() == item.getFeed().getId()); + } + } + } + + public void testGetFeedItemList() { + final Context context = getInstrumentation().getTargetContext(); + final int numFeeds = 1; + final int numItems = 10; + Feed feed = saveFeedlist(context, numFeeds, numItems, false).get(0); + List<FeedItem> items = feed.getItems(); + feed.setItems(null); + List<FeedItem> savedItems = DBReader.getFeedItemList(context, feed); + assertNotNull(savedItems); + assertTrue(savedItems.size() == items.size()); + for (int i = 0; i < savedItems.size(); i++) { + assertTrue(items.get(i).getId() == savedItems.get(i).getId()); + } + } + + private List<FeedItem> saveQueue(int numItems) { + if (numItems <= 0) { + throw new IllegalArgumentException("numItems<=0"); + } + final Context context = getInstrumentation().getTargetContext(); + List<Feed> feeds = saveFeedlist(context, numItems, numItems, false); + List<FeedItem> allItems = new ArrayList<FeedItem>(); + for (Feed f : feeds) { + allItems.addAll(f.getItems()); + } + // take random items from every feed + Random random = new Random(); + List<FeedItem> queue = new ArrayList<FeedItem>(); + while (queue.size() < numItems) { + int index = random.nextInt(numItems); + if (!queue.contains(allItems.get(index))) { + queue.add(allItems.get(index)); + } + } + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setQueue(queue); + adapter.close(); + return queue; + } + + public void testGetQueueIDList() { + final Context context = getInstrumentation().getTargetContext(); + final int numItems = 10; + List<FeedItem> queue = saveQueue(numItems); + List<Long> ids = DBReader.getQueueIDList(context); + assertNotNull(ids); + assertTrue(queue.size() == ids.size()); + for (int i = 0; i < queue.size(); i++) { + assertTrue(ids.get(i) != 0); + assertTrue(queue.get(i).getId() == ids.get(i)); + } + } + + public void testGetQueue() { + final Context context = getInstrumentation().getTargetContext(); + final int numItems = 10; + List<FeedItem> queue = saveQueue(numItems); + List<FeedItem> savedQueue = DBReader.getQueue(context); + assertNotNull(savedQueue); + assertTrue(queue.size() == savedQueue.size()); + for (int i = 0; i < queue.size(); i++) { + assertTrue(savedQueue.get(i).getId() != 0); + assertTrue(queue.get(i).getId() == savedQueue.get(i).getId()); + } + } + + private List<FeedItem> saveDownloadedItems(int numItems) { + if (numItems <= 0) { + throw new IllegalArgumentException("numItems<=0"); + } + final Context context = getInstrumentation().getTargetContext(); + List<Feed> feeds = saveFeedlist(context, numItems, numItems, true); + List<FeedItem> items = new ArrayList<FeedItem>(); + for (Feed f : feeds) { + items.addAll(f.getItems()); + } + List<FeedItem> downloaded = new ArrayList<FeedItem>(); + Random random = new Random(); + + while (downloaded.size() < numItems) { + int i = random.nextInt(numItems); + if (!downloaded.contains(items.get(i))) { + FeedItem item = items.get(i); + item.getMedia().setDownloaded(true); + item.getMedia().setFile_url("file" + i); + downloaded.add(item); + } + } + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setFeedItemlist(downloaded); + adapter.close(); + return downloaded; + } + + public void testGetDownloadedItems() { + final Context context = getInstrumentation().getTargetContext(); + final int numItems = 10; + List<FeedItem> downloaded = saveDownloadedItems(numItems); + List<FeedItem> downloaded_saved = DBReader.getDownloadedItems(context); + assertNotNull(downloaded_saved); + assertTrue(downloaded_saved.size() == downloaded.size()); + for (FeedItem item : downloaded_saved) { + assertNotNull(item.getMedia()); + assertTrue(item.getMedia().isDownloaded()); + assertNotNull(item.getMedia().getDownload_url()); + } + } + + private List<FeedItem> saveUnreadItems(int numItems) { + if (numItems <= 0) { + throw new IllegalArgumentException("numItems<=0"); + } + final Context context = getInstrumentation().getTargetContext(); + List<Feed> feeds = saveFeedlist(context, numItems, numItems, true); + List<FeedItem> items = new ArrayList<FeedItem>(); + for (Feed f : feeds) { + items.addAll(f.getItems()); + } + List<FeedItem> unread = new ArrayList<FeedItem>(); + Random random = new Random(); + + while (unread.size() < numItems) { + int i = random.nextInt(numItems); + if (!unread.contains(items.get(i))) { + FeedItem item = items.get(i); + item.setRead(false); + unread.add(item); + } + } + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setFeedItemlist(unread); + adapter.close(); + return unread; + } + + public void testGetUnreadItemsList() { + final Context context = getInstrumentation().getTargetContext(); + final int numItems = 10; + + List<FeedItem> unread = saveUnreadItems(numItems); + List<FeedItem> unreadSaved = DBReader.getUnreadItemsList(context); + assertNotNull(unreadSaved); + assertTrue(unread.size() == unreadSaved.size()); + for (FeedItem item : unreadSaved) { + assertFalse(item.isRead()); + } + } + + public void testGetUnreadItemIds() { + final Context context = getInstrumentation().getTargetContext(); + final int numItems = 10; + + List<FeedItem> unread = saveUnreadItems(numItems); + long[] unreadIds = new long[unread.size()]; + for (int i = 0; i < unread.size(); i++) { + unreadIds[i] = unread.get(i).getId(); + } + long[] unreadSaved = DBReader.getUnreadItemIds(context); + assertNotNull(unreadSaved); + assertTrue(unread.size() == unreadSaved.length); + for (long savedId : unreadSaved) { + boolean found = false; + for (long id : unreadIds) { + if (id == savedId) { + found = true; + break; + } + } + assertTrue(found); + } + } + + public void testGetPlaybackHistory() { + final Context context = getInstrumentation().getTargetContext(); + final int numItems = (DBReader.PLAYBACK_HISTORY_SIZE+1) * 2; + final int playedItems = DBReader.PLAYBACK_HISTORY_SIZE + 1; + final int numReturnedItems = Math.min(playedItems, DBReader.PLAYBACK_HISTORY_SIZE); + final int numFeeds = 1; + + Feed feed = DBTestUtils.saveFeedlist(context, numFeeds, numItems, true).get(0); + long[] ids = new long[playedItems]; + + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + for (int i = 0; i < playedItems; i++) { + FeedMedia m = feed.getItems().get(i).getMedia(); + m.setPlaybackCompletionDate(new Date(i + 1)); + adapter.setFeedMediaPlaybackCompletionDate(m); + ids[ids.length - 1 - i] = m.getItem().getId(); + } + adapter.close(); + + List<FeedItem> saved = DBReader.getPlaybackHistory(context); + assertNotNull(saved); + assertEquals("Wrong size: ", numReturnedItems, saved.size()); + for (int i = 0; i < numReturnedItems; i++) { + FeedItem item = saved.get(i); + assertNotNull(item.getMedia().getPlaybackCompletionDate()); + assertEquals("Wrong sort order: ", item.getId(), ids[i]); + } + } + + public void testGetFeedStatisticsCheckOrder() { + final Context context = getInstrumentation().getTargetContext(); + final int NUM_FEEDS = 10; + final int NUM_ITEMS = 10; + List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, false); + List<FeedItemStatistics> statistics = DBReader.getFeedStatisticsList(context); + assertNotNull(statistics); + assertEquals(feeds.size(), statistics.size()); + for (int i = 0; i < NUM_FEEDS; i++) { + assertEquals("Wrong entry at index " + i, feeds.get(i).getId(), statistics.get(i).getFeedID()); + } + } + + public void testGetNavDrawerDataQueueEmptyNoUnreadItems() { + final Context context = getInstrumentation().getTargetContext(); + final int NUM_FEEDS = 10; + final int NUM_ITEMS = 10; + List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, true); + DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(context); + assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); + assertEquals(0, navDrawerData.numUnreadItems); + assertEquals(0, navDrawerData.queueSize); + } + + public void testGetNavDrawerDataQueueNotEmptyWithUnreadItems() { + final Context context = getInstrumentation().getTargetContext(); + final int NUM_FEEDS = 10; + final int NUM_ITEMS = 10; + final int NUM_QUEUE = 1; + final int NUM_UNREAD = 2; + List<Feed> feeds = DBTestUtils.saveFeedlist(context, NUM_FEEDS, NUM_ITEMS, true); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + for (int i = 0; i < NUM_UNREAD; i++) { + FeedItem item = feeds.get(0).getItems().get(i); + item.setRead(false); + adapter.setSingleFeedItem(item); + } + List<FeedItem> queue = new ArrayList<FeedItem>(); + for (int i = 0; i < NUM_QUEUE; i++) { + FeedItem item = feeds.get(1).getItems().get(i); + queue.add(item); + } + adapter.setQueue(queue); + + adapter.close(); + + DBReader.NavDrawerData navDrawerData = DBReader.getNavDrawerData(context); + assertEquals(NUM_FEEDS, navDrawerData.feeds.size()); + assertEquals(NUM_UNREAD, navDrawerData.numUnreadItems); + assertEquals(NUM_QUEUE, navDrawerData.queueSize); + } +} diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java new file mode 100644 index 000000000..e28a7918f --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java @@ -0,0 +1,326 @@ +package de.test.antennapod.storage; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.test.InstrumentationTestCase; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.preferences.UserPreferences; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.storage.DBTasks; +import de.danoeh.antennapod.core.storage.PodDBAdapter; +import de.danoeh.antennapod.core.util.flattr.FlattrStatus; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import static de.test.antennapod.storage.DBTestUtils.*; + +/** + * 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), 0)); + 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), 0)); + 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), 0)); + 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()); + } + } + + /** + * Reproduces a bug where DBTasks.performAutoCleanup(android.content.Context) would use the ID of the FeedItem in the + * call to DBWriter.deleteFeedMediaOfItem instead of the ID of the FeedMedia. This would cause the wrong item to be deleted. + * @throws IOException + */ + public void testPerformAutoCleanupShouldNotDeleteBecauseInQueue_withFeedsWithNoMedia() throws IOException { + final Context context = getInstrumentation().getTargetContext(); + // add feed with no enclosures so that item ID != media ID + saveFeedlist(context, 1, 10, false); + + // add candidate for performAutoCleanup + List<Feed> feeds = saveFeedlist(getInstrumentation().getTargetContext(), 1, 1, true); + FeedMedia m = feeds.get(0).getItems().get(0).getMedia(); + m.setDownloaded(true); + m.setFile_url("file"); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setMedia(m); + adapter.close(); + + testPerformAutoCleanupShouldNotDeleteBecauseInQueue(); + } + + 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)[0]; + + assertTrue(newFeed == feed); + assertTrue(feed.getId() != 0); + for (FeedItem item : feed.getItems()) { + assertFalse(item.isRead()); + assertTrue(item.getId() != 0); + } + } + + /** Two feeds with the same title, but different download URLs should be treated as different feeds. */ + public void testUpdateFeedSameTitle() { + final Context context = getInstrumentation().getTargetContext(); + + Feed feed1 = new Feed("url1", new Date(), "title"); + Feed feed2 = new Feed("url2", new Date(), "title"); + + feed1.setItems(new ArrayList<FeedItem>()); + feed2.setItems(new ArrayList<FeedItem>()); + + Feed savedFeed1 = DBTasks.updateFeed(context, feed1)[0]; + Feed savedFeed2 = DBTasks.updateFeed(context, feed2)[0]; + + assertTrue(savedFeed1.getId() != savedFeed2.getId()); + } + + 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)[0]; + 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(); + } + } + + private void expiredFeedListTestHelper(long lastUpdate, long expirationTime, boolean shouldReturn) { + final Context context = getInstrumentation().getTargetContext(); + UserPreferences.setUpdateInterval(context, expirationTime); + Feed feed = new Feed(0, new Date(lastUpdate), "feed", "link", "descr", null, + null, null, null, "feed", null, null, "url", false, new FlattrStatus(), false, null); + feed.setItems(new ArrayList<FeedItem>()); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + adapter.setCompleteFeed(feed); + adapter.close(); + + assertTrue(feed.getId() != 0); + List<Feed> expiredFeeds = DBTasks.getExpiredFeeds(context); + assertNotNull(expiredFeeds); + if (shouldReturn) { + assertTrue(expiredFeeds.size() == 1); + assertTrue(expiredFeeds.get(0).getId() == feed.getId()); + } else { + assertTrue(expiredFeeds.isEmpty()); + } + } + + public void testGetExpiredFeedsTestShouldReturn() { + final long expirationTime = 1000 * 60 * 60; + expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime - 1, expirationTime, true); + } + + public void testGetExpiredFeedsTestShouldNotReturn() { + final long expirationTime = 1000 * 60 * 60; + expiredFeedListTestHelper(System.currentTimeMillis() - expirationTime / 2, expirationTime, false); + } +} diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java new file mode 100644 index 000000000..9e5f6546d --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java @@ -0,0 +1,57 @@ +package de.test.antennapod.storage; + +import android.content.Context; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.storage.PodDBAdapter; +import de.danoeh.antennapod.core.util.comparator.FeedItemPubdateComparator; +import de.danoeh.antennapod.core.util.flattr.FlattrStatus; +import junit.framework.Assert; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +/** + * Utility methods for DB* tests. + */ +public class DBTestUtils { + + public static List<Feed> saveFeedlist(Context context, int numFeeds, int numItems, boolean withMedia) { + if (numFeeds <= 0) { + throw new IllegalArgumentException("numFeeds<=0"); + } + if (numItems < 0) { + throw new IllegalArgumentException("numItems<0"); + } + + List<Feed> feeds = new ArrayList<Feed>(); + PodDBAdapter adapter = new PodDBAdapter(context); + adapter.open(); + for (int i = 0; i < numFeeds; i++) { + Feed f = new Feed(0, new Date(), "feed " + i, "link" + i, "descr", null, null, + null, null, "id" + i, null, null, "url" + i, false, new FlattrStatus(), false, null); + f.setItems(new ArrayList<FeedItem>()); + for (int j = 0; j < numItems; j++) { + FeedItem item = new FeedItem(0, "item " + j, "id" + j, "link" + j, new Date(), + true, f); + if (withMedia) { + FeedMedia media = new FeedMedia(item, "url" + j, 1, "audio/mp3"); + item.setMedia(media); + } + f.getItems().add(item); + } + Collections.sort(f.getItems(), new FeedItemPubdateComparator()); + adapter.setCompleteFeed(f); + Assert.assertTrue(f.getId() != 0); + for (FeedItem item : f.getItems()) { + Assert.assertTrue(item.getId() != 0); + } + feeds.add(f); + } + adapter.close(); + return feeds; + } +} diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java new file mode 100644 index 000000000..4678a843b --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java @@ -0,0 +1,796 @@ +package de.test.antennapod.storage; + +import android.content.Context; +import android.database.Cursor; +import android.test.InstrumentationTestCase; +import android.util.Log; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedImage; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.feed.FeedMedia; +import de.danoeh.antennapod.core.storage.DBReader; +import de.danoeh.antennapod.core.storage.DBWriter; +import de.danoeh.antennapod.core.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, 0); + 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.setOwner(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, 0); + 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.getImageCursor(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, 0); + 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.setOwner(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.getImageCursor(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.setOwner(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.getImageCursor(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 testDeleteFeedWithItemImages() throws InterruptedException, ExecutionException, TimeoutException, IOException { + 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.setOwner(feed); + feed.setImage(image); + + // create items with images + 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 itemImageFile = new File(destFolder, "item-image-" + i); + FeedImage itemImage = new FeedImage(0, "item-image" + i, itemImageFile.getAbsolutePath(), "url", true); + item.setImage(itemImage); + } + + 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.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.getImageCursor(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.getImageCursor(item.getImage().getId()); + assertEquals(0, c.getCount()); + 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.setOwner(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, 0); + 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.getImageCursor(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.setOwner(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, 0); + 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.getImageCursor(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, 0); + 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() 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.markAllItemsRead(context).get(TIMEOUT, TimeUnit.SECONDS); + List<FeedItem> loadedItems = DBReader.getFeedItemList(context, feed); + for (FeedItem item : loadedItems) { + assertTrue(item.isRead()); + } + } + +} |