enqueue location: use the new 3-value settings

This commit is contained in:
orionlee 2019-10-28 14:26:10 -07:00
parent 52521ecddb
commit bddd2bfa2e
8 changed files with 162 additions and 154 deletions

View File

@ -189,7 +189,7 @@ public class DBTasksTest {
public void testAddQueueItemsInDownload_EnqueueEnabled() throws Exception {
// Setup test data / environment
UserPreferences.setEnqueueDownloadedEpisodes(true);
UserPreferences.setEnqueueAtFront(false);
UserPreferences.setEnqueueLocation(UserPreferences.EnqueueLocation.BACK);
List<FeedItem> fis1 = createSavedFeed("Feed 1", 2).getItems();
List<FeedItem> fis2 = createSavedFeed("Feed 2", 3).getItems();

View File

@ -5,6 +5,7 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.preference.PreferenceManager;
import androidx.annotation.StringRes;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
@ -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;
@ -129,7 +131,17 @@ public class PreferencesTest {
@Test
public void testEnqueueLocation() {
clickPreference(R.string.playback_pref);
// TODO-2652: implement the test
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

View File

@ -7,6 +7,7 @@ import android.preference.PreferenceManager;
import de.danoeh.antennapod.BuildConfig;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation;
import de.danoeh.antennapod.core.util.download.AutoUpdateManager;
import de.danoeh.antennapod.core.util.gui.NotificationUtils;
@ -75,6 +76,13 @@ public class PreferenceUpgrader {
}
UserPreferences.setQueueLocked(false);
if (!prefs.contains(UserPreferences.PREF_ENQUEUE_LOCATION)) {
final String keyOldPrefEnqueueFront = "prefQueueAddToFront";
boolean enqueueAtFront = prefs.getBoolean(keyOldPrefEnqueueFront, false);
EnqueueLocation enqueueLocation = enqueueAtFront ? EnqueueLocation.FRONT : EnqueueLocation.BACK;
UserPreferences.setEnqueueLocation(enqueueLocation);
}
}
}
}

View File

@ -63,9 +63,6 @@ public class UserPreferences {
public static final String PREF_BACK_BUTTON_BEHAVIOR = "prefBackButtonBehavior";
private static final String PREF_BACK_BUTTON_GO_TO_PAGE = "prefBackButtonGoToPage";
// Queue
public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront";
public static final String PREF_QUEUE_KEEP_IN_PROGESS_AT_FRONT = "prefQueueKeepInProgressAtFront";
public static final String PREF_QUEUE_KEEP_SORTED = "prefQueueKeepSorted";
public static final String PREF_QUEUE_KEEP_SORTED_ORDER = "prefQueueKeepSortedOrder";
@ -299,6 +296,7 @@ public class UserPreferences {
BACK, FRONT, AFTER_CURRENTLY_PLAYING;
}
@NonNull
public static EnqueueLocation getEnqueueLocation() {
String valStr = prefs.getString(PREF_ENQUEUE_LOCATION, EnqueueLocation.BACK.name());
try {
@ -310,29 +308,12 @@ public class UserPreferences {
}
}
// TODO-2652: migrate settings
public static boolean enqueueAtFront() { // TODO-2652: migrate to the new settings
return prefs.getBoolean(PREF_QUEUE_ADD_TO_FRONT, false);
}
@VisibleForTesting
public static void setEnqueueAtFront(boolean enqueueAtFront) { // TODO-2652: migrate to the new settings
public static void setEnqueueLocation(@NonNull EnqueueLocation location) {
prefs.edit()
.putBoolean(PREF_QUEUE_ADD_TO_FRONT, enqueueAtFront)
.putString(PREF_ENQUEUE_LOCATION, location.name())
.apply();
}
/**
*
* @return {@code true} if in enqueuing items/podcast episodes, when the existing front item is
* in-progress, i.e., the user has played part of it, such item remains at the front of the
* queue; {@code false} otherwise.
*/
public static boolean keepInProgressAtFront() { // TODO-2652: migrate to the new settings
return prefs.getBoolean(PREF_QUEUE_KEEP_IN_PROGESS_AT_FRONT, false);
}
public static boolean isPauseOnHeadsetDisconnect() {
return prefs.getBoolean(PREF_PAUSE_ON_HEADSET_DISCONNECT, true);
}

View File

@ -46,6 +46,7 @@ import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.LongList;
import de.danoeh.antennapod.core.util.Permutor;
import de.danoeh.antennapod.core.util.SortOrder;
import de.danoeh.antennapod.core.util.playback.Playable;
/**
* Provides methods for writing data to AntennaPod's database.
@ -326,19 +327,15 @@ public class DBWriter {
List<QueueEvent> events = new ArrayList<>();
List<FeedItem> updatedItems = new ArrayList<>();
ItemEnqueuePositionCalculator positionCalculator =
new ItemEnqueuePositionCalculator(
new ItemEnqueuePositionCalculator.Options()
.setEnqueueAtFront(UserPreferences.enqueueAtFront())
.setKeepInProgressAtFront(UserPreferences.keepInProgressAtFront())
);
new ItemEnqueuePositionCalculator(UserPreferences.getEnqueueLocation());
Playable currentlyPlaying = Playable.PlayableUtils.createInstanceFromPreferences(context);
for (int i = 0; i < itemIds.length; i++) {
if (!itemListContains(queue, itemIds[i])) {
final FeedItem item = DBReader.getFeedItem(itemIds[i]);
if (item != null) {
int insertPosition = positionCalculator.calcPosition(i, item, queue);
int insertPosition = positionCalculator.calcPosition(i, item, queue, currentlyPlaying);
queue.add(insertPosition, item);
events.add(QueueEvent.added(item, insertPosition));

View File

@ -3,11 +3,15 @@ package de.danoeh.antennapod.core.storage;
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import java.util.List;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation;
import de.danoeh.antennapod.core.util.playback.Playable;
/**
* @see DBWriter#addQueueItem(Context, boolean, long...) it uses the class to determine
@ -15,65 +19,41 @@ import de.danoeh.antennapod.core.feed.FeedItem;
*/
class ItemEnqueuePositionCalculator {
public static class Options {
private boolean enqueueAtFront = false;
private boolean keepInProgressAtFront = false;
public boolean isEnqueueAtFront() {
return enqueueAtFront;
}
public Options setEnqueueAtFront(boolean enqueueAtFront) {
this.enqueueAtFront = enqueueAtFront;
return this;
}
public boolean isKeepInProgressAtFront() {
return keepInProgressAtFront;
}
public Options setKeepInProgressAtFront(boolean keepInProgressAtFront) {
this.keepInProgressAtFront = keepInProgressAtFront;
return this;
}
}
@NonNull
private final Options options;
private final EnqueueLocation enqueueLocation;
@VisibleForTesting
DownloadStateProvider downloadStateProvider = DownloadRequester.getInstance();
public ItemEnqueuePositionCalculator(@NonNull Options options) {
this.options = options;
public ItemEnqueuePositionCalculator(@NonNull EnqueueLocation enqueueLocation) {
this.enqueueLocation = enqueueLocation;
}
/**
*
* @param positionAmongToAdd Typically, the callers has a list of items to be inserted to
* the queue. This parameter indicates the position (0-based) of
* the item among the one to inserted. E.g., it is needed for
* enqueue at front option.
*
* @param item the item to be inserted
* @param curQueue the queue to which the item is to be inserted
* @return the position (0-based) the item should be inserted to the named queu
* @param item the item to be inserted
* @param curQueue the queue to which the item is to be inserted
* @param currentPlaying the currently playing media
* @return the position (0-based) the item should be inserted to the named queue
*/
public int calcPosition(int positionAmongToAdd, FeedItem item, List<FeedItem> curQueue) {
if (options.isEnqueueAtFront()) {
if (options.isKeepInProgressAtFront() &&
curQueue.size() > 0 &&
curQueue.get(0).getMedia() != null &&
curQueue.get(0).getMedia().isInProgress()) {
// leave the front in progress item at the front
return getPositionOfFirstNonDownloadingItem(positionAmongToAdd + 1, curQueue);
} else { // typical case
public int calcPosition(int positionAmongToAdd, @NonNull FeedItem item,
@NonNull List<FeedItem> curQueue, @Nullable Playable currentPlaying) {
switch (enqueueLocation) {
case BACK:
return curQueue.size();
case FRONT:
// return NOT 0, so that when a list of items are inserted, the items inserted
// keep the same order. Returning 0 will reverse the order
return getPositionOfFirstNonDownloadingItem(positionAmongToAdd, curQueue);
}
} else {
return curQueue.size();
case AFTER_CURRENTLY_PLAYING:
int currentlyPlayingPosition = getCurrentlyPlayingPosition(curQueue, currentPlaying);
return getPositionOfFirstNonDownloadingItem(
currentlyPlayingPosition + (1 + positionAmongToAdd), curQueue);
default:
throw new AssertionError("calcPosition() : unrecognized enqueueLocation option: " + enqueueLocation);
}
}
@ -103,4 +83,18 @@ class ItemEnqueuePositionCalculator {
return false;
}
}
private static int getCurrentlyPlayingPosition(@NonNull List<FeedItem> curQueue,
@Nullable Playable currentPlaying) {
if (!(currentPlaying instanceof FeedMedia)) {
return -1;
}
final long curPlayingItemId = ((FeedMedia) currentPlaying).getItem().getId();
for (int i = 0; i < curQueue.size(); i++) {
if (curPlayingItemId == curQueue.get(i).getId()) {
return i;
}
}
return -1;
}
}

View File

@ -455,10 +455,10 @@
<string name="pref_showDownloadReport_sum">If downloads fail, generate a report that shows the details of the failure.</string>
<string name="pref_expand_notify_unsupport_toast">Android versions before 4.1 do not support expanded notifications.</string>
<string name="pref_enqueue_location_title">Enqueue Location</string>
<string name="pref_enqueue_location_sum">Add episodes to: %1$s.</string>
<string name="enqueue_location_back">back of the queue</string>
<string name="enqueue_location_front">front of the queue</string>
<string name="enqueue_location_after_current">after current episode</string>
<string name="pref_enqueue_location_sum">Add episodes to: %1$s</string>
<string name="enqueue_location_back">Back</string>
<string name="enqueue_location_front">Front</string>
<string name="enqueue_location_after_current">After current episode</string>
<string name="pref_smart_mark_as_played_disabled">Disabled</string>
<string name="pref_image_cache_size_title">Image Cache Size</string>
<string name="pref_image_cache_size_sum">Size of the disk cache for images.</string>

View File

@ -16,9 +16,16 @@ import java.util.stream.Collectors;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.feed.FeedMother;
import de.danoeh.antennapod.core.storage.ItemEnqueuePositionCalculator.Options;
import de.danoeh.antennapod.core.util.CollectionTestUtil;
import de.danoeh.antennapod.core.feed.MediaType;
import de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation;
import de.danoeh.antennapod.core.util.playback.ExternalMedia;
import de.danoeh.antennapod.core.util.playback.Playable;
import static de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation.AFTER_CURRENTLY_PLAYING;
import static de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation.BACK;
import static de.danoeh.antennapod.core.preferences.UserPreferences.EnqueueLocation.FRONT;
import static de.danoeh.antennapod.core.util.CollectionTestUtil.concat;
import static de.danoeh.antennapod.core.util.CollectionTestUtil.list;
import static de.danoeh.antennapod.core.util.FeedItemUtil.getIdList;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
@ -31,28 +38,25 @@ public class ItemEnqueuePositionCalculatorTest {
public static class BasicTest {
@Parameters(name = "{index}: case<{0}>, expected:{1}")
public static Iterable<Object[]> data() {
Options optDefault = new Options();
Options optEnqAtFront = new Options().setEnqueueAtFront(true);
return Arrays.asList(new Object[][]{
{"case default, i.e., add to the end",
CollectionTestUtil.concat(QUEUE_DEFAULT_IDS, TFI_ID),
optDefault, 0, QUEUE_DEFAULT},
concat(QUEUE_DEFAULT_IDS, TFI_ID),
BACK, 0, QUEUE_DEFAULT},
{"case default (2nd item)",
CollectionTestUtil.concat(QUEUE_DEFAULT_IDS, TFI_ID),
optDefault, 1, QUEUE_DEFAULT},
concat(QUEUE_DEFAULT_IDS, TFI_ID),
BACK, 1, QUEUE_DEFAULT},
{"case option enqueue at front",
CollectionTestUtil.concat(TFI_ID, QUEUE_DEFAULT_IDS),
optEnqAtFront, 0, QUEUE_DEFAULT},
concat(TFI_ID, QUEUE_DEFAULT_IDS),
FRONT, 0, QUEUE_DEFAULT},
{"case option enqueue at front (2nd item)",
CollectionTestUtil.list(11L, TFI_ID, 12L, 13L, 14L),
optEnqAtFront, 1, QUEUE_DEFAULT},
list(11L, TFI_ID, 12L, 13L, 14L),
FRONT, 1, QUEUE_DEFAULT},
{"case empty queue, option default",
CollectionTestUtil.list(TFI_ID),
optDefault, 0, QUEUE_EMPTY},
list(TFI_ID),
BACK, 0, QUEUE_EMPTY},
{"case empty queue, option enqueue at front",
CollectionTestUtil.list(TFI_ID),
optEnqAtFront, 0, QUEUE_EMPTY},
list(TFI_ID),
FRONT, 0, QUEUE_EMPTY},
});
}
@ -63,7 +67,7 @@ public class ItemEnqueuePositionCalculatorTest {
public List<Long> idsExpected;
@Parameter(2)
public Options options;
public EnqueueLocation options;
@Parameter(3)
public int posAmongAdded; // the position of feed item to be inserted among the list to be inserted.
@ -71,7 +75,6 @@ public class ItemEnqueuePositionCalculatorTest {
@Parameter(4)
public List<FeedItem> curQueue;
public static final long TFI_ID = 101;
/**
@ -85,49 +88,62 @@ public class ItemEnqueuePositionCalculatorTest {
List<FeedItem> queue = new ArrayList<>(curQueue);
FeedItem tFI = tFI(TFI_ID);
doAddToQueueAndAssertResult(message,
calculator, posAmongAdded, tFI, queue,
calculator, posAmongAdded, tFI, queue, getCurrentlyPlaying(),
idsExpected);
}
Playable getCurrentlyPlaying() { return null; }
}
@RunWith(Parameterized.class)
public static class KeepInProgressAtFrontTest extends BasicTest {
public static class AfterCurrentlyPlayingTest extends BasicTest {
@Parameters(name = "{index}: case<{0}>, expected:{1}")
public static Iterable<Object[]> data() {
Options optKeepInProgressAtFront =
new Options().setEnqueueAtFront(true).setKeepInProgressAtFront(true);
// edge case: keep in progress without enabling enqueue at front is meaningless
Options optKeepInProgressAtFrontWithNoEnqueueAtFront =
new Options().setKeepInProgressAtFront(true);
return Arrays.asList(new Object[][]{
{"case option keep in progress at front",
CollectionTestUtil.list(11L, TFI_ID, 12L, 13L),
optKeepInProgressAtFront, 0, QUEUE_FRONT_IN_PROGRESS},
{"case option keep in progress at front (2nd item)",
CollectionTestUtil.list(11L, 12L, TFI_ID, 13L),
optKeepInProgressAtFront, 1, QUEUE_FRONT_IN_PROGRESS},
{"case option keep in progress at front, front item not in progress",
CollectionTestUtil.concat(TFI_ID, QUEUE_DEFAULT_IDS),
optKeepInProgressAtFront, 0, QUEUE_DEFAULT},
{"case option keep in progress at front, front item no media at all",
CollectionTestUtil.concat(TFI_ID, QUEUE_FRONT_NO_MEDIA_IDS),
optKeepInProgressAtFront, 0, QUEUE_FRONT_NO_MEDIA}, // No media should not cause any exception
{"case option keep in progress at front, but enqueue at front is disabled",
CollectionTestUtil.concat(QUEUE_FRONT_IN_PROGRESS_IDS, TFI_ID),
optKeepInProgressAtFrontWithNoEnqueueAtFront, 0, QUEUE_FRONT_IN_PROGRESS},
{"case empty queue, option keep in progress at front",
CollectionTestUtil.list(TFI_ID),
optKeepInProgressAtFront, 0, QUEUE_EMPTY},
{"case option after currently playing",
list(11L, TFI_ID, 12L, 13L, 14L),
AFTER_CURRENTLY_PLAYING, 0, QUEUE_DEFAULT, 11L},
{"case option after currently playing (2nd item)",
list(11L, 12L, TFI_ID, 13L, 14L),
AFTER_CURRENTLY_PLAYING, 1, QUEUE_DEFAULT, 11L},
{"case option after currently playing, currently playing in the middle of the queue",
list(11L, 12L, 13L, TFI_ID, 14L),
AFTER_CURRENTLY_PLAYING, 0, QUEUE_DEFAULT, 13L},
{"case option after currently playing, currently playing is not in queue",
concat(TFI_ID, QUEUE_DEFAULT_IDS),
AFTER_CURRENTLY_PLAYING, 0, QUEUE_DEFAULT, 99L},
{"case option after currently playing, no currentlyPlaying is null",
concat(TFI_ID, QUEUE_DEFAULT_IDS),
AFTER_CURRENTLY_PLAYING, 0, QUEUE_DEFAULT, ID_CURRENTLY_PLAYING_NULL},
{"case option after currently playing, currentlyPlaying is externalMedia",
concat(TFI_ID, QUEUE_DEFAULT_IDS),
AFTER_CURRENTLY_PLAYING, 0, QUEUE_DEFAULT, ID_CURRENTLY_PLAYING_NOT_FEEDMEDIA},
{"case empty queue, option after currently playing",
list(TFI_ID),
AFTER_CURRENTLY_PLAYING, 0, QUEUE_EMPTY, ID_CURRENTLY_PLAYING_NULL},
});
}
private static final List<FeedItem> QUEUE_FRONT_IN_PROGRESS = Arrays.asList(tFI(11, 60000), tFI(12), tFI(13));
private static final List<Long> QUEUE_FRONT_IN_PROGRESS_IDS = getIdList(QUEUE_FRONT_IN_PROGRESS);
@Parameter(5)
public long idCurrentlyPlaying = -1;
private static final List<FeedItem> QUEUE_FRONT_NO_MEDIA = Arrays.asList(tFINoMedia(11), tFI(12), tFI(13));
private static final List<Long> QUEUE_FRONT_NO_MEDIA_IDS = getIdList(QUEUE_FRONT_NO_MEDIA);
@Override
Playable getCurrentlyPlaying() {
if (ID_CURRENTLY_PLAYING_NOT_FEEDMEDIA == idCurrentlyPlaying) {
return externalMedia();
}
if (ID_CURRENTLY_PLAYING_NULL == idCurrentlyPlaying) {
return null;
}
return tFI(idCurrentlyPlaying).getMedia();
}
private static Playable externalMedia() {
return new ExternalMedia("http://example.com/episode.mp3", MediaType.AUDIO);
}
private static final long ID_CURRENTLY_PLAYING_NULL = -1L;
private static final long ID_CURRENTLY_PLAYING_NOT_FEEDMEDIA = -9999L;
}
@ -136,24 +152,21 @@ public class ItemEnqueuePositionCalculatorTest {
@Parameters(name = "{index}: case<{0}>")
public static Iterable<Object[]> data() {
Options optDefault = new Options();
Options optEnqAtFront = new Options().setEnqueueAtFront(true);
// Attempts to make test more readable by showing the expected list of ids
// (rather than the expected positions)
return Arrays.asList(new Object[][] {
{"download order test, enqueue default",
CollectionTestUtil.concat(QUEUE_DEFAULT_IDS, 101L),
CollectionTestUtil.concat(QUEUE_DEFAULT_IDS, CollectionTestUtil.list(101L, 102L)),
CollectionTestUtil.concat(QUEUE_DEFAULT_IDS, CollectionTestUtil.list(101L, 102L, 201L)),
CollectionTestUtil.concat(QUEUE_DEFAULT_IDS, CollectionTestUtil.list(101L, 102L, 201L, 202L)),
optDefault, QUEUE_DEFAULT},
concat(QUEUE_DEFAULT_IDS, 101L),
concat(QUEUE_DEFAULT_IDS, list(101L, 102L)),
concat(QUEUE_DEFAULT_IDS, list(101L, 102L, 201L)),
concat(QUEUE_DEFAULT_IDS, list(101L, 102L, 201L, 202L)),
BACK, QUEUE_DEFAULT},
{"download order test, enqueue at front",
CollectionTestUtil.concat(101L, QUEUE_DEFAULT_IDS),
CollectionTestUtil.concat(CollectionTestUtil.list(101L, 102L), QUEUE_DEFAULT_IDS),
CollectionTestUtil.concat(CollectionTestUtil.list(101L, 102L, 201L), QUEUE_DEFAULT_IDS),
CollectionTestUtil.concat(CollectionTestUtil.list(101L, 102L, 201L, 202L), QUEUE_DEFAULT_IDS),
optEnqAtFront, QUEUE_DEFAULT},
concat(101L, QUEUE_DEFAULT_IDS),
concat(list(101L, 102L), QUEUE_DEFAULT_IDS),
concat(list(101L, 102L, 201L), QUEUE_DEFAULT_IDS),
concat(list(101L, 102L, 201L, 202L), QUEUE_DEFAULT_IDS),
FRONT, QUEUE_DEFAULT},
});
}
@ -174,7 +187,7 @@ public class ItemEnqueuePositionCalculatorTest {
public List<Long> idsExpectedAfter202;
@Parameter(5)
public Options options;
public EnqueueLocation options;
@Parameter(6)
public List<FeedItem> queueInitial;
@ -217,7 +230,7 @@ public class ItemEnqueuePositionCalculatorTest {
FeedItem tFI202 = tFI_isDownloading(202, stubDownloadStateProvider);
doAddToQueueAndAssertResult(message + " (bulk insertion, 2nd item)",
calculator, 1, tFI202, queue,
calculator, 1, tFI202, queue, null,
idsExpectedAfter202);
// TODO: simulate download failure cases.
@ -249,31 +262,34 @@ public class ItemEnqueuePositionCalculatorTest {
FeedItem itemToAdd,
List<FeedItem> queue,
List<Long> idsExpected) {
int posActual = calculator.calcPosition(positionAmongAdd, itemToAdd, queue);
doAddToQueueAndAssertResult(message, calculator, positionAmongAdd, itemToAdd, queue, null, idsExpected);
}
static void doAddToQueueAndAssertResult(String message,
ItemEnqueuePositionCalculator calculator,
int positionAmongAdd,
FeedItem itemToAdd,
List<FeedItem> queue,
Playable currentlyPlaying,
List<Long> idsExpected) {
int posActual = calculator.calcPosition(positionAmongAdd, itemToAdd, queue, currentlyPlaying);
queue.add(posActual, itemToAdd);
assertEquals(message, idsExpected, getIdList(queue));
}
static final List<FeedItem> QUEUE_EMPTY = Collections.unmodifiableList(Arrays.asList());
static final List<FeedItem> QUEUE_DEFAULT = Collections.unmodifiableList(Arrays.asList(tFI(11), tFI(12), tFI(13), tFI(14)));
static final List<Long> QUEUE_DEFAULT_IDS = QUEUE_DEFAULT.stream().map(fi -> fi.getId()).collect(Collectors.toList());
static final List<FeedItem> QUEUE_DEFAULT =
Collections.unmodifiableList(Arrays.asList(tFI(11), tFI(12), tFI(13), tFI(14)));
static final List<Long> QUEUE_DEFAULT_IDS =
QUEUE_DEFAULT.stream().map(fi -> fi.getId()).collect(Collectors.toList());
static FeedItem tFI(long id) {
return tFI(id, -1);
}
static FeedItem tFI(long id, int position) {
FeedItem item = tFINoMedia(id);
FeedMedia media = new FeedMedia(item, "download_url", 1234567, "audio/mpeg");
media.setId(item.getId());
item.setMedia(media);
if (position >= 0) {
media.setPosition(position);
}
return item;
}