summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorHerbert Reiter <46045854+damoasda@users.noreply.github.com>2021-02-28 14:16:07 +0100
committerGitHub <noreply@github.com>2021-02-28 14:16:07 +0100
commit47a0336c3e5cb4c370ad2612de3e8ba6605f6871 (patch)
tree0e3e4b74388e01c4161a94937d43bf3320d73011 /core
parent6e76dcea3d1b33c75a32b181e83e2f0d94085701 (diff)
downloadAntennaPod-47a0336c3e5cb4c370ad2612de3e8ba6605f6871.zip
Refactoring: Remove Cursor related code from Feed class (#4968)
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java77
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java3
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java13
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapper.java70
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapperTest.java100
6 files changed, 201 insertions, 65 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
index da946cf0b..dd8a466eb 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/feed/Feed.java
@@ -1,6 +1,5 @@
package de.danoeh.antennapod.core.feed;
-import android.database.Cursor;
import android.text.TextUtils;
import androidx.annotation.Nullable;
@@ -9,11 +8,10 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
-import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.SortOrder;
/**
- * Data Object for a whole feed
+ * Data Object for a whole feed.
*
* @author daniel
*/
@@ -24,9 +22,14 @@ public class Feed extends FeedFile {
public static final String TYPE_ATOM1 = "atom";
public static final String PREFIX_LOCAL_FOLDER = "antennapod_local:";
- /* title as defined by the feed */
+ /**
+ * title as defined by the feed.
+ */
private String feedTitle;
- /* custom title set by the user */
+
+ /**
+ * custom title set by the user.
+ */
private String customTitle;
/**
@@ -40,25 +43,25 @@ public class Feed extends FeedFile {
private String description;
private String language;
/**
- * Name of the author
+ * Name of the author.
*/
private String author;
private String imageUrl;
private List<FeedItem> items;
/**
- * String that identifies the last update (adopted from Last-Modified or ETag header)
+ * String that identifies the last update (adopted from Last-Modified or ETag header).
*/
private String lastUpdate;
private String paymentLink;
/**
- * Feed type, for example RSS 2 or Atom
+ * Feed type, for example RSS 2 or Atom.
*/
private String type;
/**
- * Feed preferences
+ * Feed preferences.
*/
private FeedPreferences preferences;
@@ -120,7 +123,7 @@ public class Feed extends FeedFile {
this.paged = paged;
this.nextPageLink = nextPageLink;
this.items = new ArrayList<>();
- if(filter != null) {
+ if (filter != null) {
this.itemfilter = new FeedItemFilter(filter);
} else {
this.itemfilter = new FeedItemFilter(new String[0]);
@@ -130,7 +133,7 @@ public class Feed extends FeedFile {
}
/**
- * This constructor is used for test purposes
+ * This constructor is used for test purposes.
*/
public Feed(long id, String lastUpdate, String title, String link, String description, String paymentLink,
String author, String language, String type, String feedIdentifier, String imageUrl, String fileUrl,
@@ -173,56 +176,6 @@ public class Feed extends FeedFile {
preferences = new FeedPreferences(0, true, FeedPreferences.AutoDeleteAction.GLOBAL, VolumeAdaptionSetting.OFF, username, password);
}
- public static Feed fromCursor(Cursor cursor) {
- int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
- int indexLastUpdate = cursor.getColumnIndex(PodDBAdapter.KEY_LASTUPDATE);
- int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
- int indexCustomTitle = cursor.getColumnIndex(PodDBAdapter.KEY_CUSTOM_TITLE);
- int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
- int indexDescription = cursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION);
- int indexPaymentLink = cursor.getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK);
- int indexAuthor = cursor.getColumnIndex(PodDBAdapter.KEY_AUTHOR);
- int indexLanguage = cursor.getColumnIndex(PodDBAdapter.KEY_LANGUAGE);
- int indexType = cursor.getColumnIndex(PodDBAdapter.KEY_TYPE);
- int indexFeedIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_FEED_IDENTIFIER);
- int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
- int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
- int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
- int indexIsPaged = cursor.getColumnIndex(PodDBAdapter.KEY_IS_PAGED);
- int indexNextPageLink = cursor.getColumnIndex(PodDBAdapter.KEY_NEXT_PAGE_LINK);
- int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE);
- int indexSortOrder = cursor.getColumnIndex(PodDBAdapter.KEY_SORT_ORDER);
- int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED);
- int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL);
-
- Feed feed = new Feed(
- cursor.getLong(indexId),
- cursor.getString(indexLastUpdate),
- cursor.getString(indexTitle),
- cursor.getString(indexCustomTitle),
- cursor.getString(indexLink),
- cursor.getString(indexDescription),
- cursor.getString(indexPaymentLink),
- cursor.getString(indexAuthor),
- cursor.getString(indexLanguage),
- cursor.getString(indexType),
- cursor.getString(indexFeedIdentifier),
- cursor.getString(indexImageUrl),
- cursor.getString(indexFileUrl),
- cursor.getString(indexDownloadUrl),
- cursor.getInt(indexDownloaded) > 0,
- cursor.getInt(indexIsPaged) > 0,
- cursor.getString(indexNextPageLink),
- cursor.getString(indexHide),
- SortOrder.fromCodeString(cursor.getString(indexSortOrder)),
- cursor.getInt(indexLastUpdateFailed) > 0
- );
-
- FeedPreferences preferences = FeedPreferences.fromCursor(cursor);
- feed.setPreferences(preferences);
- return feed;
- }
-
/**
* Returns the item at the specified index.
*
@@ -382,7 +335,7 @@ public class Feed extends FeedFile {
}
public void setCustomTitle(String customTitle) {
- if(customTitle == null || customTitle.equals(feedTitle)) {
+ if (customTitle == null || customTitle.equals(feedTitle)) {
this.customTitle = null;
} else {
this.customTitle = customTitle;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
index 27f08243f..fcf61b070 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBReader.java
@@ -23,6 +23,7 @@ import de.danoeh.antennapod.core.feed.FeedPreferences;
import de.danoeh.antennapod.core.feed.SubscriptionsFilter;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
+import de.danoeh.antennapod.core.storage.mapper.FeedCursorMapper;
import de.danoeh.antennapod.core.util.LongIntMap;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.comparator.DownloadStatusComparator;
@@ -204,7 +205,7 @@ public final class DBReader {
}
private static Feed extractFeedFromCursorRow(Cursor cursor) {
- Feed feed = Feed.fromCursor(cursor);
+ Feed feed = FeedCursorMapper.convert(cursor);
FeedPreferences preferences = FeedPreferences.fromCursor(cursor);
feed.setPreferences(preferences);
return feed;
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index f5a8fb07a..596ab624e 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -19,6 +19,7 @@ import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.LocalFeedUpdater;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.download.DownloadStatus;
+import de.danoeh.antennapod.core.storage.mapper.FeedCursorMapper;
import de.danoeh.antennapod.core.sync.SyncService;
import de.danoeh.antennapod.core.util.DownloadError;
import de.danoeh.antennapod.core.util.LongList;
@@ -516,7 +517,7 @@ public final class DBTasks {
List<Feed> items = new ArrayList<>();
if (cursor.moveToFirst()) {
do {
- items.add(Feed.fromCursor(cursor));
+ items.add(FeedCursorMapper.convert(cursor));
} while (cursor.moveToNext());
}
setResult(items);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
index 8d1352a10..adb5e6a74 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/PodDBAdapter.java
@@ -15,6 +15,7 @@ import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import de.danoeh.antennapod.core.storage.mapper.FeedItemFilterQuery;
import org.apache.commons.io.FileUtils;
@@ -372,6 +373,7 @@ public class PodDBAdapter {
* For more information see
* <a href="https://github.com/robolectric/robolectric/issues/1890">robolectric/robolectric#1890</a>.</p>
*/
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
public static void tearDownTests() {
getInstance().dbHelper.close();
instance = null;
@@ -1379,7 +1381,16 @@ public class PodDBAdapter {
}
/**
- * Called when a database corruption happens
+ * Insert raw data to the database. *
+ * Call method only for unit tests.
+ */
+ @VisibleForTesting(otherwise = VisibleForTesting.NONE)
+ public void insertTestData(@NonNull String table, @NonNull ContentValues values) {
+ db.insert(table, null, values);
+ }
+
+ /**
+ * Called when a database corruption happens.
*/
public static class PodDbErrorHandler implements DatabaseErrorHandler {
@Override
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapper.java b/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapper.java
new file mode 100644
index 000000000..783fba596
--- /dev/null
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapper.java
@@ -0,0 +1,70 @@
+package de.danoeh.antennapod.core.storage.mapper;
+
+import android.database.Cursor;
+
+import androidx.annotation.NonNull;
+
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.feed.FeedPreferences;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.core.util.SortOrder;
+
+/**
+ * Converts a {@link Cursor} to a {@link Feed} object.
+ */
+public abstract class FeedCursorMapper {
+
+ /**
+ * Create a {@link Feed} instance from a database row (cursor).
+ */
+ @NonNull
+ public static Feed convert(@NonNull Cursor cursor) {
+ int indexId = cursor.getColumnIndex(PodDBAdapter.KEY_ID);
+ int indexLastUpdate = cursor.getColumnIndex(PodDBAdapter.KEY_LASTUPDATE);
+ int indexTitle = cursor.getColumnIndex(PodDBAdapter.KEY_TITLE);
+ int indexCustomTitle = cursor.getColumnIndex(PodDBAdapter.KEY_CUSTOM_TITLE);
+ int indexLink = cursor.getColumnIndex(PodDBAdapter.KEY_LINK);
+ int indexDescription = cursor.getColumnIndex(PodDBAdapter.KEY_DESCRIPTION);
+ int indexPaymentLink = cursor.getColumnIndex(PodDBAdapter.KEY_PAYMENT_LINK);
+ int indexAuthor = cursor.getColumnIndex(PodDBAdapter.KEY_AUTHOR);
+ int indexLanguage = cursor.getColumnIndex(PodDBAdapter.KEY_LANGUAGE);
+ int indexType = cursor.getColumnIndex(PodDBAdapter.KEY_TYPE);
+ int indexFeedIdentifier = cursor.getColumnIndex(PodDBAdapter.KEY_FEED_IDENTIFIER);
+ int indexFileUrl = cursor.getColumnIndex(PodDBAdapter.KEY_FILE_URL);
+ int indexDownloadUrl = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOAD_URL);
+ int indexDownloaded = cursor.getColumnIndex(PodDBAdapter.KEY_DOWNLOADED);
+ int indexIsPaged = cursor.getColumnIndex(PodDBAdapter.KEY_IS_PAGED);
+ int indexNextPageLink = cursor.getColumnIndex(PodDBAdapter.KEY_NEXT_PAGE_LINK);
+ int indexHide = cursor.getColumnIndex(PodDBAdapter.KEY_HIDE);
+ int indexSortOrder = cursor.getColumnIndex(PodDBAdapter.KEY_SORT_ORDER);
+ int indexLastUpdateFailed = cursor.getColumnIndex(PodDBAdapter.KEY_LAST_UPDATE_FAILED);
+ int indexImageUrl = cursor.getColumnIndex(PodDBAdapter.KEY_IMAGE_URL);
+
+ Feed feed = new Feed(
+ cursor.getLong(indexId),
+ cursor.getString(indexLastUpdate),
+ cursor.getString(indexTitle),
+ cursor.getString(indexCustomTitle),
+ cursor.getString(indexLink),
+ cursor.getString(indexDescription),
+ cursor.getString(indexPaymentLink),
+ cursor.getString(indexAuthor),
+ cursor.getString(indexLanguage),
+ cursor.getString(indexType),
+ cursor.getString(indexFeedIdentifier),
+ cursor.getString(indexImageUrl),
+ cursor.getString(indexFileUrl),
+ cursor.getString(indexDownloadUrl),
+ cursor.getInt(indexDownloaded) > 0,
+ cursor.getInt(indexIsPaged) > 0,
+ cursor.getString(indexNextPageLink),
+ cursor.getString(indexHide),
+ SortOrder.fromCodeString(cursor.getString(indexSortOrder)),
+ cursor.getInt(indexLastUpdateFailed) > 0
+ );
+
+ FeedPreferences preferences = FeedPreferences.fromCursor(cursor);
+ feed.setPreferences(preferences);
+ return feed;
+ }
+}
diff --git a/core/src/test/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapperTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapperTest.java
new file mode 100644
index 000000000..c779b6d55
--- /dev/null
+++ b/core/src/test/java/de/danoeh/antennapod/core/storage/mapper/FeedCursorMapperTest.java
@@ -0,0 +1,100 @@
+package de.danoeh.antennapod.core.storage.mapper;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import de.danoeh.antennapod.core.feed.Feed;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+@RunWith(RobolectricTestRunner.class)
+public class FeedCursorMapperTest {
+ private PodDBAdapter adapter;
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getInstrumentation().getContext();
+
+ PodDBAdapter.init(context);
+ adapter = PodDBAdapter.getInstance();
+
+ writeFeedToDatabase();
+ }
+
+ @After
+ public void tearDown() {
+ PodDBAdapter.tearDownTests();
+ }
+
+ @SuppressWarnings("ConstantConditions")
+ @Test
+ public void testFromCursor() {
+ try (Cursor cursor = adapter.getAllFeedsCursor()) {
+ cursor.moveToNext();
+ Feed feed = FeedCursorMapper.convert(cursor);
+ assertTrue(feed.getId() >= 0);
+ assertEquals("feed custom title", feed.getTitle());
+ assertEquals("feed custom title", feed.getCustomTitle());
+ assertEquals("feed link", feed.getLink());
+ assertEquals("feed description", feed.getDescription());
+ assertEquals("feed payment link", feed.getPaymentLink());
+ assertEquals("feed author", feed.getAuthor());
+ assertEquals("feed language", feed.getLanguage());
+ assertEquals("feed image url", feed.getImageUrl());
+ assertEquals("feed file url", feed.getFile_url());
+ assertEquals("feed download url", feed.getDownload_url());
+ assertTrue(feed.isDownloaded());
+ assertEquals("feed last update", feed.getLastUpdate());
+ assertEquals("feed type", feed.getType());
+ assertEquals("feed identifier", feed.getFeedIdentifier());
+ assertTrue(feed.isPaged());
+ assertEquals("feed next page link", feed.getNextPageLink());
+ assertTrue(feed.getItemFilter().showUnplayed);
+ assertEquals(1, feed.getSortOrder().code);
+ assertTrue(feed.hasLastUpdateFailed());
+ }
+ }
+
+ /**
+ * Insert test data to the database.
+ * Uses raw database insert instead of adapter.setCompleteFeed() to avoid testing the Feed class
+ * against itself.
+ */
+ private void writeFeedToDatabase() {
+ ContentValues values = new ContentValues();
+ values.put(PodDBAdapter.KEY_TITLE, "feed title");
+ values.put(PodDBAdapter.KEY_CUSTOM_TITLE, "feed custom title");
+ values.put(PodDBAdapter.KEY_LINK, "feed link");
+ values.put(PodDBAdapter.KEY_DESCRIPTION, "feed description");
+ values.put(PodDBAdapter.KEY_PAYMENT_LINK, "feed payment link");
+ values.put(PodDBAdapter.KEY_AUTHOR, "feed author");
+ values.put(PodDBAdapter.KEY_LANGUAGE, "feed language");
+ values.put(PodDBAdapter.KEY_IMAGE_URL, "feed image url");
+
+ values.put(PodDBAdapter.KEY_FILE_URL, "feed file url");
+ values.put(PodDBAdapter.KEY_DOWNLOAD_URL, "feed download url");
+ values.put(PodDBAdapter.KEY_DOWNLOADED, true);
+ values.put(PodDBAdapter.KEY_LASTUPDATE, "feed last update");
+ values.put(PodDBAdapter.KEY_TYPE, "feed type");
+ values.put(PodDBAdapter.KEY_FEED_IDENTIFIER, "feed identifier");
+
+ values.put(PodDBAdapter.KEY_IS_PAGED, true);
+ values.put(PodDBAdapter.KEY_NEXT_PAGE_LINK, "feed next page link");
+ values.put(PodDBAdapter.KEY_HIDE, "unplayed");
+ values.put(PodDBAdapter.KEY_SORT_ORDER, "1");
+ values.put(PodDBAdapter.KEY_LAST_UPDATE_FAILED, true);
+
+ adapter.insertTestData(PodDBAdapter.TABLE_NAME_FEEDS, values);
+ }
+}