summaryrefslogtreecommitdiff
path: root/app/src/androidTest/java/de
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/androidTest/java/de')
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java168
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java95
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java22
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java25
4 files changed, 288 insertions, 22 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
new file mode 100644
index 000000000..c6beb2d42
--- /dev/null
+++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
@@ -0,0 +1,168 @@
+package de.test.antennapod.storage;
+
+import android.content.Context;
+import android.content.Intent;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionTimeoutException;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import de.danoeh.antennapod.core.ClientConfig;
+import de.danoeh.antennapod.core.DBTasksCallbacks;
+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.service.playback.PlaybackService;
+import de.danoeh.antennapod.core.storage.AutomaticDownloadAlgorithm;
+import de.danoeh.antennapod.core.storage.DBReader;
+import de.danoeh.antennapod.core.storage.DBTasks;
+import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
+import de.danoeh.antennapod.core.storage.PodDBAdapter;
+import de.danoeh.antennapod.core.util.playback.Playable;
+import de.test.antennapod.ui.UITestUtils;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+public class AutoDownloadTest {
+
+ private Context context;
+ private UITestUtils stubFeedsServer;
+
+ private DBTasksCallbacks dbTasksCallbacksOrig;
+
+ @Before
+ public void setUp() throws Exception {
+ context = ApplicationProvider.getApplicationContext();
+
+ stubFeedsServer = new UITestUtils(context);;
+ stubFeedsServer.setup();
+
+ dbTasksCallbacksOrig = ClientConfig.dbTasksCallbacks;
+
+ // create new database
+ PodDBAdapter.init(context);
+ PodDBAdapter.deleteDatabase();
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.close();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ stubFeedsServer.tearDown();
+
+ context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
+ Awaitility.await().until(() -> !PlaybackService.isRunning);
+
+ ClientConfig.dbTasksCallbacks = dbTasksCallbacksOrig;
+ }
+
+ /**
+ * A cross-functional test, ensuring playback's behavior works with Auto Download in boundary condition.
+ *
+ * Scenario:
+ * - For setting enqueue location AFTER_CURRENTLY_PLAYING
+ * - when playback of an episode is complete and the app advances to the next episode (continuous playback on)
+ * - when automatic download kicks in,
+ * - ensure the next episode is the current playing one, needed for AFTER_CURRENTLY_PLAYING enqueue location.
+ */
+ @Test
+ public void downloadsEnqueuedToAfterCurrent_CurrentAdvancedToNextOnPlaybackComplete() throws Exception {
+ UserPreferences.setFollowQueue(true); // continuous playback
+
+ // Setup: feeds and queue
+ // downloads 3 of them, leave some in new state (auto-downloadable)
+ stubFeedsServer.addLocalFeedData(false);
+ List<FeedItem> queue = DBReader.getQueue();
+ assertTrue(queue.size() > 1);
+ FeedItem item0 = queue.get(0);
+ FeedItem item1 = queue.get(1);
+
+ // Setup: enable automatic download
+ // it is not needed, as the actual automatic download is stubbed.
+ StubDownloadAlgorithm stubDownloadAlgorithm = new StubDownloadAlgorithm();
+ useDownloadAlgorithm(stubDownloadAlgorithm);
+
+ // Actual test
+ // Play the first one in the queue
+ playEpisode(item0);
+
+ try {
+ // when playback is complete, advances to the next one, and auto download kicks in,
+ // ensure that currently playing has been advanced to the next one by this point.
+ Awaitility.await("advanced to the next episode")
+ .atMost(6000, MILLISECONDS) // the test mp3 media is 3-second long. twice should be enough
+ .until(() -> item1.equals(stubDownloadAlgorithm.getCurrentlyPlayingAtDownload()));
+ } catch (ConditionTimeoutException cte) {
+ FeedItem actual = stubDownloadAlgorithm.getCurrentlyPlayingAtDownload();
+ fail("when auto download is triggered, the next episode should be playing: ("
+ + item1.getId() + ", " + item1.getTitle() + ") . "
+ + "Actual playing: ("
+ + (actual == null ? "" : actual.getId() + ", " + actual.getTitle()) + ")"
+ );
+ }
+
+ }
+
+ private void playEpisode(@NonNull FeedItem item) {
+ FeedMedia media = item.getMedia();
+ DBTasks.playMedia(context, media, false, true, true);
+ Awaitility.await("episode is playing")
+ .atMost(1000, MILLISECONDS)
+ .until(() -> item.equals(getCurrentlyPlaying()));
+ }
+
+ private FeedItem getCurrentlyPlaying() {
+ Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(context);
+ if (playable == null) {
+ return null;
+ }
+ return ((FeedMedia)playable).getItem();
+ }
+
+ private void useDownloadAlgorithm(final AutomaticDownloadAlgorithm downloadAlgorithm) {
+ DBTasksCallbacks dbTasksCallbacksStub = new DBTasksCallbacks() {
+ @Override
+ public AutomaticDownloadAlgorithm getAutomaticDownloadAlgorithm() {
+ return downloadAlgorithm;
+ }
+
+ @Override
+ public EpisodeCleanupAlgorithm getEpisodeCacheCleanupAlgorithm() {
+ return dbTasksCallbacksOrig.getEpisodeCacheCleanupAlgorithm();
+ }
+ };
+ ClientConfig.dbTasksCallbacks = dbTasksCallbacksStub;
+ }
+
+ private class StubDownloadAlgorithm implements AutomaticDownloadAlgorithm {
+ @Nullable
+ private FeedItem currentlyPlaying;
+
+ @Override
+ public Runnable autoDownloadUndownloadedItems(Context context) {
+ return () -> {
+ if (currentlyPlaying == null) {
+ currentlyPlaying = getCurrentlyPlaying();
+ } else {
+ throw new AssertionError("Stub automatic download should be invoked once and only once");
+ }
+ };
+ }
+
+ @Nullable
+ FeedItem getCurrentlyPlayingAtDownload() {
+ return currentlyPlaying;
+ }
+ }
+}
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
index 55ea16f13..cce4e5111 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
@@ -2,26 +2,31 @@ package de.test.antennapod.storage;
import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
-import androidx.test.filters.SmallTest;
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.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import static de.danoeh.antennapod.core.util.FeedItemUtil.getIdList;
import static java.util.Collections.singletonList;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -179,4 +184,82 @@ public class DBTasksTest {
lastDate = item.getPubDate();
}
}
+
+ @Test
+ public void testAddQueueItemsInDownload_EnqueueEnabled() throws Exception {
+ // Setup test data / environment
+ UserPreferences.setEnqueueDownloadedEpisodes(true);
+ UserPreferences.setEnqueueLocation(UserPreferences.EnqueueLocation.BACK);
+
+ List<FeedItem> fis1 = createSavedFeed("Feed 1", 2).getItems();
+ List<FeedItem> fis2 = createSavedFeed("Feed 2", 3).getItems();
+
+ DBWriter.addQueueItem(context, fis1.get(0), fis2.get(0)).get();
+ // the first item fis1.get(0) is already in the queue
+ FeedItem[] itemsToDownload = new FeedItem[]{ fis1.get(0), fis1.get(1), fis2.get(2), fis2.get(1) };
+
+ // Expectations:
+ List<FeedItem> expectedEnqueued = Arrays.asList(fis1.get(1), fis2.get(2), fis2.get(1));
+ List<FeedItem> expectedQueue = new ArrayList<>();
+ expectedQueue.addAll(DBReader.getQueue());
+ expectedQueue.addAll(expectedEnqueued);
+
+ // Run actual test and assert results
+ List<? extends FeedItem> actualEnqueued =
+ DBTasks.enqueueFeedItemsToDownload(context, itemsToDownload);
+
+ assertEqualsByIds("Only items not in the queue are enqueued", expectedEnqueued, actualEnqueued);
+ assertEqualsByIds("Queue has new items appended", expectedQueue, DBReader.getQueue());
+ }
+
+ @Test
+ public void testAddQueueItemsInDownload_EnqueueDisabled() throws Exception {
+ // Setup test data / environment
+ UserPreferences.setEnqueueDownloadedEpisodes(false);
+
+ List<FeedItem> fis1 = createSavedFeed("Feed 1", 2).getItems();
+ List<FeedItem> fis2 = createSavedFeed("Feed 2", 3).getItems();
+
+ DBWriter.addQueueItem(context, fis1.get(0), fis2.get(0)).get();
+ FeedItem[] itemsToDownload = new FeedItem[]{ fis1.get(0), fis1.get(1), fis2.get(2), fis2.get(1) };
+
+ // Expectations:
+ List<FeedItem> expectedEnqueued = Collections.emptyList();
+ List<FeedItem> expectedQueue = DBReader.getQueue();
+
+ // Run actual test and assert results
+ List<? extends FeedItem> actualEnqueued =
+ DBTasks.enqueueFeedItemsToDownload(context, itemsToDownload);
+
+ assertEqualsByIds("No item is enqueued", expectedEnqueued, actualEnqueued);
+ assertEqualsByIds("Queue is unchanged", expectedQueue, DBReader.getQueue());
+ }
+
+ private void assertEqualsByIds(String msg, List<? extends FeedItem> expected, List<? extends FeedItem> actual) {
+ // assert only the IDs, so that any differences are easily to spot.
+ List<Long> expectedIds = getIdList(expected);
+ List<Long> actualIds = getIdList(actual);
+ assertEquals(msg, expectedIds, actualIds);
+ }
+
+ private Feed createSavedFeed(String title, int numFeedItems) {
+ final Feed feed = new Feed("url", null, title);
+
+ if (numFeedItems > 0) {
+ List<FeedItem> items = new ArrayList<>(numFeedItems);
+ for (int i = 1; i <= numFeedItems; i++) {
+ FeedItem item = new FeedItem(0, "item " + i + " of " + title, "id", "link",
+ new Date(), FeedItem.UNPLAYED, feed);
+ items.add(item);
+ }
+ feed.setItems(items);
+ }
+
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ adapter.open();
+ adapter.setCompleteFeed(feed);
+ adapter.close();
+ return feed;
+ }
+
}
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
index 42f4413d3..1e13bd5c3 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -4,12 +4,15 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.preference.PreferenceManager;
+import android.util.Log;
+
import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.LargeTest;
import androidx.test.filters.MediumTest;
-import android.util.Log;
import org.awaitility.Awaitility;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
import java.io.File;
import java.io.IOException;
@@ -29,9 +32,7 @@ import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.Consumer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
+import de.danoeh.antennapod.core.util.FeedItemUtil;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
@@ -475,11 +476,12 @@ public class DBWriterTest {
assertFalse(OLD_DATE == media.getPlaybackCompletionDate().getTime());
}
- private Feed queueTestSetupMultipleItems(final int NUM_ITEMS) throws InterruptedException, ExecutionException, TimeoutException {
+ private Feed queueTestSetupMultipleItems(final int numItems) throws InterruptedException, ExecutionException, TimeoutException {
final Context context = getInstrumentation().getTargetContext();
+ UserPreferences.setEnqueueLocation(UserPreferences.EnqueueLocation.BACK);
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS; i++) {
+ for (int i = 0; i < numItems; i++) {
FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
feed.getItems().add(item);
}
@@ -573,12 +575,16 @@ public class DBWriterTest {
Cursor cursor = adapter.getQueueIDCursor();
assertTrue(cursor.moveToFirst());
assertTrue(cursor.getCount() == NUM_ITEMS);
+ List<Long> expectedIds = FeedItemUtil.getIdList(feed.getItems());
+ List<Long> actualIds = new ArrayList<>();
for (int i = 0; i < NUM_ITEMS; i++) {
assertTrue(cursor.moveToPosition(i));
- assertTrue(cursor.getLong(0) == feed.getItems().get(i).getId());
+ actualIds.add(cursor.getLong(0));
}
cursor.close();
adapter.close();
+ assertEquals("Bulk add to queue: result order should be the same as the order given",
+ expectedIds, actualIds);
}
@Test
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
index 65bc7d745..f22e4b426 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -4,13 +4,14 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.preference.PreferenceManager;
-import androidx.test.filters.LargeTest;
+import androidx.annotation.StringRes;
+import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
+
import com.robotium.solo.Solo;
import com.robotium.solo.Timeout;
-import de.test.antennapod.EspressoTestUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -21,6 +22,7 @@ import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.PreferenceActivity;
import de.danoeh.antennapod.core.preferences.UserPreferences;
+import de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation;
import de.danoeh.antennapod.core.storage.APCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm;
@@ -28,6 +30,7 @@ import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.danoeh.antennapod.fragment.SubscriptionFragment;
+import de.test.antennapod.EspressoTestUtils;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.espresso.Espresso.onView;
@@ -126,13 +129,19 @@ public class PreferencesTest {
}
@Test
- public void testEnqueueAtFront() {
+ public void testEnqueueLocation() {
clickPreference(R.string.playback_pref);
- final boolean enqueueAtFront = UserPreferences.enqueueAtFront();
- clickPreference(R.string.pref_queueAddToFront_title);
- assertTrue(solo.waitForCondition(() -> enqueueAtFront != UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout()));
- clickPreference(R.string.pref_queueAddToFront_title);
- assertTrue(solo.waitForCondition(() -> enqueueAtFront == UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout()));
+ doTestEnqueueLocation(R.string.enqueue_location_after_current, EnqueueLocation.AFTER_CURRENTLY_PLAYING);
+ doTestEnqueueLocation(R.string.enqueue_location_front, EnqueueLocation.FRONT);
+ doTestEnqueueLocation(R.string.enqueue_location_back, EnqueueLocation.BACK);
+ }
+
+ private void doTestEnqueueLocation(@StringRes int optionResId, EnqueueLocation expected) {
+ clickPreference(R.string.pref_enqueue_location_title);
+ onView(withText(optionResId)).perform(click());
+ assertTrue(solo.waitForCondition(
+ () -> expected == UserPreferences.getEnqueueLocation(),
+ Timeout.getLargeTimeout()));
}
@Test