summaryrefslogtreecommitdiff
path: root/core/src/test/java/de/danoeh
diff options
context:
space:
mode:
authorHerbert Reiter <46045854+damoasda@users.noreply.github.com>2020-10-25 17:22:36 +0100
committerGitHub <noreply@github.com>2020-10-25 17:22:36 +0100
commit28ebbedbdf34b72b31c536a118bcf5108b3ea7e5 (patch)
tree7365c90ff91414f610d3c4ba3044537e6577eb99 /core/src/test/java/de/danoeh
parent41580b57cc06c297615bc3484274859bb0c9c5c1 (diff)
downloadAntennaPod-28ebbedbdf34b72b31c536a118bcf5108b3ea7e5.zip
Local feeds: Unit tests for LocalFeedUpdater (#4551)
Diffstat (limited to 'core/src/test/java/de/danoeh')
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java208
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/storage/ItemEnqueuePositionCalculatorTest.java6
2 files changed, 211 insertions, 3 deletions
diff --git a/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java b/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
new file mode 100644
index 000000000..90bf59e92
--- /dev/null
+++ b/core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java
@@ -0,0 +1,208 @@
+package de.danoeh.antennapod.core.feed;
+
+import android.app.Application;
+import android.content.Context;
+import android.media.MediaMetadataRetriever;
+import android.webkit.MimeTypeMap;
+
+import androidx.annotation.NonNull;
+import androidx.documentfile.provider.AssetsDocumentFile;
+import androidx.documentfile.provider.DocumentFile;
+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.mockito.MockedStatic;
+import org.mockito.Mockito;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.shadows.ShadowMediaMetadataRetriever;
+
+import java.io.IOException;
+import java.util.List;
+
+import de.danoeh.antennapod.core.ApplicationCallbacks;
+import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.core.R;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
+
+/**
+ * Test local feeds handling in class LocalFeedUpdater.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class LocalFeedUpdaterTest {
+
+ /**
+ * URL to locate the local feed media files on the external storage (SD card).
+ * The exact URL doesn't matter here as access to external storage is mocked
+ * (seems not to be supported by Robolectric).
+ */
+ private static final String FEED_URL =
+ "content://com.android.externalstorage.documents/tree/primary%3ADownload%2Flocal-feed";
+ private static final String LOCAL_FEED_DIR1 = "local-feed1";
+ private static final String LOCAL_FEED_DIR2 = "local-feed2";
+
+ private Context context;
+
+ @Before
+ public void setUp() throws Exception {
+ // Initialize environment
+ context = InstrumentationRegistry.getInstrumentation().getContext();
+ UserPreferences.init(context);
+
+ Application app = (Application) context;
+ ClientConfig.applicationCallbacks = mock(ApplicationCallbacks.class);
+ when(ClientConfig.applicationCallbacks.getApplicationInstance()).thenReturn(app);
+
+ // Initialize database
+ PodDBAdapter.init(context);
+ PodDBAdapter.deleteDatabase();
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.close();
+
+ mapDummyMetadata(LOCAL_FEED_DIR1);
+ mapDummyMetadata(LOCAL_FEED_DIR2);
+ shadowOf(MimeTypeMap.getSingleton()).addExtensionMimeTypMapping("mp3", "audio/mp3");
+ }
+
+ @After
+ public void tearDown() {
+ PodDBAdapter.tearDownTests();
+ }
+
+ /**
+ * Test adding a new local feed.
+ */
+ @Test
+ public void testUpdateFeed_AddNewFeed() {
+ // check for empty database
+ List<Feed> feedListBefore = DBReader.getFeedList();
+ assertTrue(feedListBefore.isEmpty());
+
+ callUpdateFeed(LOCAL_FEED_DIR2);
+
+ // verify new feed in database
+ verifySingleFeedInDatabaseAndItemCount(2);
+ Feed feedAfter = verifySingleFeedInDatabase();
+ assertEquals(FEED_URL, feedAfter.getDownload_url());
+ }
+
+ /**
+ * Test adding further items to an existing local feed.
+ */
+ @Test
+ public void testUpdateFeed_AddMoreItems() {
+ // add local feed with 1 item (localFeedDir1)
+ callUpdateFeed(LOCAL_FEED_DIR1);
+
+ // now add another item (by changing to local feed folder localFeedDir2)
+ callUpdateFeed(LOCAL_FEED_DIR2);
+
+ verifySingleFeedInDatabaseAndItemCount(2);
+ }
+
+ /**
+ * Test removing items from an existing local feed without a corresponding media file.
+ */
+ @Test
+ public void testUpdateFeed_RemoveItems() {
+ // add local feed with 2 items (localFeedDir1)
+ callUpdateFeed(LOCAL_FEED_DIR2);
+
+ // now remove an item (by changing to local feed folder localFeedDir1)
+ callUpdateFeed(LOCAL_FEED_DIR1);
+
+ verifySingleFeedInDatabaseAndItemCount(1);
+ }
+
+ /**
+ * Test feed icon defined in the local feed media folder.
+ */
+ @Test
+ public void testUpdateFeed_FeedIconFromFolder() {
+ callUpdateFeed(LOCAL_FEED_DIR2);
+
+ Feed feedAfter = verifySingleFeedInDatabase();
+ assertTrue(feedAfter.getImageUrl().contains("local-feed2/folder.png"));
+ }
+
+ /**
+ * Test default feed icon if there is no matching file in the local feed media folder.
+ */
+ @Test
+ public void testUpdateFeed_FeedIconDefault() {
+ callUpdateFeed(LOCAL_FEED_DIR1);
+
+ Feed feedAfter = verifySingleFeedInDatabase();
+ String resourceEntryName = context.getResources().getResourceEntryName(R.raw.local_feed_default_icon);
+ assertTrue(feedAfter.getImageUrl().contains(resourceEntryName));
+ }
+
+ /**
+ * Fill ShadowMediaMetadataRetriever with dummy duration and title.
+ *
+ * @param localFeedDir assets local feed folder with media files
+ */
+ private void mapDummyMetadata(@NonNull String localFeedDir) throws IOException {
+ String[] fileNames = context.getAssets().list(localFeedDir);
+ for (String fileName : fileNames) {
+ String path = localFeedDir + '/' + fileName;
+ ShadowMediaMetadataRetriever.addMetadata(path,
+ MediaMetadataRetriever.METADATA_KEY_DURATION, "10");
+ ShadowMediaMetadataRetriever.addMetadata(path,
+ MediaMetadataRetriever.METADATA_KEY_TITLE, fileName);
+ }
+
+ }
+
+ /**
+ * Calls the method {@link LocalFeedUpdater#updateFeed(Feed, Context)} with
+ * the given local feed folder.
+ *
+ * @param localFeedDir assets local feed folder with media files
+ */
+ private void callUpdateFeed(@NonNull String localFeedDir) {
+ DocumentFile documentFile = new AssetsDocumentFile(localFeedDir, context.getAssets());
+ try (MockedStatic<DocumentFile> dfMock = Mockito.mockStatic(DocumentFile.class)) {
+ // mock external storage
+ dfMock.when(() -> DocumentFile.fromTreeUri(any(), any())).thenReturn(documentFile);
+
+ // call method to test
+ Feed feed = new Feed(FEED_URL, null);
+ LocalFeedUpdater.updateFeed(feed, context);
+ }
+ }
+
+ /**
+ * Verify that the database contains exactly one feed and return that feed.
+ */
+ @NonNull
+ private static Feed verifySingleFeedInDatabase() {
+ List<Feed> feedListAfter = DBReader.getFeedList();
+ assertEquals(1, feedListAfter.size());
+ return feedListAfter.get(0);
+ }
+
+ /**
+ * Verify that the database contains exactly one feed and the number of
+ * items in the feed.
+ *
+ * @param expectedItemCount expected number of items in the feed
+ */
+ private static void verifySingleFeedInDatabaseAndItemCount(int expectedItemCount) {
+ Feed feed = verifySingleFeedInDatabase();
+ List<FeedItem> feedItems = DBReader.getFeedItemList(feed);
+ assertEquals(expectedItemCount, feedItems.size());
+ }
+}
diff --git a/core/src/test/java/de/danoeh/antennapod/core/storage/ItemEnqueuePositionCalculatorTest.java b/core/src/test/java/de/danoeh/antennapod/core/storage/ItemEnqueuePositionCalculatorTest.java
index ed7d2fa75..6c5a9daf1 100644
--- a/core/src/test/java/de/danoeh/antennapod/core/storage/ItemEnqueuePositionCalculatorTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/storage/ItemEnqueuePositionCalculatorTest.java
@@ -32,7 +32,7 @@ import static java.util.Collections.emptyList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.stub;
+import static org.mockito.Mockito.when;
public class ItemEnqueuePositionCalculatorTest {
@@ -189,7 +189,7 @@ public class ItemEnqueuePositionCalculatorTest {
//
ItemEnqueuePositionCalculator calculator = new ItemEnqueuePositionCalculator(options);
DownloadStateProvider stubDownloadStateProvider = mock(DownloadStateProvider.class);
- stub(stubDownloadStateProvider.isDownloadingFile(any(FeedMedia.class))).toReturn(false);
+ when(stubDownloadStateProvider.isDownloadingFile(any(FeedMedia.class))).thenReturn(false);
calculator.downloadStateProvider = stubDownloadStateProvider;
// Setup initial data
@@ -232,7 +232,7 @@ public class ItemEnqueuePositionCalculatorTest {
private static FeedItem setAsDownloading(FeedItem item, DownloadStateProvider stubDownloadStateProvider,
boolean isDownloading) {
- stub(stubDownloadStateProvider.isDownloadingFile(item.getMedia())).toReturn(isDownloading);
+ when(stubDownloadStateProvider.isDownloadingFile(item.getMedia())).thenReturn(isDownloading);
return item;
}