summaryrefslogtreecommitdiff
path: root/app/src/androidTest/java/de/test/antennapod
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/androidTest/java/de/test/antennapod')
-rw-r--r--app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java18
-rw-r--r--app/src/androidTest/java/de/test/antennapod/NthMatcher.java38
-rw-r--r--app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java1
-rw-r--r--app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java34
-rw-r--r--app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java29
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java1
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java1
-rw-r--r--app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java320
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java206
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java2
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java288
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java12
-rw-r--r--app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java6
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java35
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java51
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java22
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java89
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java5
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java1
-rw-r--r--app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java7
20 files changed, 624 insertions, 542 deletions
diff --git a/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java b/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java
deleted file mode 100644
index c321e6494..000000000
--- a/app/src/androidTest/java/de/test/antennapod/AntennaPodTestRunner.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.test.antennapod;
-
-import android.test.InstrumentationTestRunner;
-import android.test.suitebuilder.TestSuiteBuilder;
-
-import junit.framework.TestSuite;
-
-public class AntennaPodTestRunner extends InstrumentationTestRunner {
-
- @Override
- public TestSuite getAllTests() {
- return new TestSuiteBuilder(AntennaPodTestRunner.class)
- .includeAllPackagesUnderHere()
- .excludePackages("de.test.antennapod.gpodnet")
- .build();
- }
-
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/NthMatcher.java b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java
new file mode 100644
index 000000000..f9ecacda5
--- /dev/null
+++ b/app/src/androidTest/java/de/test/antennapod/NthMatcher.java
@@ -0,0 +1,38 @@
+package de.test.antennapod;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class NthMatcher {
+ public static <T> Matcher<T> first(final Matcher<T> matcher) {
+ return nth(matcher, 1);
+ }
+
+ public static <T> Matcher<T> second(final Matcher<T> matcher) {
+ return nth(matcher, 2);
+ }
+
+ private static <T> Matcher<T> nth(final Matcher<T> matcher, final int index) {
+ return new BaseMatcher<T>() {
+ AtomicInteger count = new AtomicInteger(0);
+
+ @Override
+ public boolean matches(final Object item) {
+ if (matcher.matches(item)) {
+ if (count.incrementAndGet() == index) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void describeTo(final Description description) {
+ description.appendText("should return first matching item");
+ }
+ };
+ }
+}
diff --git a/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java b/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java
index db463132d..ced0d7a28 100644
--- a/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java
@@ -1,6 +1,7 @@
package de.test.antennapod.feed;
import android.test.AndroidTestCase;
+
import de.danoeh.antennapod.core.feed.FeedItem;
public class FeedItemTest extends AndroidTestCase {
diff --git a/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java b/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java
index a880c330b..91e31e73c 100644
--- a/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/gpodnet/GPodnetServiceTest.java
@@ -1,43 +1,43 @@
package de.test.antennapod.gpodnet;
-import android.test.AndroidTestCase;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import android.support.test.runner.AndroidJUnit4;
import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetDevice;
import de.danoeh.antennapod.core.gpoddernet.model.GpodnetTag;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
import static java.util.Collections.singletonList;
/**
* Test class for GpodnetService
*/
-public class GPodnetServiceTest extends AndroidTestCase {
+@Ignore
+@RunWith(AndroidJUnit4.class)
+public class GPodnetServiceTest {
private GpodnetService service;
private static final String USER = "";
private static final String PW = "";
- @Override
- protected void setUp() throws Exception {
- super.setUp();
+ @Before
+ protected void setUp() {
service = new GpodnetService();
}
- @Override
- protected void tearDown() throws Exception {
- super.tearDown();
- }
-
private void authenticate() throws GpodnetServiceException {
service.authenticate(USER, PW);
}
+ @Test
public void testUploadSubscription() throws GpodnetServiceException {
authenticate();
ArrayList<String> l = new ArrayList<>();
@@ -45,6 +45,7 @@ public class GPodnetServiceTest extends AndroidTestCase {
service.uploadSubscriptions(USER, "radio", l);
}
+ @Test
public void testUploadSubscription2() throws GpodnetServiceException {
authenticate();
ArrayList<String> l = new ArrayList<>();
@@ -53,6 +54,7 @@ public class GPodnetServiceTest extends AndroidTestCase {
service.uploadSubscriptions(USER, "radio", l);
}
+ @Test
public void testUploadChanges() throws GpodnetServiceException {
authenticate();
String[] URLS = {"http://bitsundso.de/feed", "http://gamesundso.de/feed", "http://cre.fm/feed/mp3/", "http://freakshow.fm/feed/m4a/"};
@@ -63,53 +65,63 @@ public class GPodnetServiceTest extends AndroidTestCase {
service.uploadChanges(USER, "radio", added, removed);
}
+ @Test
public void testGetSubscriptionChanges() throws GpodnetServiceException {
authenticate();
service.getSubscriptionChanges(USER, "radio", 1362322610L);
}
+ @Test
public void testGetSubscriptionsOfUser()
throws GpodnetServiceException {
authenticate();
service.getSubscriptionsOfUser(USER);
}
+ @Test
public void testGetSubscriptionsOfDevice()
throws GpodnetServiceException {
authenticate();
service.getSubscriptionsOfDevice(USER, "radio");
}
+ @Test
public void testConfigureDevices() throws GpodnetServiceException {
authenticate();
service.configureDevice(USER, "foo", "This is an updated caption",
GpodnetDevice.DeviceType.LAPTOP);
}
+ @Test
public void testGetDevices() throws GpodnetServiceException {
authenticate();
service.getDevices(USER);
}
+ @Test
public void testGetSuggestions() throws GpodnetServiceException {
authenticate();
service.getSuggestions(10);
}
+ @Test
public void testTags() throws GpodnetServiceException {
service.getTopTags(20);
}
+ @Test
public void testPodcastForTags() throws GpodnetServiceException {
List<GpodnetTag> tags = service.getTopTags(20);
service.getPodcastsForTag(tags.get(1),
10);
}
+ @Test
public void testSearch() throws GpodnetServiceException {
service.searchPodcasts("linux", 64);
}
+ @Test
public void testToplist() throws GpodnetServiceException {
service.getPodcastToplist(10);
}
diff --git a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
index 39abe4b7a..9419d2318 100644
--- a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java
@@ -1,6 +1,7 @@
package de.test.antennapod.handler;
import android.content.Context;
+import android.support.test.InstrumentationRegistry;
import android.test.InstrumentationTestCase;
import org.xml.sax.SAXException;
@@ -17,7 +18,6 @@ import javax.xml.parsers.ParserConfigurationException;
import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.syndication.handler.FeedHandler;
@@ -37,7 +37,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
protected void setUp() throws Exception {
super.setUp();
- Context context = getInstrumentation().getContext();
+ Context context = InstrumentationRegistry.getTargetContext();
File destDir = context.getExternalFilesDir(FEEDS_DIR);
assertNotNull(destDir);
@@ -82,15 +82,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
assertEquals(feed.getLink(), parsedFeed.getLink());
assertEquals(feed.getDescription(), parsedFeed.getDescription());
assertEquals(feed.getPaymentLink(), parsedFeed.getPaymentLink());
-
- if (feed.getImage() != null) {
- FeedImage image = feed.getImage();
- FeedImage parsedImage = parsedFeed.getImage();
- assertNotNull(parsedImage);
-
- assertEquals(image.getTitle(), parsedImage.getTitle());
- assertEquals(image.getDownload_url(), parsedImage.getDownload_url());
- }
+ assertEquals(feed.getImageUrl(), parsedFeed.getImageUrl());
if (feed.getItems() != null) {
assertNotNull(parsedFeed.getItems());
@@ -119,14 +111,7 @@ public class FeedHandlerTest extends InstrumentationTestCase {
assertEquals(media.getMime_type(), parsedMedia.getMime_type());
}
- if (item.hasItemImage()) {
- assertTrue(parsedItem.hasItemImage());
- FeedImage image = item.getImage();
- FeedImage parsedImage = parsedItem.getImage();
-
- assertEquals(image.getTitle(), parsedImage.getTitle());
- assertEquals(image.getDownload_url(), parsedImage.getDownload_url());
- }
+ assertEquals(item.getImageUrl(), parsedFeed.getImageUrl());
if (item.getChapters() != null) {
assertNotNull(parsedItem.getChapters());
@@ -158,12 +143,8 @@ public class FeedHandlerTest extends InstrumentationTestCase {
}
private Feed createTestFeed(int numItems, boolean withImage, boolean withFeedMedia, boolean withChapters) {
- FeedImage image = null;
- if (withImage) {
- image = new FeedImage(0, "image", null, "http://example.com/picture", false);
- }
Feed feed = new Feed(0, null, "title", "http://example.com", "This is the description",
- "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", image, file.getAbsolutePath(),
+ "http://example.com/payment", "Daniel", "en", null, "http://example.com/feed", "http://example.com/picture", file.getAbsolutePath(),
"http://example.com/feed", true);
feed.setItems(new ArrayList<>());
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 93a9408b7..9cd7689ba 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTasksTest.java
@@ -5,7 +5,6 @@ import android.test.FlakyTest;
import android.test.InstrumentationTestCase;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
index c9c715a86..a577e5e36 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java
@@ -21,6 +21,7 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus;
*/
class DBTestUtils {
+ private DBTestUtils(){}
/**
* Use this method when tests don't involve chapters.
*/
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 b1cc807ea..27d76116d 100644
--- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java
@@ -1,10 +1,14 @@
package de.test.antennapod.storage;
import android.content.Context;
+import android.content.SharedPreferences;
import android.database.Cursor;
+import android.preference.PreferenceManager;
import android.test.InstrumentationTestCase;
import android.util.Log;
+import org.awaitility.Awaitility;
+
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
@@ -15,15 +19,14 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import de.danoeh.antennapod.core.feed.Chapter;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
-import de.danoeh.antennapod.core.feed.SimpleChapter;
+import de.danoeh.antennapod.core.preferences.UserPreferences;
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;
/**
* Test class for DBWriter
@@ -58,6 +61,12 @@ public class DBWriterTest extends InstrumentationTestCase {
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.close();
+
+ Context context = getInstrumentation().getTargetContext();
+ SharedPreferences.Editor prefEdit = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext()).edit();
+ prefEdit.putBoolean(UserPreferences.PREF_DELETE_REMOVES_FROM_QUEUE, true).commit();
+
+ UserPreferences.init(context);
}
public void testSetFeedMediaPlaybackInformation()
@@ -124,89 +133,54 @@ public class DBWriterTest extends InstrumentationTestCase {
assertNull(media.getFile_url());
}
- public void testDeleteFeed() throws IOException, ExecutionException, InterruptedException, TimeoutException {
- File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
- assertNotNull(destFolder);
-
- Feed feed = new Feed("url", null, "title");
- feed.setItems(new ArrayList<>());
+ public void testDeleteFeedMediaOfItemRemoveFromQueue()
+ throws IOException, ExecutionException, InterruptedException, TimeoutException {
+ assertTrue(UserPreferences.shouldDeleteRemoveFromQueue());
- // create Feed image
- File imgFile = new File(destFolder, "image");
- assertTrue(imgFile.createNewFile());
- FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
- image.setOwner(feed);
- feed.setImage(image);
+ File dest = new File(getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER), "testFile");
- List<File> itemFiles = new ArrayList<>();
- // create items with downloaded media files
- for (int i = 0; i < 10; i++) {
- FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed, true);
- feed.getItems().add(item);
+ assertTrue(dest.createNewFile());
- File enc = new File(destFolder, "file " + i);
- assertTrue(enc.createNewFile());
- itemFiles.add(enc);
+ Feed feed = new Feed("url", null, "title");
+ List<FeedItem> items = new ArrayList<>();
+ List<FeedItem> queue = new ArrayList<>();
+ feed.setItems(items);
+ FeedItem item = new FeedItem(0, "Item", "Item", "url", new Date(), FeedItem.UNPLAYED, feed);
- FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0, 0);
- item.setMedia(media);
+ FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", dest.getAbsolutePath(), "download_url", true, null, 0, 0);
+ item.setMedia(media);
- item.setChapters(new ArrayList<>());
- item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com"));
- }
+ items.add(item);
+ queue.add(item);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setCompleteFeed(feed);
+ adapter.setQueue(queue);
adapter.close();
+ assertTrue(media.getId() != 0);
+ assertTrue(item.getId() != 0);
+ queue = DBReader.getQueue();
+ assertTrue(queue.size() != 0);
- assertTrue(feed.getId() != 0);
- assertTrue(feed.getImage().getId() != 0);
- for (FeedItem item : feed.getItems()) {
- assertTrue(item.getId() != 0);
- assertTrue(item.getMedia().getId() != 0);
- assertTrue(item.getChapters().get(0).getId() != 0);
- }
-
- DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
-
- // check if files still exist
- assertFalse(imgFile.exists());
- for (File f : itemFiles) {
- assertFalse(f.exists());
- }
-
- adapter = PodDBAdapter.getInstance();
- adapter.open();
- Cursor c = adapter.getFeedCursor(feed.getId());
- assertEquals(0, c.getCount());
- c.close();
- c = adapter.getImageCursor(String.valueOf(image.getId()));
- assertEquals(0, c.getCount());
- c.close();
- for (FeedItem item : feed.getItems()) {
- c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
- assertEquals(0, c.getCount());
- c.close();
- c = adapter.getSingleFeedMediaCursor(item.getMedia().getId());
- assertEquals(0, c.getCount());
- c.close();
- c = adapter.getSimpleChaptersOfFeedItemCursor(item);
- assertEquals(0, c.getCount());
- c.close();
- }
- adapter.close();
+ DBWriter.deleteFeedMediaOfItem(getInstrumentation().getTargetContext(), media.getId());
+ Awaitility.await().until(() -> dest.exists() == false);
+ media = DBReader.getFeedMedia(media.getId());
+ assertNotNull(media);
+ assertFalse(dest.exists());
+ assertFalse(media.isDownloaded());
+ assertNull(media.getFile_url());
+ queue = DBReader.getQueue();
+ assertTrue(queue.size() == 0);
}
- public void testDeleteFeedNoImage() throws ExecutionException, InterruptedException, IOException, TimeoutException {
+ public void testDeleteFeed() throws ExecutionException, InterruptedException, IOException, TimeoutException {
File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
assertNotNull(destFolder);
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- feed.setImage(null);
-
List<File> itemFiles = new ArrayList<>();
// create items with downloaded media files
for (int i = 0; i < 10; i++) {
@@ -261,13 +235,7 @@ public class DBWriterTest extends InstrumentationTestCase {
Feed feed = new Feed("url", null, "title");
feed.setItems(null);
-
- // create Feed image
- File imgFile = new File(destFolder, "image");
- assertTrue(imgFile.createNewFile());
- FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
- image.setOwner(feed);
- feed.setImage(image);
+ feed.setImageUrl("url");
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
@@ -275,21 +243,14 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
assertTrue(feed.getId() != 0);
- assertTrue(feed.getImage().getId() != 0);
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
- // check if files still exist
- assertFalse(imgFile.exists());
-
adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0);
c.close();
- c = adapter.getImageCursor(String.valueOf(image.getId()));
- assertTrue(c.getCount() == 0);
- c.close();
adapter.close();
}
@@ -300,12 +261,7 @@ public class DBWriterTest extends InstrumentationTestCase {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- // create Feed image
- File imgFile = new File(destFolder, "image");
- assertTrue(imgFile.createNewFile());
- FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
- image.setOwner(feed);
- feed.setImage(image);
+ feed.setImageUrl("url");
// create items
for (int i = 0; i < 10; i++) {
@@ -320,87 +276,22 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
assertTrue(feed.getId() != 0);
- assertTrue(feed.getImage().getId() != 0);
- for (FeedItem item : feed.getItems()) {
- assertTrue(item.getId() != 0);
- }
-
- DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
-
- // check if files still exist
- assertFalse(imgFile.exists());
-
- adapter = PodDBAdapter.getInstance();
- adapter.open();
- Cursor c = adapter.getFeedCursor(feed.getId());
- assertTrue(c.getCount() == 0);
- c.close();
- c = adapter.getImageCursor(String.valueOf(image.getId()));
- assertTrue(c.getCount() == 0);
- c.close();
- for (FeedItem item : feed.getItems()) {
- c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
- assertTrue(c.getCount() == 0);
- c.close();
- }
- adapter.close();
- }
-
- public void testDeleteFeedWithItemImages() throws InterruptedException, ExecutionException, TimeoutException, IOException {
- File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER);
- assertNotNull(destFolder);
-
- Feed feed = new Feed("url", null, "title");
- feed.setItems(new ArrayList<>());
-
- // create Feed image
- File imgFile = new File(destFolder, "image");
- assertTrue(imgFile.createNewFile());
- FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
- image.setOwner(feed);
- feed.setImage(image);
-
- // create items with images
- for (int i = 0; i < 10; i++) {
- FeedItem item = new FeedItem(0, "Item " + i, "Item" + i, "url", new Date(), FeedItem.PLAYED, feed);
- feed.getItems().add(item);
- File itemImageFile = new File(destFolder, "item-image-" + i);
- FeedImage itemImage = new FeedImage(0, "item-image" + i, itemImageFile.getAbsolutePath(), "url", true);
- item.setImage(itemImage);
- }
-
- PodDBAdapter adapter = PodDBAdapter.getInstance();
- adapter.open();
- adapter.setCompleteFeed(feed);
- adapter.close();
-
- assertTrue(feed.getId() != 0);
- assertTrue(feed.getImage().getId() != 0);
for (FeedItem item : feed.getItems()) {
assertTrue(item.getId() != 0);
- assertTrue(item.getImage().getId() != 0);
}
DBWriter.deleteFeed(getInstrumentation().getTargetContext(), feed.getId()).get(TIMEOUT, TimeUnit.SECONDS);
- // check if files still exist
- assertFalse(imgFile.exists());
adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0);
c.close();
- c = adapter.getImageCursor(String.valueOf(image.getId()));
- assertTrue(c.getCount() == 0);
- c.close();
for (FeedItem item : feed.getItems()) {
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
assertTrue(c.getCount() == 0);
c.close();
- c = adapter.getImageCursor(String.valueOf(item.getImage().getId()));
- assertEquals(0, c.getCount());
- c.close();
}
adapter.close();
}
@@ -412,11 +303,7 @@ public class DBWriterTest extends InstrumentationTestCase {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- // create Feed image
- File imgFile = new File(destFolder, "image");
- FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
- image.setOwner(feed);
- feed.setImage(image);
+ feed.setImageUrl("url");
List<File> itemFiles = new ArrayList<>();
// create items with downloaded media files
@@ -437,7 +324,6 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
assertTrue(feed.getId() != 0);
- assertTrue(feed.getImage().getId() != 0);
for (FeedItem item : feed.getItems()) {
assertTrue(item.getId() != 0);
assertTrue(item.getMedia().getId() != 0);
@@ -460,9 +346,6 @@ public class DBWriterTest extends InstrumentationTestCase {
Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0);
c.close();
- c = adapter.getImageCursor(String.valueOf(image.getId()));
- assertTrue(c.getCount() == 0);
- c.close();
for (FeedItem item : feed.getItems()) {
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
assertTrue(c.getCount() == 0);
@@ -484,11 +367,7 @@ public class DBWriterTest extends InstrumentationTestCase {
Feed feed = new Feed("url", null, "title");
feed.setItems(new ArrayList<>());
- // create Feed image
- File imgFile = new File(destFolder, "image");
- FeedImage image = new FeedImage(0, "image", imgFile.getAbsolutePath(), "url", true);
- image.setOwner(feed);
- feed.setImage(image);
+ feed.setImageUrl("url");
List<File> itemFiles = new ArrayList<>();
// create items with downloaded media files
@@ -509,7 +388,6 @@ public class DBWriterTest extends InstrumentationTestCase {
adapter.close();
assertTrue(feed.getId() != 0);
- assertTrue(feed.getImage().getId() != 0);
for (FeedItem item : feed.getItems()) {
assertTrue(item.getId() != 0);
assertTrue(item.getMedia().getId() != 0);
@@ -522,9 +400,6 @@ public class DBWriterTest extends InstrumentationTestCase {
Cursor c = adapter.getFeedCursor(feed.getId());
assertTrue(c.getCount() == 0);
c.close();
- c = adapter.getImageCursor(String.valueOf(image.getId()));
- assertTrue(c.getCount() == 0);
- c.close();
for (FeedItem item : feed.getItems()) {
c = adapter.getFeedItemCursor(String.valueOf(item.getId()));
assertTrue(c.getCount() == 0);
@@ -700,29 +575,16 @@ public class DBWriterTest extends InstrumentationTestCase {
public void testRemoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
final Context context = getInstrumentation().getTargetContext();
- Feed feed = new Feed("url", null, "title");
- feed.setItems(new ArrayList<>());
- for (int i = 0; i < NUM_ITEMS; i++) {
- FeedItem item = new FeedItem(0, "title " + i, "id " + i, "link " + i, new Date(), FeedItem.PLAYED, feed);
- feed.getItems().add(item);
- }
-
- PodDBAdapter adapter = PodDBAdapter.getInstance();
- adapter.open();
- adapter.setCompleteFeed(feed);
- adapter.close();
+ Feed feed = createTestFeed(NUM_ITEMS);
- for (FeedItem item : feed.getItems()) {
- assertTrue(item.getId() != 0);
- }
for (int removeIndex = 0; removeIndex < NUM_ITEMS; removeIndex++) {
final FeedItem item = feed.getItems().get(removeIndex);
- adapter = PodDBAdapter.getInstance();
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setQueue(feed.getItems());
adapter.close();
- DBWriter.removeQueueItem(context, item, false).get(TIMEOUT, TimeUnit.SECONDS);
+ DBWriter.removeQueueItem(context, false, item).get(TIMEOUT, TimeUnit.SECONDS);
adapter = PodDBAdapter.getInstance();
adapter.open();
Cursor queue = adapter.getQueueIDCursor();
@@ -742,6 +604,43 @@ public class DBWriterTest extends InstrumentationTestCase {
}
}
+ public void testRemoveQueueItemMultipleItems() throws InterruptedException, ExecutionException, TimeoutException {
+ // Setup test data
+ //
+ final int NUM_ITEMS = 5;
+ final int NUM_IN_QUEUE = NUM_ITEMS - 1; // the last one not in queue for boundary condition
+ final Context context = getInstrumentation().getTargetContext();
+ Feed feed = createTestFeed(NUM_ITEMS);
+
+ List<FeedItem> itemsToAdd = feed.getItems().subList(0, NUM_IN_QUEUE);
+ withPodDB(adapter -> adapter.setQueue(itemsToAdd) );
+
+ // Actual tests
+ //
+
+ // Use array rather than List to make codes more succinct
+ Long[] itemIds = toItemIds(feed.getItems()).toArray(new Long[0]);
+
+ DBWriter.removeQueueItem(context, false,
+ itemIds[1], itemIds[3]).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Average case - 2 items removed successfully",
+ itemIds[0], itemIds[2]);
+
+ DBWriter.removeQueueItem(context, false).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Boundary case - no items supplied. queue should see no change",
+ itemIds[0], itemIds[2]);
+
+ DBWriter.removeQueueItem(context, false,
+ itemIds[0], itemIds[4], -1L).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Boundary case - items not in queue ignored",
+ itemIds[2]);
+
+ DBWriter.removeQueueItem(context, false,
+ itemIds[2], -1L).get(TIMEOUT, TimeUnit.SECONDS);
+ assertQueueByItemIds("Boundary case - invalid itemIds ignored"); // the queue is empty
+
+ }
+
public void testMoveQueueItem() throws InterruptedException, ExecutionException, TimeoutException {
final int NUM_ITEMS = 10;
Feed feed = new Feed("url", null, "title");
@@ -839,4 +738,53 @@ public class DBWriterTest extends InstrumentationTestCase {
assertTrue(item.isPlayed());
}
}
+
+ private static Feed createTestFeed(int numItems) {
+ Feed feed = new Feed("url", null, "title");
+ feed.setItems(new ArrayList<>());
+ 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);
+ }
+
+ withPodDB(adapter -> adapter.setCompleteFeed(feed));
+
+ for (FeedItem item : feed.getItems()) {
+ assertTrue(item.getId() != 0);
+ }
+ return feed;
+ }
+
+ private static void withPodDB(Consumer<PodDBAdapter> action) {
+ PodDBAdapter adapter = PodDBAdapter.getInstance();
+ try {
+ adapter.open();
+ action.accept(adapter);
+ } finally {
+ adapter.close();
+ }
+ }
+
+ private static void assertQueueByItemIds(
+ String message,
+ long... itemIdsExpected
+ ) {
+ List<FeedItem> queue = DBReader.getQueue();
+ List<Long> itemIdsActualList = toItemIds(queue);
+ List<Long> itemIdsExpectedList = new ArrayList<Long>(itemIdsExpected.length);
+ for (long id : itemIdsExpected) {
+ itemIdsExpectedList.add(id);
+ }
+
+ assertEquals(message, itemIdsExpectedList, itemIdsActualList);
+ }
+
+ private static List<Long> toItemIds(List<FeedItem> items) {
+ List<Long> itemIds = new ArrayList<Long>(items.size());
+ for(FeedItem item : items) {
+ itemIds.add(item.getId());
+ }
+ return itemIds;
+ }
+
}
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 6156da926..9a60b04b8 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/MainActivityTest.java
@@ -2,16 +2,14 @@ package de.test.antennapod.ui;
import android.content.Context;
import android.content.SharedPreferences;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.FlakyTest;
+import android.support.test.espresso.contrib.DrawerActions;
+import android.support.test.espresso.intent.Intents;
+import android.support.test.filters.FlakyTest;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
import android.widget.ListView;
-
import com.robotium.solo.Solo;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
+import com.robotium.solo.Timeout;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.activity.OnlineFeedViewActivity;
@@ -23,25 +21,46 @@ import de.danoeh.antennapod.fragment.DownloadsFragment;
import de.danoeh.antennapod.fragment.EpisodesFragment;
import de.danoeh.antennapod.fragment.PlaybackHistoryFragment;
import de.danoeh.antennapod.fragment.QueueFragment;
+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 java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.longClick;
+import static android.support.test.espresso.intent.Intents.intended;
+import static android.support.test.espresso.intent.matcher.IntentMatchers.hasComponent;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static de.test.antennapod.NthMatcher.first;
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.assertEquals;
/**
* User interface tests for MainActivity
*/
-public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
+@RunWith(AndroidJUnit4.class)
+public class MainActivityTest {
private Solo solo;
private UITestUtils uiTestUtils;
-
private SharedPreferences prefs;
- public MainActivityTest() {
- super(MainActivity.class);
- }
+ @Rule
+ public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
- @Override
- protected void setUp() throws Exception {
- super.setUp();
- Context context = getInstrumentation().getTargetContext();
+ @Before
+ public void setUp() throws IOException {
+ Intents.init();
+ Context context = mActivityRule.getActivity();
uiTestUtils = new UITestUtils(context);
uiTestUtils.setup();
@@ -54,30 +73,26 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
// override first launch preference
// do this BEFORE calling getActivity()!
- prefs = getInstrumentation().getTargetContext().getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE);
+ prefs = context.getSharedPreferences(MainActivity.PREF_NAME, Context.MODE_PRIVATE);
prefs.edit().putBoolean(MainActivity.PREF_IS_FIRST_LAUNCH, false).commit();
- solo = new Solo(getInstrumentation(), getActivity());
+ solo = new Solo(getInstrumentation(), mActivityRule.getActivity());
}
- @Override
- protected void tearDown() throws Exception {
+ @After
+ public void tearDown() throws Exception {
uiTestUtils.tearDown();
solo.finishOpenedActivities();
-
+ Intents.release();
PodDBAdapter.deleteDatabase();
-
- // reset preferences
prefs.edit().clear().commit();
-
- super.tearDown();
}
private void openNavDrawer() {
- solo.clickOnImageButton(0);
- getInstrumentation().waitForIdleSync();
+ onView(withId(R.id.drawer_layout)).perform(DrawerActions.open());
}
+ @Test
public void testAddFeed() throws Exception {
uiTestUtils.addHostedFeedData();
final Feed feed = uiTestUtils.hostedFeeds.get(0);
@@ -89,10 +104,12 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
solo.waitForView(R.id.butSubscribe);
assertEquals(solo.getString(R.string.subscribe_label), solo.getButton(0).getText().toString());
solo.clickOnButton(0);
- solo.waitForText(solo.getString(R.string.subscribed_label));
+ assertTrue(solo.waitForText(solo.getString(R.string.open_podcast), 0, Timeout.getLargeTimeout(), false));
}
- @FlakyTest(tolerance = 3)
+
+ @Test
+ @FlakyTest
public void testClickNavDrawer() throws Exception {
uiTestUtils.addLocalFeedData(false);
@@ -150,57 +167,60 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
return ((MainActivity) solo.getCurrentActivity()).getSupportActionBar().getTitle().toString();
}
- @SuppressWarnings("unchecked")
- @FlakyTest(tolerance = 3)
+
+ @Test
+ @FlakyTest
public void testGoToPreferences() {
openNavDrawer();
- solo.clickOnText(solo.getString(R.string.settings_label));
- solo.waitForActivity(PreferenceActivity.class);
+ onView(withText(R.string.settings_label)).perform(click());
+ intended(hasComponent(PreferenceActivity.class.getName()));
}
+ @Test
public void testDrawerPreferencesHideSomeElements() {
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
openNavDrawer();
- solo.clickLongOnText(solo.getString(R.string.queue_label));
- solo.waitForDialogToOpen();
- solo.clickOnText(solo.getString(R.string.episodes_label));
- solo.clickOnText(solo.getString(R.string.playback_history_label));
- solo.clickOnText(solo.getString(R.string.confirm_label));
- solo.waitForDialogToClose();
+ onView(first(withText(R.string.queue_label))).perform(longClick());
+ onView(withText(R.string.episodes_label)).perform(click());
+ onView(withText(R.string.playback_history_label)).perform(click());
+ onView(withText(R.string.confirm_label)).perform(click());
+
List<String> hidden = UserPreferences.getHiddenDrawerItems();
assertEquals(2, hidden.size());
assertTrue(hidden.contains(EpisodesFragment.TAG));
assertTrue(hidden.contains(PlaybackHistoryFragment.TAG));
}
+ @Test
public void testDrawerPreferencesUnhideSomeElements() {
List<String> hidden = Arrays.asList(PlaybackHistoryFragment.TAG, DownloadsFragment.TAG);
UserPreferences.setHiddenDrawerItems(hidden);
openNavDrawer();
- solo.clickLongOnText(solo.getString(R.string.queue_label));
- solo.waitForDialogToOpen();
- solo.clickOnText(solo.getString(R.string.downloads_label));
- solo.clickOnText(solo.getString(R.string.queue_label));
- solo.clickOnText(solo.getString(R.string.confirm_label));
- solo.waitForDialogToClose();
+ onView(first(withText(R.string.queue_label))).perform(longClick());
+
+ onView(withText(R.string.downloads_label)).perform(click());
+ onView(withText(R.string.queue_label)).perform(click());
+ onView(withText(R.string.confirm_label)).perform(click());
+
hidden = UserPreferences.getHiddenDrawerItems();
assertEquals(2, hidden.size());
assertTrue(hidden.contains(QueueFragment.TAG));
assertTrue(hidden.contains(PlaybackHistoryFragment.TAG));
}
+
+ @Test
public void testDrawerPreferencesHideAllElements() {
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
- String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles);
+ String[] titles = mActivityRule.getActivity().getResources().getStringArray(R.array.nav_drawer_titles);
openNavDrawer();
- solo.clickLongOnText(solo.getString(R.string.queue_label));
- solo.waitForDialogToOpen();
+ onView(first(withText(R.string.queue_label))).perform(longClick());
for (String title : titles) {
- solo.clickOnText(title);
+ onView(first(withText(title))).perform(click());
}
- solo.clickOnText(solo.getString(R.string.confirm_label));
- solo.waitForDialogToClose();
+ onView(withText(R.string.confirm_label)).perform(click());
+
List<String> hidden = UserPreferences.getHiddenDrawerItems();
assertEquals(titles.length, hidden.size());
for (String tag : MainActivity.NAV_DRAWER_TAGS) {
@@ -208,21 +228,85 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
}
}
+ @Test
public void testDrawerPreferencesHideCurrentElement() {
UserPreferences.setHiddenDrawerItems(new ArrayList<>());
-
openNavDrawer();
- String downloads = solo.getString(R.string.downloads_label);
- solo.clickOnText(downloads);
- solo.waitForView(android.R.id.list);
+ onView(withText(R.string.downloads_label)).perform(click());
openNavDrawer();
- solo.clickLongOnText(downloads);
- solo.waitForDialogToOpen();
- solo.clickOnText(downloads);
- solo.clickOnText(solo.getString(R.string.confirm_label));
- solo.waitForDialogToClose();
+
+ onView(first(withText(R.string.queue_label))).perform(longClick());
+ onView(first(withText(R.string.downloads_label))).perform(click());
+ onView(withText(R.string.confirm_label)).perform(click());
+
List<String> hidden = UserPreferences.getHiddenDrawerItems();
assertEquals(1, hidden.size());
assertTrue(hidden.contains(DownloadsFragment.TAG));
}
+
+ @Test
+ public void testBackButtonBehaviorGoToPage() {
+ openNavDrawer();
+ solo.clickOnText(solo.getString(R.string.settings_label));
+ solo.clickOnText(solo.getString(R.string.user_interface_label));
+ solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title));
+ solo.clickOnText(solo.getString(R.string.back_button_go_to_page));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.subscriptions_label));
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ solo.goBackToActivity(MainActivity.class.getSimpleName());
+ solo.goBack();
+ assertEquals(solo.getString(R.string.subscriptions_label), getActionbarTitle());
+ }
+
+ @Test
+ public void testBackButtonBehaviorOpenDrawer() {
+ openNavDrawer();
+ solo.clickOnText(solo.getString(R.string.settings_label));
+ solo.clickOnText(solo.getString(R.string.user_interface_label));
+ solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title));
+ solo.clickOnText(solo.getString(R.string.back_button_open_drawer));
+ solo.goBackToActivity(MainActivity.class.getSimpleName());
+ solo.goBack();
+ assertTrue(((MainActivity)solo.getCurrentActivity()).isDrawerOpen());
+ }
+
+ @Test
+ public void testBackButtonBehaviorDoubleTap() {
+ openNavDrawer();
+ solo.clickOnText(solo.getString(R.string.settings_label));
+ solo.clickOnText(solo.getString(R.string.user_interface_label));
+ solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title));
+ solo.clickOnText(solo.getString(R.string.back_button_double_tap));
+ solo.goBackToActivity(MainActivity.class.getSimpleName());
+ solo.goBack();
+ solo.goBack();
+ assertTrue(solo.getCurrentActivity().isFinishing());
+ }
+
+ @Test
+ public void testBackButtonBehaviorPrompt() {
+ openNavDrawer();
+ solo.clickOnText(solo.getString(R.string.settings_label));
+ solo.clickOnText(solo.getString(R.string.user_interface_label));
+ solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title));
+ solo.clickOnText(solo.getString(R.string.back_button_show_prompt));
+ solo.goBackToActivity(MainActivity.class.getSimpleName());
+ solo.goBack();
+ solo.clickOnText(solo.getString(R.string.yes));
+ solo.waitForDialogToClose();
+ assertTrue(solo.getCurrentActivity().isFinishing());
+ }
+
+ @Test
+ public void testBackButtonBehaviorDefault() {
+ openNavDrawer();
+ solo.clickOnText(solo.getString(R.string.settings_label));
+ solo.clickOnText(solo.getString(R.string.user_interface_label));
+ solo.clickOnText(solo.getString(R.string.pref_back_button_behavior_title));
+ solo.clickOnText(solo.getString(R.string.back_button_default));
+ solo.goBackToActivity(MainActivity.class.getSimpleName());
+ solo.goBack();
+ assertTrue(solo.getCurrentActivity().isFinishing());
+ }
}
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java
index 293ed2848..55ed998bb 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java
@@ -59,7 +59,7 @@ public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActi
.clear()
.putBoolean(UserPreferences.PREF_UNPAUSE_ON_HEADSET_RECONNECT, false)
.putBoolean(UserPreferences.PREF_PAUSE_ON_HEADSET_DISCONNECT, false)
- .putBoolean(UserPreferences.PREF_SONIC, true)
+ .putString(UserPreferences.PREF_MEDIA_PLAYER, "sonic")
.commit();
solo = new Solo(getInstrumentation(), getActivity());
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 9a5ea437c..d934bf3e2 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java
@@ -1,12 +1,23 @@
package de.test.antennapod.ui;
-import android.content.Context;
+import android.content.SharedPreferences;
import android.content.res.Resources;
-import android.test.ActivityInstrumentationTestCase2;
+import android.preference.PreferenceManager;
+import android.support.test.espresso.contrib.RecyclerViewActions;
+import android.support.test.rule.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
import com.robotium.solo.Solo;
import com.robotium.solo.Timeout;
+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 java.util.Arrays;
import java.util.concurrent.TimeUnit;
@@ -17,36 +28,48 @@ import de.danoeh.antennapod.core.storage.APCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APNullCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.APQueueCleanupAlgorithm;
import de.danoeh.antennapod.core.storage.EpisodeCleanupAlgorithm;
-
-public class PreferencesTest extends ActivityInstrumentationTestCase2<PreferenceActivity> {
-
- private static final String TAG = "PreferencesTest";
-
+import de.danoeh.antennapod.fragment.EpisodesFragment;
+import de.danoeh.antennapod.fragment.QueueFragment;
+import de.danoeh.antennapod.fragment.SubscriptionFragment;
+
+import static android.support.test.InstrumentationRegistry.getInstrumentation;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+import static android.support.test.espresso.matcher.ViewMatchers.withText;
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+
+@RunWith(AndroidJUnit4.class)
+public class PreferencesTest {
private Solo solo;
- private Context context;
private Resources res;
+ private SharedPreferences prefs;
- public PreferencesTest() {
- super(PreferenceActivity.class);
- }
+ @Rule
+ public ActivityTestRule<PreferenceActivity> mActivityRule = new ActivityTestRule<>(PreferenceActivity.class);
- @Override
- public void setUp() throws Exception {
- super.setUp();
- solo = new Solo(getInstrumentation(), getActivity());
+ @Before
+ public void setUp() {
+ solo = new Solo(getInstrumentation(), mActivityRule.getActivity());
Timeout.setSmallTimeout(500);
Timeout.setLargeTimeout(1000);
- context = getInstrumentation().getTargetContext();
- res = getActivity().getResources();
- UserPreferences.init(context);
+ res = mActivityRule.getActivity().getResources();
+ UserPreferences.init(mActivityRule.getActivity());
+
+ prefs = PreferenceManager.getDefaultSharedPreferences(mActivityRule.getActivity());
+ prefs.edit().clear();
+ prefs.edit().putBoolean(UserPreferences.PREF_ENABLE_AUTODL, true).commit();
}
- @Override
- public void tearDown() throws Exception {
+ @After
+ public void tearDown() {
solo.finishOpenedActivities();
- super.tearDown();
+ prefs.edit().clear();
}
+ @Test
public void testSwitchTheme() {
final int theme = UserPreferences.getTheme();
int otherTheme;
@@ -55,13 +78,13 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
} else {
otherTheme = R.string.pref_theme_title_light;
}
- solo.clickOnText(solo.getString(R.string.user_interface_label));
- solo.clickOnText(solo.getString(R.string.pref_set_theme_title));
- solo.waitForDialogToOpen();
- solo.clickOnText(solo.getString(otherTheme));
+ clickPreference(withText(R.string.user_interface_label));
+ clickPreference(withText(R.string.pref_set_theme_title));
+ onView(withText(otherTheme)).perform(click());
assertTrue(solo.waitForCondition(() -> UserPreferences.getTheme() != theme, Timeout.getLargeTimeout()));
}
+ @Test
public void testSwitchThemeBack() {
final int theme = UserPreferences.getTheme();
int otherTheme;
@@ -70,33 +93,23 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
} else {
otherTheme = R.string.pref_theme_title_light;
}
- solo.clickOnText(solo.getString(R.string.user_interface_label));
- solo.clickOnText(solo.getString(R.string.pref_set_theme_title));
- solo.waitForDialogToOpen(1000);
- solo.clickOnText(solo.getString(otherTheme));
+ clickPreference(withText(R.string.user_interface_label));
+ clickPreference(withText(R.string.pref_set_theme_title));
+ onView(withText(otherTheme)).perform(click());
assertTrue(solo.waitForCondition(() -> UserPreferences.getTheme() != theme, Timeout.getLargeTimeout()));
}
- public void testExpandNotification() {
- solo.clickOnText(solo.getString(R.string.user_interface_label));
- final int priority = UserPreferences.getNotifyPriority();
- solo.clickOnText(solo.getString(R.string.pref_expandNotify_title));
- assertTrue(solo.waitForCondition(() -> priority != UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout()));
- solo.clickOnText(solo.getString(R.string.pref_expandNotify_title));
- assertTrue(solo.waitForCondition(() -> priority == UserPreferences.getNotifyPriority(), Timeout.getLargeTimeout()));
- }
-
+ @Test
public void testEnablePersistentPlaybackControls() {
- solo.clickOnText(solo.getString(R.string.user_interface_label));
final boolean persistNotify = UserPreferences.isPersistNotify();
- solo.scrollDown();
- solo.scrollDown();
- solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
+ clickPreference(withText(R.string.user_interface_label));
+ clickPreference(withText(R.string.pref_persistNotify_title));
assertTrue(solo.waitForCondition(() -> persistNotify != UserPreferences.isPersistNotify(), Timeout.getLargeTimeout()));
- solo.clickOnText(solo.getString(R.string.pref_persistNotify_title));
+ clickPreference(withText(R.string.pref_persistNotify_title));
assertTrue(solo.waitForCondition(() -> persistNotify == UserPreferences.isPersistNotify(), Timeout.getLargeTimeout()));
}
+ @Test
public void testSetLockscreenButtons() {
solo.clickOnText(solo.getString(R.string.user_interface_label));
solo.scrollDown();
@@ -123,6 +136,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> !UserPreferences.showSkipOnCompactNotification(), Timeout.getLargeTimeout()));
}
+ @Test
public void testEnqueueAtFront() {
solo.clickOnText(solo.getString(R.string.playback_pref));
final boolean enqueueAtFront = UserPreferences.enqueueAtFront();
@@ -134,6 +148,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> enqueueAtFront == UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout()));
}
+ @Test
public void testHeadPhonesDisconnect() {
solo.clickOnText(solo.getString(R.string.playback_pref));
final boolean pauseOnHeadsetDisconnect = UserPreferences.isPauseOnHeadsetDisconnect();
@@ -143,6 +158,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect == UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout()));
}
+ @Test
public void testHeadPhonesReconnect() {
solo.clickOnText(solo.getString(R.string.playback_pref));
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
@@ -156,6 +172,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> unpauseOnHeadsetReconnect == UserPreferences.isUnpauseOnHeadsetReconnect(), Timeout.getLargeTimeout()));
}
+ @Test
public void testBluetoothReconnect() {
solo.clickOnText(solo.getString(R.string.playback_pref));
if(UserPreferences.isPauseOnHeadsetDisconnect() == false) {
@@ -169,6 +186,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> unpauseOnBluetoothReconnect == UserPreferences.isUnpauseOnBluetoothReconnect(), Timeout.getLargeTimeout()));
}
+ @Test
public void testContinuousPlayback() {
solo.clickOnText(solo.getString(R.string.playback_pref));
final boolean continuousPlayback = UserPreferences.isFollowQueue();
@@ -180,6 +198,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> continuousPlayback == UserPreferences.isFollowQueue(), Timeout.getLargeTimeout()));
}
+ @Test
public void testAutoDelete() {
solo.clickOnText(solo.getString(R.string.storage_pref));
final boolean autoDelete = UserPreferences.isAutoDelete();
@@ -189,17 +208,15 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> autoDelete == UserPreferences.isAutoDelete(), Timeout.getLargeTimeout()));
}
+ @Test
public void testPlaybackSpeeds() {
- solo.clickOnText(solo.getString(R.string.playback_pref));
- solo.scrollDown();
- solo.scrollDown();
- solo.clickOnText(solo.getString(R.string.pref_playback_speed_title));
- solo.waitForDialogToOpen(1000);
+ clickPreference(withText(R.string.playback_pref));
+ clickPreference(withText(R.string.pref_playback_speed_title));
assertTrue(solo.searchText(res.getStringArray(R.array.playback_speed_values)[0]));
- solo.clickOnText(solo.getString(R.string.cancel_label));
- solo.waitForDialogToClose(1000);
+ onView(withText(R.string.cancel_label)).perform(click());
}
+ @Test
public void testPauseForInterruptions() {
solo.clickOnText(solo.getString(R.string.playback_pref));
final boolean pauseForFocusLoss = UserPreferences.shouldPauseForFocusLoss();
@@ -209,6 +226,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> pauseForFocusLoss == UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout()));
}
+ @Test
public void testDisableUpdateInterval() {
solo.clickOnText(solo.getString(R.string.network_pref));
solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_sum));
@@ -217,31 +235,31 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() == 0, 1000));
}
+ @Test
public void testSetUpdateInterval() {
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_title));
- solo.waitForDialogToOpen();
- solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Interval));
- solo.waitForDialogToOpen();
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_autoUpdateIntervallOrTime_title));
+ onView(withText(R.string.pref_autoUpdateIntervallOrTime_Interval)).perform(click());
String search = "12 " + solo.getString(R.string.pref_update_interval_hours_plural);
- solo.clickOnText(search);
- solo.waitForDialogToClose();
+ onView(withText(search)).perform(click());
assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() ==
TimeUnit.HOURS.toMillis(12), Timeout.getLargeTimeout()));
}
+ @Test
public void testMobileUpdates() {
- solo.clickOnText(solo.getString(R.string.network_pref));
+ clickPreference(withText(R.string.network_pref));
final boolean mobileUpdates = UserPreferences.isAllowMobileUpdate();
- solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title));
+ clickPreference(withText(R.string.pref_mobileUpdate_title));
assertTrue(solo.waitForCondition(() -> mobileUpdates != UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout()));
- solo.clickOnText(solo.getString(R.string.pref_mobileUpdate_title));
+ clickPreference(withText(R.string.pref_mobileUpdate_title));
assertTrue(solo.waitForCondition(() -> mobileUpdates == UserPreferences.isAllowMobileUpdate(), Timeout.getLargeTimeout()));
}
+ @Test
public void testSetSequentialDownload() {
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_parallel_downloads_title));
solo.waitForDialogToOpen();
solo.clearEditText(0);
solo.enterText(0, "1");
@@ -249,9 +267,10 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 1, Timeout.getLargeTimeout()));
}
+ @Test
public void testSetParallelDownloads() {
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_parallel_downloads_title));
solo.waitForDialogToOpen();
solo.clearEditText(0);
solo.enterText(0, "10");
@@ -259,50 +278,50 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 10, Timeout.getLargeTimeout()));
}
+ @Test
public void testSetParallelDownloadsInvalidInput() {
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_parallel_downloads_title));
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_parallel_downloads_title));
solo.waitForDialogToOpen();
solo.clearEditText(0);
solo.enterText(0, "0");
- assertEquals("1", solo.getEditText(0).getText().toString());
+ assertEquals("", solo.getEditText(0).getText().toString());
solo.clearEditText(0);
solo.enterText(0, "100");
- assertEquals("50", solo.getEditText(0).getText().toString());
+ assertEquals("", solo.getEditText(0).getText().toString());
}
+ @Test
public void testSetEpisodeCache() {
String[] entries = res.getStringArray(R.array.episode_cache_size_entries);
String[] values = res.getStringArray(R.array.episode_cache_size_values);
String entry = entries[entries.length/2];
final int value = Integer.valueOf(values[values.length/2]);
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
- solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
- solo.clickOnText(solo.getString(R.string.pref_episode_cache_title));
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_automatic_download_title));
+ clickPreference(withText(R.string.pref_episode_cache_title));
solo.waitForDialogToOpen();
solo.clickOnText(entry);
assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == value, Timeout.getLargeTimeout()));
}
+ @Test
public void testSetEpisodeCacheMin() {
String[] entries = res.getStringArray(R.array.episode_cache_size_entries);
String[] values = res.getStringArray(R.array.episode_cache_size_values);
String minEntry = entries[0];
final int minValue = Integer.valueOf(values[0]);
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
- solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
- if(!UserPreferences.isEnableAutodownload()) {
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
- }
- solo.clickOnText(solo.getString(R.string.pref_episode_cache_title));
+
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_automatic_download_title));
+ clickPreference(withText(R.string.pref_episode_cache_title));
solo.waitForDialogToOpen(1000);
solo.scrollUp();
solo.clickOnText(minEntry);
assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == minValue, Timeout.getLargeTimeout()));
}
+ @Test
public void testSetEpisodeCacheMax() {
String[] entries = res.getStringArray(R.array.episode_cache_size_entries);
String[] values = res.getStringArray(R.array.episode_cache_size_values);
@@ -311,24 +330,22 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
solo.clickOnText(solo.getString(R.string.network_pref));
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
- if(!UserPreferences.isEnableAutodownload()) {
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
- }
solo.clickOnText(solo.getString(R.string.pref_episode_cache_title));
solo.waitForDialogToOpen();
solo.clickOnText(maxEntry);
assertTrue(solo.waitForCondition(() -> UserPreferences.getEpisodeCacheSize() == maxValue, Timeout.getLargeTimeout()));
}
+ @Test
public void testAutomaticDownload() {
final boolean automaticDownload = UserPreferences.isEnableAutodownload();
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
- solo.waitForText(solo.getString(R.string.pref_automatic_download_title));
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_automatic_download_title));
+ clickPreference(withText(R.string.pref_automatic_download_title));
+
assertTrue(solo.waitForCondition(() -> automaticDownload != UserPreferences.isEnableAutodownload(), Timeout.getLargeTimeout()));
if(UserPreferences.isEnableAutodownload() == false) {
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
+ clickPreference(withText(R.string.pref_automatic_download_title));
}
assertTrue(solo.waitForCondition(() -> UserPreferences.isEnableAutodownload() == true, Timeout.getLargeTimeout()));
final boolean enableAutodownloadOnBattery = UserPreferences.isEnableAutodownloadOnBattery();
@@ -343,6 +360,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
assertTrue(solo.waitForCondition(() -> enableWifiFilter == UserPreferences.isEnableAutodownloadWifiFilter(), Timeout.getLargeTimeout()));
}
+ @Test
public void testEpisodeCleanupQueueOnly() {
solo.clickOnText(solo.getString(R.string.network_pref));
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
@@ -356,6 +374,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
Timeout.getLargeTimeout()));
}
+ @Test
public void testEpisodeCleanupNeverAlg() {
solo.clickOnText(solo.getString(R.string.network_pref));
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
@@ -369,6 +388,7 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
Timeout.getLargeTimeout()));
}
+ @Test
public void testEpisodeCleanupClassic() {
solo.clickOnText(solo.getString(R.string.network_pref));
solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
@@ -379,39 +399,39 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm();
if (alg instanceof APCleanupAlgorithm) {
APCleanupAlgorithm cleanupAlg = (APCleanupAlgorithm)alg;
- return cleanupAlg.getNumberOfDaysAfterPlayback() == 0;
+ return cleanupAlg.getNumberOfHoursAfterPlayback() == 0;
}
return false;
},
Timeout.getLargeTimeout()));
}
+ @Test
public void testEpisodeCleanupNumDays() {
- solo.clickOnText(solo.getString(R.string.network_pref));
- solo.clickOnText(solo.getString(R.string.pref_automatic_download_title));
- solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title));
- solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening));
- solo.clickOnText("5");
+ clickPreference(withText(R.string.network_pref));
+ clickPreference(withText(R.string.pref_automatic_download_title));
+ clickPreference(withText(R.string.pref_episode_cleanup_title));
+ solo.waitForDialogToOpen();
+ String search = res.getQuantityString(R.plurals.episode_cleanup_days_after_listening, 5, 5);
+ onView(withText(search)).perform(click());
assertTrue(solo.waitForCondition(() -> {
EpisodeCleanupAlgorithm alg = UserPreferences.getEpisodeCleanupAlgorithm();
if (alg instanceof APCleanupAlgorithm) {
APCleanupAlgorithm cleanupAlg = (APCleanupAlgorithm)alg;
- return cleanupAlg.getNumberOfDaysAfterPlayback() == 5;
+ return cleanupAlg.getNumberOfHoursAfterPlayback() == 120; // 5 days
}
return false;
},
Timeout.getLargeTimeout()));
}
-
+ @Test
public void testRewindChange() {
int seconds = UserPreferences.getRewindSecs();
int deltas[] = res.getIntArray(R.array.seek_delta_values);
- solo.clickOnText(solo.getString(R.string.playback_pref));
- solo.scrollDown();
- solo.scrollDown();
- solo.clickOnText(solo.getString(R.string.pref_rewind));
+ clickPreference(withText(R.string.playback_pref));
+ clickPreference(withText(R.string.pref_rewind));
solo.waitForDialogToOpen();
int currentIndex = Arrays.binarySearch(deltas, seconds);
@@ -419,24 +439,22 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
// Find next value (wrapping around to next)
int newIndex = (currentIndex + 1) % deltas.length;
-
- solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds");
- solo.clickOnButton("Confirm");
+ onView(withText(String.valueOf(deltas[newIndex]) + " seconds")).perform(click());
+ onView(withText("Confirm")).perform(click());
solo.waitForDialogToClose();
assertTrue(solo.waitForCondition(() -> UserPreferences.getRewindSecs() == deltas[newIndex],
Timeout.getLargeTimeout()));
}
+ @Test
public void testFastForwardChange() {
- solo.clickOnText(solo.getString(R.string.playback_pref));
- solo.scrollDown();
- solo.scrollDown();
+ clickPreference(withText(R.string.playback_pref));
for (int i = 2; i > 0; i--) { // repeat twice to catch any error where fastforward is tracking rewind
int seconds = UserPreferences.getFastForwardSecs();
int deltas[] = res.getIntArray(R.array.seek_delta_values);
- solo.clickOnText(solo.getString(R.string.pref_fast_forward));
+ clickPreference(withText(R.string.pref_fast_forward));
solo.waitForDialogToOpen();
int currentIndex = Arrays.binarySearch(deltas, seconds);
@@ -445,12 +463,66 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference
// Find next value (wrapping around to next)
int newIndex = (currentIndex + 1) % deltas.length;
- solo.clickOnText(String.valueOf(deltas[newIndex]) + " seconds");
- solo.clickOnButton("Confirm");
+ onView(withText(String.valueOf(deltas[newIndex]) + " seconds")).perform(click());
+ onView(withText("Confirm")).perform(click());
solo.waitForDialogToClose();
assertTrue(solo.waitForCondition(() -> UserPreferences.getFastForwardSecs() == deltas[newIndex],
Timeout.getLargeTimeout()));
}
}
+
+ @Test
+ public void testBackButtonBehaviorGoToPageSelector() {
+ clickPreference(withText(R.string.user_interface_label));
+ clickPreference(withText(R.string.pref_back_button_behavior_title));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.back_button_go_to_page));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.queue_label));
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE,
+ Timeout.getLargeTimeout()));
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(QueueFragment.TAG),
+ Timeout.getLargeTimeout()));
+ clickPreference(withText(R.string.pref_back_button_behavior_title));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.back_button_go_to_page));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.episodes_label));
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE,
+ Timeout.getLargeTimeout()));
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(EpisodesFragment.TAG),
+ Timeout.getLargeTimeout()));
+ clickPreference(withText(R.string.pref_back_button_behavior_title));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.back_button_go_to_page));
+ solo.waitForDialogToOpen();
+ solo.clickOnText(solo.getString(R.string.subscriptions_label));
+ solo.clickOnText(solo.getString(R.string.confirm_label));
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonBehavior() == UserPreferences.BackButtonBehavior.GO_TO_PAGE,
+ Timeout.getLargeTimeout()));
+ assertTrue(solo.waitForCondition(() -> UserPreferences.getBackButtonGoToPage().equals(SubscriptionFragment.TAG),
+ Timeout.getLargeTimeout()));
+ }
+
+ @Test
+ public void testDeleteRemovesFromQueue() {
+ clickPreference(withText(R.string.storage_pref));
+ if (!UserPreferences.shouldDeleteRemoveFromQueue()) {
+ clickPreference(withText(R.string.pref_delete_removes_from_queue_title));
+ assertTrue(solo.waitForCondition(UserPreferences::shouldDeleteRemoveFromQueue, Timeout.getLargeTimeout()));
+ }
+ final boolean deleteRemovesFromQueue = UserPreferences.shouldDeleteRemoveFromQueue();
+ solo.clickOnText(solo.getString(R.string.pref_delete_removes_from_queue_title));
+ assertTrue(solo.waitForCondition(() -> deleteRemovesFromQueue != UserPreferences.shouldDeleteRemoveFromQueue(), Timeout.getLargeTimeout()));
+ solo.clickOnText(solo.getString(R.string.pref_delete_removes_from_queue_title));
+ assertTrue(solo.waitForCondition(() -> deleteRemovesFromQueue == UserPreferences.shouldDeleteRemoveFromQueue(), Timeout.getLargeTimeout()));
+ }
+
+ private void clickPreference(Matcher<View> matcher) {
+ onView(withId(R.id.list))
+ .perform(RecyclerViewActions.actionOnItem(hasDescendant(matcher), click()));
+ }
}
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 3af22af9d..ff5374268 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
@@ -22,7 +22,6 @@ import de.danoeh.antennapod.activity.MainActivity;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.Feed;
-import de.danoeh.antennapod.core.feed.FeedImage;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
@@ -136,12 +135,9 @@ class UITestUtils {
public void addHostedFeedData() throws IOException {
if (feedDataHosted) throw new IllegalStateException("addHostedFeedData was called twice on the same instance");
for (int i = 0; i < NUM_FEEDS; i++) {
- File bitmapFile = newBitmapFile("image" + i);
- FeedImage image = new FeedImage(0, "image " + i, null, hostFile(bitmapFile), false);
Feed feed = new Feed(0, null, "Title " + i, "http://example.com/" + i, "Description of feed " + i,
- "http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, image, null,
+ "http://example.com/pay/feed" + i, "author " + i, "en", Feed.TYPE_RSS2, "feed" + i, null, null,
"http://example.com/feed/src/" + i, false);
- image.setOwner(feed);
// create items
List<FeedItem> items = new ArrayList<>();
@@ -187,12 +183,6 @@ class UITestUtils {
List<FeedItem> queue = new ArrayList<>();
for (Feed feed : hostedFeeds) {
feed.setDownloaded(true);
- if (feed.getImage() != null) {
- FeedImage image = feed.getImage();
- int fileId = Integer.parseInt(StringUtils.substringAfter(image.getDownload_url(), "files/"));
- image.setFile_url(server.accessFile(fileId).getAbsolutePath());
- image.setDownloaded(true);
- }
if (downloadEpisodes) {
for (FeedItem item : feed.getItems()) {
if (item.hasMedia()) {
diff --git a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java
index 53fd7d7fd..45ba472ff 100644
--- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtilsTest.java
@@ -38,9 +38,6 @@ public class UITestUtilsTest extends InstrumentationTestCase {
for (Feed feed : feeds) {
testUrlReachable(feed.getDownload_url());
- if (feed.getImage() != null) {
- testUrlReachable(feed.getImage().getDownload_url());
- }
for (FeedItem item : feed.getItems()) {
if (item.hasMedia()) {
testUrlReachable(item.getMedia().getDownload_url());
@@ -66,9 +63,6 @@ public class UITestUtilsTest extends InstrumentationTestCase {
for (Feed feed : uiTestUtils.hostedFeeds) {
assertTrue(feed.getId() != 0);
- if (feed.getImage() != null) {
- assertTrue(feed.getImage().getId() != 0);
- }
for (FeedItem item : feed.getItems()) {
assertTrue(item.getId() != 0);
if (item.hasMedia()) {
diff --git a/app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java b/app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java
deleted file mode 100644
index 47fca41ba..000000000
--- a/app/src/androidTest/java/de/test/antennapod/util/ConverterTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package de.test.antennapod.util;
-
-import android.test.AndroidTestCase;
-
-import de.danoeh.antennapod.core.util.Converter;
-
-/**
- * Test class for converter
- */
-public class ConverterTest extends AndroidTestCase {
-
- public void testGetDurationStringLong() throws Exception {
- String expected = "13:05:10";
- int input = 47110000;
- assertEquals(expected, Converter.getDurationStringLong(input));
- }
-
- public void testGetDurationStringShort() throws Exception {
- String expected = "13:05";
- int input = 47110000;
- assertEquals(expected, Converter.getDurationStringShort(input));
- }
-
- public void testDurationStringLongToMs() throws Exception {
- String input = "01:20:30";
- long expected = 4830000;
- assertEquals(expected, Converter.durationStringLongToMs(input));
- }
-
- public void testDurationStringShortToMs() throws Exception {
- String input = "8:30";
- long expected = 30600000;
- assertEquals(expected, Converter.durationStringShortToMs(input));
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java b/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java
deleted file mode 100644
index d564d0492..000000000
--- a/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package de.test.antennapod.util;
-
-import junit.framework.TestCase;
-
-import de.danoeh.antennapod.core.util.RewindAfterPauseUtils;
-
-/**
- * Tests for {@link RewindAfterPauseUtils}.
- */
-public class RewindAfterPauseUtilTest extends TestCase {
-
- public void testCalculatePositionWithRewindNoRewind() {
- final int ORIGINAL_POSITION = 10000;
- long lastPlayed = System.currentTimeMillis();
- int position = RewindAfterPauseUtils.calculatePositionWithRewind(ORIGINAL_POSITION, lastPlayed);
-
- assertEquals(ORIGINAL_POSITION, position);
- }
-
- public void testCalculatePositionWithRewindSmallRewind() {
- final int ORIGINAL_POSITION = 10000;
- long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_SHORT_REWIND - 1000;
- int position = RewindAfterPauseUtils.calculatePositionWithRewind(ORIGINAL_POSITION, lastPlayed);
-
- assertEquals(ORIGINAL_POSITION - RewindAfterPauseUtils.SHORT_REWIND, position);
- }
-
- public void testCalculatePositionWithRewindMediumRewind() {
- final int ORIGINAL_POSITION = 10000;
- long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_MEDIUM_REWIND - 1000;
- int position = RewindAfterPauseUtils.calculatePositionWithRewind(ORIGINAL_POSITION, lastPlayed);
-
- assertEquals(ORIGINAL_POSITION - RewindAfterPauseUtils.MEDIUM_REWIND, position);
- }
-
- public void testCalculatePositionWithRewindLongRewind() {
- final int ORIGINAL_POSITION = 30000;
- long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_LONG_REWIND - 1000;
- int position = RewindAfterPauseUtils.calculatePositionWithRewind(ORIGINAL_POSITION, lastPlayed);
-
- assertEquals(ORIGINAL_POSITION - RewindAfterPauseUtils.LONG_REWIND, position);
- }
-
- public void testCalculatePositionWithRewindNegativeNumber() {
- final int ORIGINAL_POSITION = 100;
- long lastPlayed = System.currentTimeMillis() - RewindAfterPauseUtils.ELAPSED_TIME_FOR_LONG_REWIND - 1000;
- int position = RewindAfterPauseUtils.calculatePositionWithRewind(ORIGINAL_POSITION, lastPlayed);
-
- assertEquals(0, position);
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java b/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java
deleted file mode 100644
index 2cca6b4dc..000000000
--- a/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package de.test.antennapod.util;
-
-import android.test.AndroidTestCase;
-
-import de.danoeh.antennapod.core.util.URIUtil;
-
-/**
- * Test class for URIUtil
- */
-public class URIUtilTest extends AndroidTestCase {
-
- public void testGetURIFromRequestUrlShouldNotEncode() {
- final String testUrl = "http://example.com/this%20is%20encoded";
- assertEquals(testUrl, URIUtil.getURIFromRequestUrl(testUrl).toString());
- }
-
- public void testGetURIFromRequestUrlShouldEncode() {
- final String testUrl = "http://example.com/this is not encoded";
- final String expected = "http://example.com/this%20is%20not%20encoded";
- assertEquals(expected, URIUtil.getURIFromRequestUrl(testUrl).toString());
- }
-}
diff --git a/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java b/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java
index 7e535e12c..4bef14cd9 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/playback/TimelineTest.java
@@ -30,12 +30,12 @@ public class TimelineTest extends InstrumentationTestCase {
context = getInstrumentation().getTargetContext();
}
- private Playable newTestPlayable(List<Chapter> chapters, String shownotes) {
+ private Playable newTestPlayable(List<Chapter> chapters, String shownotes, int duration) {
FeedItem item = new FeedItem(0, "Item", "item-id", "http://example.com/item", new Date(), FeedItem.PLAYED, null);
item.setChapters(chapters);
item.setContentEncoded(shownotes);
FeedMedia media = new FeedMedia(item, "http://example.com/episode", 100, "audio/mp3");
- media.setDuration(Integer.MAX_VALUE);
+ media.setDuration(duration);
item.setMedia(media);
return media;
}
@@ -44,7 +44,17 @@ public class TimelineTest extends InstrumentationTestCase {
final String timeStr = "10:11:12";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11 + 12 * 1000;
- Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>");
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ public void testProcessShownotesAddTimecodeHHMMSSMoreThen24HoursNoChapters() throws Exception {
+ final String timeStr = "25:00:00";
+ final long time = 25 * 60 * 60 * 1000;
+
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes(true);
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
@@ -54,17 +64,67 @@ public class TimelineTest extends InstrumentationTestCase {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
- Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>");
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ public void testProcessShownotesAddTimecodeMMSSNoChapters() throws Exception {
+ final String timeStr = "10:11";
+ final long time = 10 * 60 * 1000 + 11 * 1000;
+
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", 11 * 60 * 1000);
Timeline t = new Timeline(context, p);
String res = t.processShownotes(true);
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
+ public void testProcessShownotesAddTimecodeHMMSSNoChapters() throws Exception {
+ final String timeStr = "2:11:12";
+ final long time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
+
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", Integer.MAX_VALUE);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ public void testProcessShownotesAddTimecodeMSSNoChapters() throws Exception {
+ final String timeStr = "1:12";
+ final long time = 60 * 1000 + 12 * 1000;
+
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStr + " here.</p>", 2 * 60 * 1000);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
+ }
+
+ public void testProcessShownotesAddTimecodeMultipleFormatsNoChapters() throws Exception {
+ final String[] timeStrings = new String[]{ "10:12", "1:10:12" };
+
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 2 * 60 * 60 * 1000);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000 }, timeStrings);
+ }
+
+ public void testProcessShownotesAddTimecodeMultipleShortFormatNoChapters() throws Exception {
+
+ // One of these timecodes fits as HH:MM and one does not so both should be parsed as MM:SS.
+ final String[] timeStrings = new String[]{ "10:12", "2:12" };
+
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode " + timeStrings[0] + " here. Hey look another one " + timeStrings[1] + " here!</p>", 3 * 60 * 60 * 1000);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[]{ 10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000 }, timeStrings);
+ }
+
public void testProcessShownotesAddTimecodeParentheses() throws Exception {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
- Playable p = newTestPlayable(null, "<p> Some test text with a timecode (" + timeStr + ") here.</p>");
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode (" + timeStr + ") here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes(true);
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
@@ -74,7 +134,7 @@ public class TimelineTest extends InstrumentationTestCase {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
- Playable p = newTestPlayable(null, "<p> Some test text with a timecode [" + timeStr + "] here.</p>");
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode [" + timeStr + "] here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes(true);
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
@@ -84,12 +144,27 @@ public class TimelineTest extends InstrumentationTestCase {
final String timeStr = "10:11";
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
- Playable p = newTestPlayable(null, "<p> Some test text with a timecode <" + timeStr + "> here.</p>");
+ Playable p = newTestPlayable(null, "<p> Some test text with a timecode <" + timeStr + "> here.</p>", Integer.MAX_VALUE);
Timeline t = new Timeline(context, p);
String res = t.processShownotes(true);
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
+ public void testProcessShownotesAndInvalidTimecode() throws Exception {
+ final String[] timeStrs = new String[] {"2:1", "0:0", "000", "00", "00:000"};
+
+ StringBuilder shownotes = new StringBuilder("<p> Some test text with timecodes ");
+ for (String timeStr : timeStrs) {
+ shownotes.append(timeStr).append(" ");
+ }
+ shownotes.append("here.</p>");
+
+ Playable p = newTestPlayable(null, shownotes.toString(), Integer.MAX_VALUE);
+ Timeline t = new Timeline(context, p);
+ String res = t.processShownotes(true);
+ checkLinkCorrect(res, new long[0], new String[0]);
+ }
+
private void checkLinkCorrect(String res, long[] timecodes, String[] timecodeStr) {
assertNotNull(res);
Document d = Jsoup.parse(res);
diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java
index afe15f1b2..8d2408b45 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/AtomGenerator.java
@@ -56,6 +56,11 @@ public class AtomGenerator implements FeedGenerator{
xml.text(feed.getDescription());
xml.endTag(null, "subtitle");
}
+ if (feed.getImageUrl() != null) {
+ xml.startTag(null, "logo");
+ xml.text(feed.getImageUrl());
+ xml.endTag(null, "logo");
+ }
if (feed.getPaymentLink() != null) {
GeneratorUtil.addPaymentLink(xml, feed.getPaymentLink(), false);
diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java
index 7f6f0fb0f..89542d222 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/GeneratorUtil.java
@@ -8,6 +8,7 @@ import java.io.IOException;
* Utility methods for FeedGenerator
*/
class GeneratorUtil {
+ private GeneratorUtil(){}
public static void addPaymentLink(XmlSerializer xml, String paymentLink, boolean withNamespace) throws IOException {
String ns = (withNamespace) ? "http://www.w3.org/2005/Atom" : null;
diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java
index f2d53799d..5f8b4d18c 100644
--- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java
+++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/RSS2Generator.java
@@ -54,6 +54,13 @@ public class RSS2Generator implements FeedGenerator{
xml.text(feed.getLanguage());
xml.endTag(null, "language");
}
+ if (feed.getImageUrl() != null) {
+ xml.startTag(null, "image");
+ xml.startTag(null, "url");
+ xml.text(feed.getImageUrl());
+ xml.endTag(null, "url");
+ xml.endTag(null, "image");
+ }
if (feed.getPaymentLink() != null) {
GeneratorUtil.addPaymentLink(xml, feed.getPaymentLink(), true);