summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java67
-rw-r--r--app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java15
-rw-r--r--app/src/androidTest/java/de/test/antennapod/NthMatcher.java7
-rw-r--r--app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java17
-rw-r--r--app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java17
-rw-r--r--app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java17
-rw-r--r--app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java165
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java71
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java29
-rw-r--r--app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java36
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java22
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java8
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java21
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java13
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/TextOnlyFeedsTest.java71
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java29
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java9
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java4
-rw-r--r--app/src/main/res/layout/mediaplayerinfo_activity.xml2
-rw-r--r--app/src/main/res/xml/feed_settings.xml2
20 files changed, 355 insertions, 267 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
index c76cd2032..bbd8a705c 100644
--- a/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/EspressoTestUtils.java
@@ -1,6 +1,8 @@
package de.test.antennapod;
import android.content.Context;
+import android.content.Intent;
+import androidx.annotation.IdRes;
import androidx.annotation.StringRes;
import androidx.test.InstrumentationRegistry;
import androidx.test.espresso.PerformException;
@@ -14,11 +16,16 @@ import androidx.test.espresso.util.TreeIterables;
import android.view.View;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.service.download.DownloadService;
+import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.dialog.RatingDialog;
+import org.awaitility.Awaitility;
+import org.awaitility.core.ConditionTimeoutException;
import org.hamcrest.Matcher;
import java.io.File;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import static androidx.test.espresso.Espresso.onView;
@@ -77,6 +84,31 @@ public class EspressoTestUtils {
}
/**
+ * Perform action of waiting for a specific view id.
+ * https://stackoverflow.com/a/30338665/
+ * @param id The id of the child to click.
+ */
+ public static ViewAction clickChildViewWithId(final @IdRes int id) {
+ return new ViewAction() {
+ @Override
+ public Matcher<View> getConstraints() {
+ return null;
+ }
+
+ @Override
+ public String getDescription() {
+ return "Click on a child view with specified id.";
+ }
+
+ @Override
+ public void perform(UiController uiController, View view) {
+ View v = view.findViewById(id);
+ v.performClick();
+ }
+ };
+ }
+
+ /**
* Clear all app databases
*/
public static void clearPreferences() {
@@ -127,12 +159,37 @@ public class EspressoTestUtils {
onView(withId(R.id.drawer_layout)).perform(DrawerActions.open());
}
- public static void closeNavDrawer() {
- onView(isRoot()).perform(waitForView(withId(R.id.drawer_layout), 1000));
- onView(withId(R.id.drawer_layout)).perform(DrawerActions.close());
- }
-
public static ViewInteraction onDrawerItem(Matcher<View> viewMatcher) {
return onView(allOf(viewMatcher, withId(R.id.txtvTitle)));
}
+
+ public static void tryKillPlaybackService() {
+ Context context = InstrumentationRegistry.getTargetContext();
+ context.stopService(new Intent(context, PlaybackService.class));
+ try {
+ // Android has no reliable way to stop a service instantly.
+ // Calling stopSelf marks allows the system to destroy the service but the actual call
+ // to onDestroy takes until the next GC of the system, which we can not influence.
+ // Try to wait for the service at least a bit.
+ Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !PlaybackService.isRunning);
+ } catch (ConditionTimeoutException e) {
+ e.printStackTrace();
+ }
+ androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
+
+ public static void tryKillDownloadService() {
+ Context context = InstrumentationRegistry.getTargetContext();
+ context.stopService(new Intent(context, DownloadService.class));
+ try {
+ // Android has no reliable way to stop a service instantly.
+ // Calling stopSelf marks allows the system to destroy the service but the actual call
+ // to onDestroy takes until the next GC of the system, which we can not influence.
+ // Try to wait for the service at least a bit.
+ Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !DownloadService.isRunning);
+ } catch (ConditionTimeoutException e) {
+ e.printStackTrace();
+ }
+ androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+ }
}
diff --git a/app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java b/app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java
new file mode 100644
index 000000000..41ab15b9b
--- /dev/null
+++ b/app/src/androidTest/java/de/test/antennapod/IgnoreOnCi.java
@@ -0,0 +1,15 @@
+package de.test.antennapod;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Tests with this annotation are ignored on CI. This could be reasonable
+ * if the performance of the CI server is not enough to provide a reliable result.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface IgnoreOnCi {
+}
diff --git a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java
index 3f2b83a26..85eabcc63 100644
--- a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java
+++ b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java
@@ -11,10 +11,6 @@ public class NthMatcher {
return nth(matcher, 1);
}
- public static <T> Matcher<T> second(final Matcher<T> matcher) {
- return nth(matcher, 2);
- }
-
public static <T> Matcher<T> nth(final Matcher<T> matcher, final int index) {
return new BaseMatcher<T>() {
AtomicInteger count = new AtomicInteger(0);
@@ -31,7 +27,8 @@ public class NthMatcher {
@Override
public void describeTo(final Description description) {
- description.appendText("should return first matching item");
+ description.appendText("Item #" + index + " ");
+ description.appendDescriptionOf(matcher);
}
};
}
diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java
deleted file mode 100644
index a80ee41d7..000000000
--- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackBuiltinTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.test.antennapod.playback;
-
-import androidx.test.filters.LargeTest;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import org.junit.Before;
-
-/**
- * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity.
- */
-@LargeTest
-public class PlaybackBuiltinTest extends PlaybackTest {
- @Before
- public void setUp() throws Exception {
- super.setUp();
- UserPreferences.enableBuiltin();
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java
deleted file mode 100644
index 0cf73f069..000000000
--- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackExoplayerTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.test.antennapod.playback;
-
-import androidx.test.filters.LargeTest;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import org.junit.Before;
-
-/**
- * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity.
- */
-@LargeTest
-public class PlaybackExoplayerTest extends PlaybackTest {
- @Before
- public void setUp() throws Exception {
- super.setUp();
- UserPreferences.enableExoplayer();
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java
deleted file mode 100644
index a0fb74809..000000000
--- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackSonicTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package de.test.antennapod.playback;
-
-import androidx.test.filters.LargeTest;
-import de.danoeh.antennapod.core.preferences.UserPreferences;
-import org.junit.Before;
-
-/**
- * Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity.
- */
-@LargeTest
-public class PlaybackSonicTest extends PlaybackTest {
- @Before
- public void setUp() throws Exception {
- super.setUp();
- UserPreferences.enableSonic();
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
index be2fc432c..cc380813e 100644
--- a/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/playback/PlaybackTest.java
@@ -4,55 +4,79 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import android.view.KeyEvent;
+import android.view.View;
+import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.rule.ActivityTestRule;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
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.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.storage.DBWriter;
+import de.danoeh.antennapod.core.util.IntentUtils;
+import de.danoeh.antennapod.core.util.LongList;
import de.test.antennapod.EspressoTestUtils;
+import de.test.antennapod.IgnoreOnCi;
import de.test.antennapod.ui.UITestUtils;
import org.awaitility.Awaitility;
+import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.contrib.RecyclerViewActions.actionOnItemAtPosition;
+import static androidx.test.espresso.matcher.ViewMatchers.hasMinimumChildCount;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static de.test.antennapod.EspressoTestUtils.clickChildViewWithId;
import static de.test.antennapod.EspressoTestUtils.onDrawerItem;
import static de.test.antennapod.EspressoTestUtils.openNavDrawer;
import static de.test.antennapod.EspressoTestUtils.waitForView;
-import static de.test.antennapod.NthMatcher.first;
-import static de.test.antennapod.NthMatcher.nth;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* Test cases for starting and ending playback from the MainActivity and AudioPlayerActivity.
*/
-public abstract class PlaybackTest {
-
+@LargeTest
+@IgnoreOnCi
+@RunWith(Parameterized.class)
+public class PlaybackTest {
@Rule
public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(MainActivity.class, false, false);
+ @Parameterized.Parameter(value = 0)
+ public String playerToUse;
private UITestUtils uiTestUtils;
protected Context context;
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> initParameters() {
+ return Arrays.asList(new Object[][] { { "exoplayer" }, { "builtin" }, { "sonic" } });
+ }
+
@Before
public void setUp() throws Exception {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
@@ -60,6 +84,9 @@ public abstract class PlaybackTest {
EspressoTestUtils.clearDatabase();
EspressoTestUtils.makeNotFirstRun();
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ prefs.edit().putString(UserPreferences.PREF_MEDIA_PLAYER, playerToUse).apply();
+
uiTestUtils = new UITestUtils(context);
uiTestUtils.setup();
}
@@ -67,10 +94,8 @@ public abstract class PlaybackTest {
@After
public void tearDown() throws Exception {
activityTestRule.finishActivity();
+ EspressoTestUtils.tryKillPlaybackService();
uiTestUtils.tearDown();
- // shut down playback service
- context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
- Awaitility.await().until(() -> !PlaybackService.isRunning);
}
@Test
@@ -78,23 +103,9 @@ public abstract class PlaybackTest {
setContinuousPlaybackPreference(false);
uiTestUtils.addLocalFeedData(true);
activityTestRule.launchActivity(new Intent());
- List<FeedItem> queue = DBReader.getQueue();
- final FeedItem first = queue.get(0);
playFromQueue(0);
- Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getPlaybackController(getActivity()).getStatus()
- != PlayerStatus.PLAYING) {
- return true;
- } else if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId()
- != first.getMedia().getId();
- } else {
- return true;
- }
- });
-
- Thread.sleep(1000);
- assertNotEquals(PlayerStatus.PLAYING, uiTestUtils.getPlaybackController(getActivity()).getStatus());
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(
+ () -> uiTestUtils.getPlaybackController(getActivity()).getStatus() == PlayerStatus.INITIALIZED);
}
@Test
@@ -108,22 +119,10 @@ public abstract class PlaybackTest {
final FeedItem second = queue.get(1);
playFromQueue(0);
- Awaitility.await().atMost(2, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId()
- == first.getMedia().getId();
- } else {
- return false;
- }
- });
- Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId()
- == second.getMedia().getId();
- } else {
- return false;
- }
- });
+ Awaitility.await().atMost(2, TimeUnit.SECONDS).until(
+ () -> first.getMedia().equals(uiTestUtils.getCurrentMedia()));
+ Awaitility.await().atMost(6, TimeUnit.SECONDS).until(
+ () -> second.getMedia().equals(uiTestUtils.getCurrentMedia()));
}
@@ -213,33 +212,27 @@ public abstract class PlaybackTest {
}
private void skipEpisode() {
- Intent skipIntent = new Intent(PlaybackService.ACTION_SKIP_CURRENT_EPISODE);
- context.sendBroadcast(skipIntent);
+ IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SKIP_CURRENT_EPISODE);
}
protected void pauseEpisode() {
- Intent pauseIntent = new Intent(PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
- context.sendBroadcast(pauseIntent);
+ IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_PAUSE_PLAY_CURRENT_EPISODE);
}
protected void startLocalPlayback() {
openNavDrawer();
onDrawerItem(withText(R.string.episodes_label)).perform(click());
- onView(isRoot()).perform(waitForView(withId(R.id.emptyViewTitle), 1000));
+ onView(isRoot()).perform(waitForView(withText(R.string.all_episodes_short_label), 1000));
onView(withText(R.string.all_episodes_short_label)).perform(click());
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10);
- onView(isRoot()).perform(waitForView(withId(R.id.butSecondaryAction), 1000));
-
- onView(first(withId(R.id.butSecondaryAction))).perform(click());
- long mediaId = episodes.get(0).getMedia().getId();
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId;
- } else {
- return false;
- }
- });
+ Matcher<View> allEpisodesMatcher = allOf(withId(android.R.id.list), isDisplayed(), hasMinimumChildCount(2));
+ onView(isRoot()).perform(waitForView(allEpisodesMatcher, 1000));
+ onView(allEpisodesMatcher).perform(actionOnItemAtPosition(0, clickChildViewWithId(R.id.butSecondaryAction)));
+
+ FeedMedia media = episodes.get(0).getMedia();
+ Awaitility.await().atMost(1, TimeUnit.SECONDS).until(
+ () -> media.equals(uiTestUtils.getCurrentMedia()));
}
/**
@@ -249,16 +242,14 @@ public abstract class PlaybackTest {
protected void playFromQueue(int itemIdx) {
final List<FeedItem> queue = DBReader.getQueue();
- onView(nth(withId(R.id.butSecondaryAction), itemIdx + 1)).perform(click());
- onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000));
- long mediaId = queue.get(itemIdx).getMedia().getId();
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId;
- } else {
- return false;
- }
- });
+ Matcher<View> queueMatcher = allOf(withId(R.id.recyclerView), isDisplayed(), hasMinimumChildCount(2));
+ onView(isRoot()).perform(waitForView(queueMatcher, 1000));
+ onView(queueMatcher).perform(actionOnItemAtPosition(itemIdx, clickChildViewWithId(R.id.butSecondaryAction)));
+
+ FeedMedia media = queue.get(itemIdx).getMedia();
+ Awaitility.await().atMost(1, TimeUnit.SECONDS).until(
+ () -> media.equals(uiTestUtils.getCurrentMedia()));
+
}
/**
@@ -272,42 +263,36 @@ public abstract class PlaybackTest {
final List<FeedItem> episodes = DBReader.getRecentlyPublishedEpisodes(0, 10);
startLocalPlayback();
- long mediaId = episodes.get(0).getMedia().getId();
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId;
- } else {
- return false;
- }
- });
-
- Awaitility.await().atMost(5, TimeUnit.SECONDS).until(() ->
- uiTestUtils.getCurrentMedia(getActivity()) == null
- || uiTestUtils.getCurrentMedia(getActivity()).getId() != mediaId);
+ FeedMedia media = episodes.get(0).getMedia();
+ Awaitility.await().atMost(1, TimeUnit.SECONDS).until(
+ () -> media.equals(uiTestUtils.getCurrentMedia()));
+
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(
+ () -> !media.equals(uiTestUtils.getCurrentMedia()));
startLocalPlayback();
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(() -> {
- if (uiTestUtils.getCurrentMedia(getActivity()) != null) {
- return uiTestUtils.getCurrentMedia(getActivity()).getId() == mediaId;
- } else {
- return false;
- }
- });
+
+ Awaitility.await().atMost(1, TimeUnit.SECONDS).until(
+ () -> media.equals(uiTestUtils.getCurrentMedia()));
}
protected void doTestSmartMarkAsPlayed_Skip_ForEpisode(int itemIdxNegAllowed) throws Exception {
setSmartMarkAsPlayedPreference(60);
// ensure when an episode is skipped, it is removed due to smart as played
setSkipKeepsEpisodePreference(false);
+ uiTestUtils.setMediaFileName("30sec.mp3");
uiTestUtils.addLocalFeedData(true);
+ LongList queue = DBReader.getQueueIDList();
int fiIdx;
if (itemIdxNegAllowed >= 0) {
fiIdx = itemIdxNegAllowed;
} else { // negative index: count from the end, with -1 being the last one, etc.
- fiIdx = DBReader.getQueue().size() + itemIdxNegAllowed;
+ fiIdx = queue.size() + itemIdxNegAllowed;
}
- final FeedItem feedItem = DBReader.getQueue().get(fiIdx);
+ final long feedItemId = queue.get(fiIdx);
+ queue.removeIndex(fiIdx);
+ assertFalse(queue.contains(feedItemId)); // Verify that episode is in queue only once
activityTestRule.launchActivity(new Intent());
playFromQueue(fiIdx);
@@ -316,8 +301,8 @@ public abstract class PlaybackTest {
// assert item no longer in queue (needs to wait till skip is asynchronously processed)
Awaitility.await()
- .atMost(1000, MILLISECONDS)
- .until(() -> !DBReader.getQueue().contains(feedItem));
- assertTrue(DBReader.getFeedItem(feedItem.getId()).isPlayed());
+ .atMost(5000, MILLISECONDS)
+ .until(() -> !DBReader.getQueueIDList().contains(feedItemId));
+ assertTrue(DBReader.getFeedItem(feedItemId).isPlayed());
}
}
diff --git a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java
index d0e14d70a..1ca4de1ad 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/download/DownloadServiceTest.java
@@ -1,10 +1,13 @@
package de.test.antennapod.service.download;
+import android.content.Context;
+import android.content.Intent;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;
+import de.test.antennapod.EspressoTestUtils;
import org.awaitility.Awaitility;
import org.awaitility.core.ConditionTimeoutException;
import org.junit.After;
@@ -53,6 +56,8 @@ public class DownloadServiceTest {
@Before
public void setUp() throws Exception {
+ EspressoTestUtils.clearDatabase();
+ EspressoTestUtils.clearPreferences();
origFactory = DownloadService.getDownloaderFactory();
testFeed = setUpTestFeeds();
testMedia11 = testFeed.getItemAtIndex(0).getMedia();
@@ -77,6 +82,10 @@ public class DownloadServiceTest {
@After
public void tearDown() throws Exception {
DownloadService.setDownloaderFactory(origFactory);
+ Context context = InstrumentationRegistry.getTargetContext();
+ DownloadRequester.getInstance().cancelAllDownloads(context);
+ context.stopService(new Intent(context, DownloadService.class));
+ EspressoTestUtils.tryKillDownloadService();
}
@Test
@@ -136,8 +145,9 @@ public class DownloadServiceTest {
}
private void doTestCancelDownload_UndoEnqueue(boolean itemAlreadyInQueue) throws Exception {
+ Context context = InstrumentationRegistry.getTargetContext();
// let download takes longer to ensure the test can cancel the download in time
- DownloadService.setDownloaderFactory(new StubDownloaderFactory(150, downloadStatus -> {
+ DownloadService.setDownloaderFactory(new StubDownloaderFactory(10000, downloadStatus -> {
downloadStatus.setSuccessful();
}));
UserPreferences.setEnqueueDownloadedEpisodes(true);
@@ -146,45 +156,38 @@ public class DownloadServiceTest {
final long item1Id = testMedia11.getItem().getId();
if (itemAlreadyInQueue) {
// simulate item already in queue condition
- DBWriter.addQueueItem(InstrumentationRegistry.getTargetContext(), false, item1Id).get();
+ DBWriter.addQueueItem(context, false, item1Id).get();
assertTrue(DBReader.getQueueIDList().contains(item1Id));
} else {
assertFalse(DBReader.getQueueIDList().contains(item1Id));
}
withFeedItemEventListener(feedItemEventListener -> {
- try {
- DownloadRequester.getInstance().downloadMedia(false, InstrumentationRegistry.getTargetContext(),
- testMedia11.getItem());
- if (itemAlreadyInQueue) {
- Awaitility.await("download service receives the request - "
- + "no event is expected before cancel is issued")
- .atLeast(100, TimeUnit.MILLISECONDS)
- .until(() -> true);
- } else {
- Awaitility.await("item enqueue event")
- .atMost(1000, TimeUnit.MILLISECONDS)
- .until(() -> feedItemEventListener.getEvents().size() >= 1);
- }
- DownloadRequester.getInstance().cancelDownload(InstrumentationRegistry.getTargetContext(),
- testMedia11);
- final int totalNumEventsExpected = itemAlreadyInQueue ? 1 : 3;
- Awaitility.await("item dequeue event + download termination event")
- .atMost(1000, TimeUnit.MILLISECONDS)
- .until(() ->feedItemEventListener.getEvents().size() >= totalNumEventsExpected);
- assertFalse("The download should have been canceled",
- DBReader.getFeedMedia(testMedia11.getId()).isDownloaded());
- if (itemAlreadyInQueue) {
- assertTrue("The FeedItem should still be in the queue after the download is cancelled."
- + " It's there before download.",
- DBReader.getQueueIDList().contains(item1Id));
- } else {
- assertFalse("The FeedItem should not be in the queue after the download is cancelled.",
- DBReader.getQueueIDList().contains(item1Id));
- }
- } catch (ConditionTimeoutException cte) {
- fail("The expected FeedItemEvent (for media download complete) has not been posted. "
- + cte.getMessage());
+ DownloadRequester.getInstance().downloadMedia(false, context, testMedia11.getItem());
+ if (itemAlreadyInQueue) {
+ Awaitility.await("download service receives the request - "
+ + "no event is expected before cancel is issued")
+ .atLeast(100, TimeUnit.MILLISECONDS)
+ .until(() -> true);
+ } else {
+ Awaitility.await("item enqueue event")
+ .atMost(2000, TimeUnit.MILLISECONDS)
+ .until(() -> feedItemEventListener.getEvents().size() >= 1);
+ }
+ DownloadRequester.getInstance().cancelDownload(context, testMedia11);
+ final int totalNumEventsExpected = itemAlreadyInQueue ? 1 : 3;
+ Awaitility.await("item dequeue event + download termination event")
+ .atMost(1000, TimeUnit.MILLISECONDS)
+ .until(() -> feedItemEventListener.getEvents().size() >= totalNumEventsExpected);
+ assertFalse("The download should have been canceled",
+ DBReader.getFeedMedia(testMedia11.getId()).isDownloaded());
+ if (itemAlreadyInQueue) {
+ assertTrue("The FeedItem should still be in the queue after the download is cancelled."
+ + " It's there before download.",
+ DBReader.getQueueIDList().contains(item1Id));
+ } else {
+ assertFalse("The FeedItem should not be in the queue after the download is cancelled.",
+ DBReader.getQueueIDList().contains(item1Id));
}
});
}
diff --git a/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java b/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java
index 4530b7679..7d9ec7c98 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/download/HttpDownloaderTest.java
@@ -29,10 +29,9 @@ public class HttpDownloaderTest {
private static final String TAG = "HttpDownloaderTest";
private static final String DOWNLOAD_DIR = "testdownloads";
- private static boolean successful = true;
-
+ private String url404;
+ private String urlAuth;
private File destDir;
-
private HTTPBin httpServer;
public HttpDownloaderTest() {
@@ -57,6 +56,8 @@ public class HttpDownloaderTest {
assertTrue(destDir.exists());
httpServer = new HTTPBin();
httpServer.start();
+ url404 = httpServer.getBaseUrl() + "/status/404";
+ urlAuth = httpServer.getBaseUrl() + "/basic-auth/user/passwd";
}
private FeedFileImpl setupFeedFile(String downloadUrl, String title, boolean deleteExisting) {
@@ -88,33 +89,29 @@ public class HttpDownloaderTest {
return downloader;
}
-
- private static final String URL_404 = HTTPBin.BASE_URL + "/status/404";
- private static final String URL_AUTH = HTTPBin.BASE_URL + "/basic-auth/user/passwd";
-
@Test
public void testPassingHttp() {
- download(HTTPBin.BASE_URL + "/status/200", "test200", true);
+ download(httpServer.getBaseUrl() + "/status/200", "test200", true);
}
@Test
public void testRedirect() {
- download(HTTPBin.BASE_URL + "/redirect/4", "testRedirect", true);
+ download(httpServer.getBaseUrl() + "/redirect/4", "testRedirect", true);
}
@Test
public void testGzip() {
- download(HTTPBin.BASE_URL + "/gzip/100", "testGzip", true);
+ download(httpServer.getBaseUrl() + "/gzip/100", "testGzip", true);
}
@Test
public void test404() {
- download(URL_404, "test404", false);
+ download(url404, "test404", false);
}
@Test
public void testCancel() {
- final String url = HTTPBin.BASE_URL + "/delay/3";
+ final String url = httpServer.getBaseUrl() + "/delay/3";
FeedFileImpl feedFile = setupFeedFile(url, "delay", true);
final Downloader downloader = new HttpDownloader(new DownloadRequest(feedFile.getFile_url(), url, "delay", 0, feedFile.getTypeAsInt()));
Thread t = new Thread() {
@@ -139,7 +136,7 @@ public class HttpDownloaderTest {
@Test
public void testDeleteOnFailShouldDelete() {
- Downloader downloader = download(URL_404, "testDeleteOnFailShouldDelete", false, true, null, null, true);
+ Downloader downloader = download(url404, "testDeleteOnFailShouldDelete", false, true, null, null, true);
assertFalse(new File(downloader.getDownloadRequest().getDestination()).exists());
}
@@ -149,18 +146,18 @@ public class HttpDownloaderTest {
File dest = new File(destDir, filename);
dest.delete();
assertTrue(dest.createNewFile());
- Downloader downloader = download(URL_404, filename, false, false, null, null, false);
+ Downloader downloader = download(url404, filename, false, false, null, null, false);
assertTrue(new File(downloader.getDownloadRequest().getDestination()).exists());
}
@Test
public void testAuthenticationShouldSucceed() throws InterruptedException {
- download(URL_AUTH, "testAuthSuccess", true, true, "user", "passwd", true);
+ download(urlAuth, "testAuthSuccess", true, true, "user", "passwd", true);
}
@Test
public void testAuthenticationShouldFail() {
- Downloader downloader = download(URL_AUTH, "testAuthSuccess", false, true, "user", "Wrong passwd", true);
+ Downloader downloader = download(urlAuth, "testAuthSuccess", false, true, "user", "Wrong passwd", true);
assertEquals(DownloadError.ERROR_UNAUTHORIZED, downloader.getResult().getReason());
}
diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
index 3511fd0b1..c17324750 100644
--- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceMediaPlayerTest.java
@@ -2,8 +2,8 @@ package de.test.antennapod.service.playback;
import android.content.Context;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.MediumTest;
+import androidx.test.platform.app.InstrumentationRegistry;
import de.test.antennapod.EspressoTestUtils;
import junit.framework.AssertionFailedError;
@@ -32,7 +32,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -45,13 +45,12 @@ import static org.junit.Assert.fail;
*/
@MediumTest
public class PlaybackServiceMediaPlayerTest {
- private static final String PLAYABLE_FILE_URL = "http://127.0.0.1:" + HTTPBin.PORT + "/files/0";
private static final String PLAYABLE_DEST_URL = "psmptestfile.mp3";
private String PLAYABLE_LOCAL_URL = null;
private static final int LATCH_TIMEOUT_SECONDS = 3;
private HTTPBin httpServer;
-
+ private String playableFileUrl;
private volatile AssertionFailedError assertionError;
@After
@@ -67,10 +66,11 @@ public class PlaybackServiceMediaPlayerTest {
EspressoTestUtils.makeNotFirstRun();
EspressoTestUtils.clearDatabase();
- final Context context = InstrumentationRegistry.getTargetContext();
+ final Context context = getInstrumentation().getTargetContext();
httpServer = new HTTPBin();
httpServer.start();
+ playableFileUrl = httpServer.getBaseUrl() + "/files/0";
File cacheDir = context.getExternalFilesDir("testFiles");
if (cacheDir == null)
@@ -81,7 +81,7 @@ public class PlaybackServiceMediaPlayerTest {
assertTrue(cacheDir.canWrite());
assertTrue(cacheDir.canRead());
if (!dest.exists()) {
- InputStream i = InstrumentationRegistry.getContext().getAssets().open("3sec.mp3");
+ InputStream i = getInstrumentation().getTargetContext().getAssets().open("3sec.mp3");
OutputStream o = new FileOutputStream(new File(cacheDir, PLAYABLE_DEST_URL));
IOUtils.copy(i, o);
o.flush();
@@ -167,7 +167,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
+ Playable p = writeTestPlayable(playableFileUrl, null);
psmp.playMediaObject(p, true, false, false);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -207,7 +207,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
+ Playable p = writeTestPlayable(playableFileUrl, null);
psmp.playMediaObject(p, true, true, false);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
@@ -251,7 +251,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
+ Playable p = writeTestPlayable(playableFileUrl, null);
psmp.playMediaObject(p, true, false, true);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -296,7 +296,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, null);
+ Playable p = writeTestPlayable(playableFileUrl, null);
psmp.playMediaObject(p, true, true, true);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -334,7 +334,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
psmp.playMediaObject(p, false, false, false);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -373,7 +373,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
psmp.playMediaObject(p, false, true, false);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -415,7 +415,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
psmp.playMediaObject(p, false, false, true);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -460,7 +460,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
psmp.playMediaObject(p, false, true, true);
boolean res = countDownLatch.await(LATCH_TIMEOUT_SECONDS, TimeUnit.SECONDS);
if (assertionError != null)
@@ -523,7 +523,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
if (initialState == PlayerStatus.PLAYING) {
psmp.playMediaObject(p, stream, true, true);
}
@@ -616,7 +616,7 @@ public class PlaybackServiceMediaPlayerTest {
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
if (initialState == PlayerStatus.PREPARED || initialState == PlayerStatus.PLAYING || initialState == PlayerStatus.PAUSED) {
boolean startWhenPrepared = (initialState != PlayerStatus.PREPARED);
- psmp.playMediaObject(writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL), false, startWhenPrepared, true);
+ psmp.playMediaObject(writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL), false, startWhenPrepared, true);
}
if (initialState == PlayerStatus.PAUSED) {
psmp.pause(false, false);
@@ -673,7 +673,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
if (initialState == PlayerStatus.INITIALIZED
|| initialState == PlayerStatus.PLAYING
|| initialState == PlayerStatus.PREPARED
@@ -747,7 +747,7 @@ public class PlaybackServiceMediaPlayerTest {
}
});
PlaybackServiceMediaPlayer psmp = new LocalPSMP(c, callback);
- Playable p = writeTestPlayable(PLAYABLE_FILE_URL, PLAYABLE_LOCAL_URL);
+ Playable p = writeTestPlayable(playableFileUrl, PLAYABLE_LOCAL_URL);
boolean prepareImmediately = initialState != PlayerStatus.INITIALIZED;
boolean startImmediately = initialState != PlayerStatus.PREPARED;
psmp.playMediaObject(p, false, startImmediately, prepareImmediately);
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
index 00eef5c8d..b89f1b9bc 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/AutoDownloadTest.java
@@ -7,6 +7,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.core.app.ApplicationProvider;
+import androidx.test.platform.app.InstrumentationRegistry;
+import de.test.antennapod.EspressoTestUtils;
import org.awaitility.Awaitility;
import org.awaitility.core.ConditionTimeoutException;
import org.junit.After;
@@ -14,6 +16,7 @@ import org.junit.Before;
import org.junit.Test;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.DBTasksCallbacks;
@@ -49,21 +52,16 @@ public class AutoDownloadTest {
dbTasksCallbacksOrig = ClientConfig.dbTasksCallbacks;
- // create new database
- PodDBAdapter.init(context);
- PodDBAdapter.deleteDatabase();
- PodDBAdapter adapter = PodDBAdapter.getInstance();
- adapter.open();
- adapter.close();
+ EspressoTestUtils.clearPreferences();
+ EspressoTestUtils.clearDatabase();
+ UserPreferences.setAllowMobileStreaming(true);
}
@After
public void tearDown() throws Exception {
- stubFeedsServer.tearDown();
ClientConfig.dbTasksCallbacks = dbTasksCallbacksOrig;
-
- context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
- Awaitility.await().until(() -> !PlaybackService.isRunning);
+ EspressoTestUtils.tryKillPlaybackService();
+ stubFeedsServer.tearDown();
}
/**
@@ -117,7 +115,7 @@ public class AutoDownloadTest {
FeedMedia media = item.getMedia();
DBTasks.playMedia(context, media, false, true, true);
Awaitility.await("episode is playing")
- .atMost(1000, MILLISECONDS)
+ .atMost(2000, MILLISECONDS)
.until(() -> item.equals(getCurrentlyPlaying()));
}
@@ -126,7 +124,7 @@ public class AutoDownloadTest {
if (playable == null) {
return null;
}
- return ((FeedMedia)playable).getItem();
+ return ((FeedMedia) playable).getItem();
}
private void useDownloadAlgorithm(final AutomaticDownloadAlgorithm downloadAlgorithm) {
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
index 42c770df9..0784cb078 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
@@ -29,10 +29,12 @@ import static androidx.test.espresso.contrib.ActivityResultMatchers.hasResultCod
import static androidx.test.espresso.intent.Intents.intended;
import static androidx.test.espresso.intent.Intents.times;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
+import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static de.test.antennapod.EspressoTestUtils.clickPreference;
import static de.test.antennapod.EspressoTestUtils.openNavDrawer;
+import static de.test.antennapod.EspressoTestUtils.waitForView;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -75,11 +77,11 @@ public class MainActivityTest {
final Feed feed = uiTestUtils.hostedFeeds.get(0);
openNavDrawer();
onView(withText(R.string.add_feed_label)).perform(click());
- onView(withId(R.id.etxtFeedurl)).perform(typeText(feed.getDownload_url()));
- onView(withText(R.string.confirm_label)).perform(scrollTo()).perform(click());
+ onView(withId(R.id.etxtFeedurl)).perform(scrollTo(), typeText(feed.getDownload_url()));
+ onView(withText(R.string.confirm_label)).perform(scrollTo(), click());
Espresso.closeSoftKeyboard();
onView(withText(R.string.subscribe_label)).perform(click());
- intended(hasComponent(MainActivity.class.getName()), times(2));
+ onView(isRoot()).perform(waitForView(withId(R.id.butShowSettings), 5000));
}
private String getActionbarTitle() {
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 e734e4a67..a68afbc2e 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -32,6 +32,7 @@ import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.scrollTo;
+import static androidx.test.espresso.action.ViewActions.swipeDown;
import static androidx.test.espresso.action.ViewActions.swipeUp;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
@@ -246,10 +247,10 @@ public class PreferencesTest {
public void testPauseForInterruptions() {
onView(withText(R.string.playback_pref)).perform(click());
final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss();
- onView(withText(R.string.pref_pausePlaybackForFocusLoss_title)).perform(click());
+ clickPreference(R.string.pref_pausePlaybackForFocusLoss_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> pauseForFocusLoss != UserPreferences.shouldPauseForFocusLoss());
- onView(withText(R.string.pref_pausePlaybackForFocusLoss_title)).perform(click());
+ clickPreference(R.string.pref_pausePlaybackForFocusLoss_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> pauseForFocusLoss == UserPreferences.shouldPauseForFocusLoss());
}
@@ -332,7 +333,8 @@ public class PreferencesTest {
clickPreference(R.string.network_pref);
clickPreference(R.string.pref_automatic_download_title);
clickPreference(R.string.pref_episode_cache_title);
- onView(withText(minEntry)).perform(scrollTo()).perform(click());
+ onView(withId(R.id.select_dialog_listview)).perform(swipeDown());
+ onView(withText(minEntry)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> UserPreferences.getEpisodeCacheSize() == minValue);
}
@@ -346,6 +348,7 @@ public class PreferencesTest {
onView(withText(R.string.network_pref)).perform(click());
onView(withText(R.string.pref_automatic_download_title)).perform(click());
onView(withText(R.string.pref_episode_cache_title)).perform(click());
+ onView(withId(R.id.select_dialog_listview)).perform(swipeUp());
onView(withText(maxEntry)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> UserPreferences.getEpisodeCacheSize() == maxValue);
@@ -365,17 +368,17 @@ public class PreferencesTest {
Awaitility.await().atMost(1000, MILLISECONDS)
.until(UserPreferences::isEnableAutodownload);
final boolean enableAutodownloadOnBattery = UserPreferences.isEnableAutodownloadOnBattery();
- onView(withText(R.string.pref_automatic_download_on_battery_title)).perform(click());
+ clickPreference(R.string.pref_automatic_download_on_battery_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> enableAutodownloadOnBattery != UserPreferences.isEnableAutodownloadOnBattery());
- onView(withText(R.string.pref_automatic_download_on_battery_title)).perform(click());
+ clickPreference(R.string.pref_automatic_download_on_battery_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> enableAutodownloadOnBattery == UserPreferences.isEnableAutodownloadOnBattery());
final boolean enableWifiFilter = UserPreferences.isEnableAutodownloadWifiFilter();
- onView(withText(R.string.pref_autodl_wifi_filter_title)).perform(click());
+ clickPreference(R.string.pref_autodl_wifi_filter_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> enableWifiFilter != UserPreferences.isEnableAutodownloadWifiFilter());
- onView(withText(R.string.pref_autodl_wifi_filter_title)).perform(click());
+ clickPreference(R.string.pref_autodl_wifi_filter_title);
Awaitility.await().atMost(1000, MILLISECONDS)
.until(() -> enableWifiFilter == UserPreferences.isEnableAutodownloadWifiFilter());
}
@@ -425,7 +428,7 @@ public class PreferencesTest {
clickPreference(R.string.network_pref);
clickPreference(R.string.pref_automatic_download_title);
clickPreference(R.string.pref_episode_cleanup_title);
- String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 5, 5);
+ String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 3, 3);
onView(isRoot()).perform(waitForView(withText(search), 1000));
onView(withText(search)).perform(click());
Awaitility.await().atMost(1000, MILLISECONDS)
@@ -433,7 +436,7 @@ public class PreferencesTest {
EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm();
if (alg instanceof APCleanupAlgorithm) {
APCleanupAlgorithm cleanupAlg = (APCleanupAlgorithm) alg;
- return cleanupAlg.getNumberOfHoursAfterPlayback() == 120; // 5 days
+ return cleanupAlg.getNumberOfHoursAfterPlayback() == 72; // 5 days
}
return false;
});
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java
index d28858f72..df32ed3c0 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/SpeedChangeTest.java
@@ -11,11 +11,11 @@ import de.danoeh.antennapod.activity.AudioplayerActivity;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.preferences.PlaybackPreferences;
import de.danoeh.antennapod.core.preferences.UserPreferences;
-import de.danoeh.antennapod.core.service.playback.PlaybackService;
import de.danoeh.antennapod.core.service.playback.PlayerStatus;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.fragment.QueueFragment;
import de.test.antennapod.EspressoTestUtils;
+import de.test.antennapod.IgnoreOnCi;
import org.awaitility.Awaitility;
import org.junit.After;
import org.junit.Before;
@@ -39,6 +39,7 @@ import static de.test.antennapod.EspressoTestUtils.waitForView;
* User interface tests for changing the playback speed.
*/
@RunWith(AndroidJUnit4.class)
+@IgnoreOnCi
public class SpeedChangeTest {
@Rule
@@ -68,9 +69,7 @@ public class SpeedChangeTest {
UserPreferences.setPlaybackSpeedArray(new String[] {"1.00", "2.00", "3.00"});
availableSpeeds = UserPreferences.getPlaybackSpeedArray();
- context.sendBroadcast(new Intent(PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE));
- Awaitility.await().until(() -> !PlaybackService.isRunning);
-
+ EspressoTestUtils.tryKillPlaybackService();
activityRule.launchActivity(new Intent());
}
@@ -88,7 +87,7 @@ public class SpeedChangeTest {
public void testChangeSpeedPlaying() {
onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000));
onView(withId(R.id.butPlay)).perform(click());
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(()
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(()
-> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING);
clickThroughSpeeds();
}
@@ -97,10 +96,10 @@ public class SpeedChangeTest {
public void testChangeSpeedPaused() {
onView(isRoot()).perform(waitForView(withId(R.id.butPlay), 1000));
onView(withId(R.id.butPlay)).perform(click());
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(()
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(()
-> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PLAYING);
onView(withId(R.id.butPlay)).perform(click());
- Awaitility.await().atMost(1, TimeUnit.SECONDS).until(()
+ Awaitility.await().atMost(5, TimeUnit.SECONDS).until(()
-> activityRule.getActivity().getPlaybackController().getStatus() == PlayerStatus.PAUSED);
clickThroughSpeeds();
}
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/TextOnlyFeedsTest.java b/app/src/androidTest/java/de/test/antennapod/ui/TextOnlyFeedsTest.java
new file mode 100644
index 000000000..7ba7a57f2
--- /dev/null
+++ b/app/src/androidTest/java/de/test/antennapod/ui/TextOnlyFeedsTest.java
@@ -0,0 +1,71 @@
+package de.test.antennapod.ui;
+
+import android.content.Intent;
+import androidx.test.espresso.intent.rule.IntentsTestRule;
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+import de.danoeh.antennapod.R;
+import de.danoeh.antennapod.activity.MainActivity;
+import de.danoeh.antennapod.core.feed.Feed;
+import de.test.antennapod.EspressoTestUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.action.ViewActions.scrollTo;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
+import static androidx.test.espresso.matcher.ViewMatchers.withText;
+import static de.test.antennapod.EspressoTestUtils.onDrawerItem;
+import static de.test.antennapod.EspressoTestUtils.openNavDrawer;
+import static de.test.antennapod.EspressoTestUtils.waitForView;
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.not;
+
+/**
+ * Test UI for feeds that do not have media files
+ */
+@RunWith(AndroidJUnit4.class)
+public class TextOnlyFeedsTest {
+
+ private UITestUtils uiTestUtils;
+
+ @Rule
+ public IntentsTestRule<MainActivity> activityRule = new IntentsTestRule<>(MainActivity.class, false, false);
+
+ @Before
+ public void setUp() throws IOException {
+ EspressoTestUtils.clearPreferences();
+ EspressoTestUtils.makeNotFirstRun();
+ EspressoTestUtils.clearDatabase();
+
+ uiTestUtils = new UITestUtils(InstrumentationRegistry.getInstrumentation().getTargetContext());
+ uiTestUtils.setHostTextOnlyFeeds(true);
+ uiTestUtils.setup();
+
+ activityRule.launchActivity(new Intent());
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ uiTestUtils.tearDown();
+ }
+
+ @Test
+ public void testMarkAsPlayedList() throws Exception {
+ uiTestUtils.addLocalFeedData(false);
+ final Feed feed = uiTestUtils.hostedFeeds.get(0);
+ openNavDrawer();
+ onDrawerItem(withText(feed.getTitle())).perform(scrollTo(), click());
+ onView(withText(feed.getItemAtIndex(0).getTitle())).perform(click());
+ onView(withText(R.string.mark_read_label)).perform(click());
+ onView(isRoot()).perform(waitForView(allOf(withText(R.string.mark_read_label), not(isDisplayed())), 3000));
+ }
+
+}
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
index 66404e2a8..8e16d1a3b 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -5,6 +5,7 @@ import android.graphics.Bitmap;
import android.util.Log;
import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
+import de.danoeh.antennapod.core.util.playback.Playable;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -42,6 +43,7 @@ public class UITestUtils {
private static final int NUM_ITEMS_PER_FEED = 10;
private String testFileName = "3sec.mp3";
+ private boolean hostTextOnlyFeeds = false;
private final Context context;
private final HTTPBin server = new HTTPBin();
private File destDir;
@@ -87,13 +89,13 @@ public class UITestUtils {
out.close();
int id = server.serveFile(feedFile);
Assert.assertTrue(id != -1);
- return String.format("%s/files/%d", HTTPBin.BASE_URL, id);
+ return String.format("%s/files/%d", server.getBaseUrl(), id);
}
private String hostFile(File file) {
int id = server.serveFile(file);
Assert.assertTrue(id != -1);
- return String.format("%s/files/%d", HTTPBin.BASE_URL, id);
+ return String.format("%s/files/%d", server.getBaseUrl(), id);
}
private File newBitmapFile(String name) throws IOException {
@@ -141,9 +143,10 @@ public class UITestUtils {
"http://example.com/feed" + i + "/item/" + j, new Date(), FeedItem.UNPLAYED, feed);
items.add(item);
- File mediaFile = newMediaFile("feed-" + i + "-episode-" + j + ".mp3");
- item.setMedia(new FeedMedia(j, item, 0, 0, mediaFile.length(), "audio/mp3", null, hostFile(mediaFile), false, null, 0, 0));
-
+ if (!hostTextOnlyFeeds) {
+ File mediaFile = newMediaFile("feed-" + i + "-episode-" + j + ".mp3");
+ item.setMedia(new FeedMedia(j, item, 0, 0, mediaFile.length(), "audio/mp3", null, hostFile(mediaFile), false, null, 0, 0));
+ }
}
feed.setItems(items);
feed.setDownload_url(hostFeed(feed));
@@ -190,7 +193,9 @@ public class UITestUtils {
}
queue.add(feed.getItems().get(0));
- feed.getItems().get(1).getMedia().setPlaybackCompletionDate(new Date());
+ if (feed.getItems().get(1).hasMedia()) {
+ feed.getItems().get(1).getMedia().setPlaybackCompletionDate(new Date());
+ }
}
localFeedDataAdded = true;
@@ -204,15 +209,21 @@ public class UITestUtils {
}
public PlaybackController getPlaybackController(MainActivity mainActivity) {
- ExternalPlayerFragment fragment = (ExternalPlayerFragment)mainActivity.getSupportFragmentManager().findFragmentByTag(ExternalPlayerFragment.TAG);
+ ExternalPlayerFragment fragment = (ExternalPlayerFragment) mainActivity.getSupportFragmentManager()
+ .findFragmentByTag(ExternalPlayerFragment.TAG);
return fragment.getPlaybackControllerTestingOnly();
}
- public FeedMedia getCurrentMedia(MainActivity mainActivity) {
- return (FeedMedia)getPlaybackController(mainActivity).getMedia();
+ public FeedMedia getCurrentMedia() {
+ Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(context);
+ return (FeedMedia) playable;
}
public void setMediaFileName(String filename) {
testFileName = filename;
}
+
+ public void setHostTextOnlyFeeds(boolean hostTextOnlyFeeds) {
+ this.hostTextOnlyFeeds = hostTextOnlyFeeds;
+ }
}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java b/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java
index 49befd775..c588cdbc2 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/service/download/HTTPBin.java
@@ -39,9 +39,6 @@ import de.danoeh.antennapod.BuildConfig;
*/
public class HTTPBin extends NanoHTTPD {
private static final String TAG = "HTTPBin";
- public static final int PORT = 8124;
- public static final String BASE_URL = "http://127.0.0.1:" + HTTPBin.PORT;
-
private static final String MIME_HTML = "text/html";
private static final String MIME_PLAIN = "text/plain";
@@ -49,10 +46,14 @@ public class HTTPBin extends NanoHTTPD {
private final List<File> servedFiles;
public HTTPBin() {
- super(PORT);
+ super(0); // Let system pick a free port
this.servedFiles = new ArrayList<>();
}
+ public String getBaseUrl() {
+ return "http://127.0.0.1:" + getListeningPort();
+ }
+
/**
* Adds the given file to the server.
*
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
index 9a88441e0..2806f48ba 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -235,7 +235,7 @@ public class ItemFragment extends Fragment {
@Override
public void onResume() {
super.onResume();
- if(itemsLoaded) {
+ if (itemsLoaded) {
progbarLoading.setVisibility(View.GONE);
updateAppearance();
}
@@ -459,7 +459,7 @@ public class ItemFragment extends Fragment {
}
}
- @Subscribe
+ @Subscribe(threadMode = ThreadMode.MAIN)
public void onUnreadItemsChanged(UnreadItemsUpdateEvent event) {
load();
}
diff --git a/app/src/main/res/layout/mediaplayerinfo_activity.xml b/app/src/main/res/layout/mediaplayerinfo_activity.xml
index b759b0092..636cbb015 100644
--- a/app/src/main/res/layout/mediaplayerinfo_activity.xml
+++ b/app/src/main/res/layout/mediaplayerinfo_activity.xml
@@ -169,7 +169,7 @@
android:contentDescription="@string/set_playback_speed_label"
android:src="?attr/av_speed"
android:scaleType="fitCenter"
- tools:src="@drawable/ic_playback_speed_white"
+ tools:src="@drawable/ic_playback_speed_white_48dp"
tools:visibility="gone"
tools:background="@android:color/holo_green_dark" />
diff --git a/app/src/main/res/xml/feed_settings.xml b/app/src/main/res/xml/feed_settings.xml
index edc608d60..37c47e5f2 100644
--- a/app/src/main/res/xml/feed_settings.xml
+++ b/app/src/main/res/xml/feed_settings.xml
@@ -16,7 +16,7 @@
<ListPreference
android:key="feedPlaybackSpeed"
- android:icon="?attr/av_speed"
+ android:icon="?attr/ic_settings_speed"
android:title="@string/playback_speed"
android:summary="@string/pref_feed_playback_speed_sum"/>