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.antennapodsp.feed.Feed;
import de.danoeh.antennapodsp.feed.FeedItem;
import de.danoeh.antennapodsp.feed.FeedMedia;
import de.danoeh.antennapodsp.preferences.UserPreferences;
import de.danoeh.antennapodsp.storage.DBReader;
import de.danoeh.antennapodsp.storage.DBTasks;
import de.danoeh.antennapodsp.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;
import static instrumentationTest.de.test.antennapod.storage.DBTestUtils.saveFeedlist;
/**
* 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());
}
}
/**
* 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);
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();
}
}
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);
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);
}
}