diff options
author | Herbert Reiter <46045854+damoasda@users.noreply.github.com> | 2020-10-25 17:22:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-25 17:22:36 +0100 |
commit | 28ebbedbdf34b72b31c536a118bcf5108b3ea7e5 (patch) | |
tree | 7365c90ff91414f610d3c4ba3044537e6577eb99 /core/src/test/java/de | |
parent | 41580b57cc06c297615bc3484274859bb0c9c5c1 (diff) | |
download | AntennaPod-28ebbedbdf34b72b31c536a118bcf5108b3ea7e5.zip |
Local feeds: Unit tests for LocalFeedUpdater (#4551)
Diffstat (limited to 'core/src/test/java/de')
-rw-r--r-- | core/src/test/java/de/danoeh/antennapod/core/feed/LocalFeedUpdaterTest.java | 208 | ||||
-rw-r--r-- | core/src/test/java/de/danoeh/antennapod/core/storage/ItemEnqueuePositionCalculatorTest.java | 6 |
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; } |