diff options
Diffstat (limited to 'app/src/androidTest/java/de/test')
29 files changed, 604 insertions, 553 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 new file mode 100644 index 000000000..ced0d7a28 --- /dev/null +++ b/app/src/androidTest/java/de/test/antennapod/feed/FeedItemTest.java @@ -0,0 +1,38 @@ +package de.test.antennapod.feed; + +import android.test.AndroidTestCase; + +import de.danoeh.antennapod.core.feed.FeedItem; + +public class FeedItemTest extends AndroidTestCase { + private static final String TEXT_LONG = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; + private static final String TEXT_SHORT = "Lorem ipsum"; + + /** + * If one of `description` or `content:encoded` is null, use the other one. + */ + public void testShownotesNullValues() throws Exception { + testShownotes(null, TEXT_LONG); + testShownotes(TEXT_LONG, null); + } + + /** + * If `description` is reasonably longer than `content:encoded`, use `description`. + */ + public void testShownotesLength() throws Exception { + testShownotes(TEXT_SHORT, TEXT_LONG); + testShownotes(TEXT_LONG, TEXT_SHORT); + } + + /** + * Checks if the shownotes equal TEXT_LONG, using the given `description` and `content:encoded` + * @param description Description of the feed item + * @param contentEncoded `content:encoded` of the feed item + */ + private void testShownotes(String description, String contentEncoded) throws Exception { + FeedItem item = new FeedItem(); + item.setDescription(description); + item.setContentEncoded(contentEncoded); + assertEquals(TEXT_LONG, item.loadShownotes().call()); + } +} 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 14a3b27b0..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,113 +1,127 @@ 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 java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +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<String>(); + ArrayList<String> l = new ArrayList<>(); l.add("http://bitsundso.de/feed"); service.uploadSubscriptions(USER, "radio", l); } + @Test public void testUploadSubscription2() throws GpodnetServiceException { authenticate(); - ArrayList<String> l = new ArrayList<String>(); + ArrayList<String> l = new ArrayList<>(); l.add("http://bitsundso.de/feed"); l.add("http://gamesundso.de/feed"); 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/"}; List<String> subscriptions = Arrays.asList(URLS[0], URLS[1]); - List<String> removed = Arrays.asList(URLS[0]); + List<String> removed = singletonList(URLS[0]); List<String> added = Arrays.asList(URLS[2], URLS[3]); service.uploadSubscriptions(USER, "radio", subscriptions); 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 ee454ce8a..6908e2ec7 100644 --- a/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/handler/FeedHandlerTest.java @@ -17,7 +17,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; @@ -32,8 +31,8 @@ import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator; public class FeedHandlerTest extends InstrumentationTestCase { private static final String FEEDS_DIR = "testfeeds"; - File file = null; - OutputStream outputStream = null; + private File file = null; + private OutputStream outputStream = null; protected void setUp() throws Exception { super.setUp(); @@ -82,15 +81,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 +110,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,14 +142,10 @@ 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<FeedItem>()); + feed.setItems(new ArrayList<>()); for (int i = 0; i < numItems; i++) { FeedItem item = new FeedItem(0, "item-" + i, "http://example.com/item-" + i, 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 9ac92c2f9..2f53ea8a6 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 @@ -23,8 +23,8 @@ import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedPreferences; import de.danoeh.antennapod.core.feed.MediaType; -import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer; import de.danoeh.antennapod.core.service.playback.LocalPSMP; +import de.danoeh.antennapod.core.service.playback.PlaybackServiceMediaPlayer; import de.danoeh.antennapod.core.service.playback.PlayerStatus; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.util.playback.Playable; diff --git a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java index 6ab6e5c61..8be57a074 100644 --- a/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/service/playback/PlaybackServiceTaskManagerTest.java @@ -9,10 +9,10 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +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.FeedItem; -import de.danoeh.antennapod.core.event.QueueEvent; import de.danoeh.antennapod.core.service.playback.PlaybackServiceTaskManager; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.util.playback.Playable; diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java index 5e5eb1e8b..5cd4e9906 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBCleanupTests.java @@ -27,12 +27,12 @@ import static de.test.antennapod.storage.DBTestUtils.saveFeedlist; public class DBCleanupTests extends InstrumentationTestCase { private static final String TAG = "DBTasksTest"; - protected static final int EPISODE_CACHE_SIZE = 5; + static final int EPISODE_CACHE_SIZE = 5; private final int cleanupAlgorithm; - protected Context context; + Context context; - protected File destFolder; + private File destFolder; public DBCleanupTests() { this.cleanupAlgorithm = UserPreferences.EPISODE_CLEANUP_DEFAULT; @@ -104,9 +104,9 @@ public class DBCleanupTests extends InstrumentationTestCase { } } - protected void populateItems(final int numItems, Feed feed, List<FeedItem> items, - List<File> files, int itemState, boolean addToQueue, - boolean addToFavorites) throws IOException { + void populateItems(final int numItems, Feed feed, List<FeedItem> items, + List<File> files, int itemState, boolean addToQueue, + boolean addToFavorites) throws IOException { for (int i = 0; i < numItems; i++) { Date itemDate = new Date(numItems - i); Date playbackCompletionDate = null; @@ -145,9 +145,9 @@ public class DBCleanupTests extends InstrumentationTestCase { final int NUM_ITEMS = EPISODE_CACHE_SIZE * 2; Feed feed = new Feed("url", null, "title"); - List<FeedItem> items = new ArrayList<FeedItem>(); + List<FeedItem> items = new ArrayList<>(); feed.setItems(items); - List<File> files = new ArrayList<File>(); + List<File> files = new ArrayList<>(); populateItems(NUM_ITEMS, feed, items, files, FeedItem.UNPLAYED, false, false); DBTasks.performAutoCleanup(context); diff --git a/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java b/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java index 3bd508eaf..d602d150b 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBQueueCleanupAlgorithmTest.java @@ -5,7 +5,6 @@ import android.test.FlakyTest; import java.io.File; import java.io.IOException; import java.util.ArrayList; -import java.util.Date; import java.util.List; import de.danoeh.antennapod.core.feed.Feed; 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 785d32e93..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; @@ -18,6 +17,8 @@ import de.danoeh.antennapod.core.storage.DBReader; import de.danoeh.antennapod.core.storage.DBTasks; import de.danoeh.antennapod.core.storage.PodDBAdapter; +import static java.util.Collections.singletonList; + /** * Test class for DBTasks */ @@ -100,7 +101,7 @@ public class DBTasksTest extends InstrumentationTestCase { assertTrue(feed.getId() != 0); final long feedID = feed.getId(); feed.setId(0); - List<Long> itemIDs = new ArrayList<Long>(); + List<Long> itemIDs = new ArrayList<>(); for (FeedItem item : feed.getItems()) { assertTrue(item.getId() != 0); itemIDs.add(item.getId()); @@ -125,7 +126,7 @@ public class DBTasksTest extends InstrumentationTestCase { public void testUpdateFeedMediaUrlResetState() { final Feed feed = new Feed("url", null, "title"); FeedItem item = new FeedItem(0, "item", "id", "link", new Date(), FeedItem.PLAYED, feed); - feed.setItems(Arrays.asList(item)); + feed.setItems(singletonList(item)); PodDBAdapter adapter = PodDBAdapter.getInstance(); adapter.open(); @@ -138,7 +139,7 @@ public class DBTasksTest extends InstrumentationTestCase { FeedMedia media = new FeedMedia(item, "url", 1024, "mime/type"); item.setMedia(media); - feed.setItems(Arrays.asList(item)); + feed.setItems(singletonList(item)); final Feed newFeed = DBTasks.updateFeed(context, feed)[0]; assertTrue(feed != newFeed); 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 d02efa521..a577e5e36 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBTestUtils.java @@ -19,8 +19,9 @@ import de.danoeh.antennapod.core.util.flattr.FlattrStatus; /** * Utility methods for DB* tests. */ -public class DBTestUtils { +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 40083e507..427cc8ddd 100644 --- a/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java +++ b/app/src/androidTest/java/de/test/antennapod/storage/DBWriterTest.java @@ -15,12 +15,9 @@ 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.storage.DBReader; import de.danoeh.antennapod.core.storage.DBWriter; import de.danoeh.antennapod.core.storage.PodDBAdapter; @@ -124,90 +121,14 @@ public class DBWriterTest extends InstrumentationTestCase { assertNull(media.getFile_url()); } - public void testDeleteFeed() throws IOException, ExecutionException, InterruptedException, 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<>()); - // 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); - - List<File> itemFiles = new ArrayList<File>(); - // 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); - - File enc = new File(destFolder, "file " + i); - assertTrue(enc.createNewFile()); - itemFiles.add(enc); - - FeedMedia media = new FeedMedia(0, item, 1, 1, 1, "mime_type", enc.getAbsolutePath(), "download_url", true, null, 0, 0); - item.setMedia(media); - - item.setChapters(new ArrayList<Chapter>()); - item.getChapters().add(new SimpleChapter(0, "item " + i, item, "example.com")); - } - - 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.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(); - } - - public void testDeleteFeedNoImage() 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<File>(); + 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); @@ -261,13 +182,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 +190,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 +208,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,24 +223,18 @@ 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); @@ -346,65 +243,6 @@ public class DBWriterTest extends InstrumentationTestCase { 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(); - } - public void testDeleteFeedWithQueueItems() throws ExecutionException, InterruptedException, TimeoutException { File destFolder = getInstrumentation().getTargetContext().getExternalFilesDir(TEST_FOLDER); assertNotNull(destFolder); @@ -412,13 +250,9 @@ 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<File>(); + 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); @@ -437,14 +271,13 @@ 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); } - List<FeedItem> queue = new ArrayList<FeedItem>(); + List<FeedItem> queue = new ArrayList<>(); queue.addAll(feed.getItems()); adapter.open(); adapter.setQueue(queue); @@ -460,9 +293,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); @@ -482,15 +312,11 @@ public class DBWriterTest extends InstrumentationTestCase { assertNotNull(destFolder); Feed feed = new Feed("url", null, "title"); - feed.setItems(new ArrayList<FeedItem>()); + 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<File>(); + 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); @@ -509,7 +335,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 +347,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); @@ -539,7 +361,7 @@ public class DBWriterTest extends InstrumentationTestCase { private FeedMedia playbackHistorySetup(Date playbackCompletionDate) { final Context context = getInstrumentation().getTargetContext(); Feed feed = new Feed("url", null, "title"); - feed.setItems(new ArrayList<FeedItem>()); + feed.setItems(new ArrayList<>()); FeedItem item = new FeedItem(0, "title", "id", "link", new Date(), FeedItem.PLAYED, feed); FeedMedia media = new FeedMedia(0, item, 10, 0, 1, "mime", null, "url", false, playbackCompletionDate, 0, 0); feed.getItems().add(item); @@ -598,7 +420,7 @@ public class DBWriterTest extends InstrumentationTestCase { for (FeedItem item : feed.getItems()) { assertTrue(item.getId() != 0); } - List<Future<?>> futures = new ArrayList<Future<?>>(); + List<Future<?>> futures = new ArrayList<>(); for (FeedItem item : feed.getItems()) { futures.add(DBWriter.addQueueItem(context, item)); } @@ -791,7 +613,7 @@ public class DBWriterTest extends InstrumentationTestCase { public void testMarkFeedRead() throws InterruptedException, ExecutionException, TimeoutException { final int NUM_ITEMS = 10; Feed feed = new Feed("url", null, "title"); - feed.setItems(new ArrayList<FeedItem>()); + 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.UNPLAYED, feed); feed.getItems().add(item); 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 bd9057b47..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,19 +2,18 @@ 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; +import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.feed.Feed; import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.storage.PodDBAdapter; @@ -22,26 +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 de.danoeh.antennapod.preferences.PreferenceController; +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,14 +104,16 @@ 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); - UserPreferences.setHiddenDrawerItems(new ArrayList<String>()); + UserPreferences.setHiddenDrawerItems(new ArrayList<>()); // queue openNavDrawer(); @@ -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(PreferenceController.getPreferenceActivity()); + onView(withText(R.string.settings_label)).perform(click()); + intended(hasComponent(PreferenceActivity.class.getName())); } + @Test public void testDrawerPreferencesHideSomeElements() { - UserPreferences.setHiddenDrawerItems(new ArrayList<String>()); + 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>()); - String[] titles = getInstrumentation().getTargetContext().getResources().getStringArray(R.array.nav_drawer_titles); + UserPreferences.setHiddenDrawerItems(new ArrayList<>()); + 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<String>()); - + 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 bfbeedd83..55ed998bb 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackSonicTest.java @@ -33,8 +33,8 @@ import de.danoeh.antennapod.core.storage.PodDBAdapter; public class PlaybackSonicTest extends ActivityInstrumentationTestCase2<MainActivity> { private static final String TAG = PlaybackTest.class.getSimpleName(); - public static final int EPISODES_DRAWER_LIST_INDEX = 1; - public static final int QUEUE_DRAWER_LIST_INDEX = 0; + private static final int EPISODES_DRAWER_LIST_INDEX = 1; + private static final int QUEUE_DRAWER_LIST_INDEX = 0; private Solo solo; private UITestUtils uiTestUtils; @@ -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/PlaybackTest.java b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackTest.java index 661c2200b..74d59abd7 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PlaybackTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PlaybackTest.java @@ -30,8 +30,8 @@ import de.danoeh.antennapod.core.storage.PodDBAdapter; public class PlaybackTest extends ActivityInstrumentationTestCase2<MainActivity> { private static final String TAG = PlaybackTest.class.getSimpleName(); - public static final int EPISODES_DRAWER_LIST_INDEX = 1; - public static final int QUEUE_DRAWER_LIST_INDEX = 0; + private static final int EPISODES_DRAWER_LIST_INDEX = 1; + private static final int QUEUE_DRAWER_LIST_INDEX = 0; private Solo solo; private UITestUtils uiTestUtils; 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 91928f01e..f217ecffa 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/PreferencesTest.java @@ -1,16 +1,14 @@ package de.test.antennapod.ui; -import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Resources; -import android.test.ActivityInstrumentationTestCase2; -import android.util.Log; - +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 java.util.Arrays; -import java.util.concurrent.TimeUnit; - import de.danoeh.antennapod.R; import de.danoeh.antennapod.activity.PreferenceActivity; import de.danoeh.antennapod.core.preferences.UserPreferences; @@ -18,36 +16,58 @@ 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; +import de.danoeh.antennapod.fragment.EpisodesFragment; +import de.danoeh.antennapod.fragment.QueueFragment; +import de.danoeh.antennapod.fragment.SubscriptionFragment; -public class PreferencesTest extends ActivityInstrumentationTestCase2<PreferenceActivity> { +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; - private static final String TAG = "PreferencesTest"; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +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; @@ -56,12 +76,13 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference } else { otherTheme = R.string.pref_theme_title_light; } - 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,37 +91,34 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference } else { otherTheme = R.string.pref_theme_title_light; } - 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() { - 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() { final boolean persistNotify = UserPreferences.isPersistNotify(); - 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(); String[] buttons = res.getStringArray(R.array.compact_notification_buttons_options); solo.clickOnText(solo.getString(R.string.pref_compact_notification_buttons_title)); solo.waitForDialogToOpen(1000); // First uncheck every checkbox - for (int i=0; i<buttons.length; i++) { - assertTrue(solo.searchText(buttons[i])); - if (solo.isTextChecked(buttons[i])) { - solo.clickOnText(buttons[i]); + for (String button : buttons) { + assertTrue(solo.searchText(button)); + if (solo.isTextChecked(button)) { + solo.clickOnText(button); } } // Now try to check all checkboxes @@ -111,20 +129,26 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(!solo.isTextChecked(buttons[2])); solo.clickOnText(solo.getString(R.string.confirm_label)); solo.waitForDialogToClose(1000); - assertTrue(solo.waitForCondition(() -> UserPreferences.showRewindOnCompactNotification(), Timeout.getLargeTimeout())); - assertTrue(solo.waitForCondition(() -> UserPreferences.showFastForwardOnCompactNotification(), Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(UserPreferences::showRewindOnCompactNotification, Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(UserPreferences::showFastForwardOnCompactNotification, Timeout.getLargeTimeout())); assertTrue(solo.waitForCondition(() -> !UserPreferences.showSkipOnCompactNotification(), Timeout.getLargeTimeout())); } + @Test public void testEnqueueAtFront() { + solo.clickOnText(solo.getString(R.string.playback_pref)); final boolean enqueueAtFront = UserPreferences.enqueueAtFront(); + solo.scrollDown(); + solo.scrollDown(); solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title)); assertTrue(solo.waitForCondition(() -> enqueueAtFront != UserPreferences.enqueueAtFront(), Timeout.getLargeTimeout())); solo.clickOnText(solo.getString(R.string.pref_queueAddToFront_title)); 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(); solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title)); assertTrue(solo.waitForCondition(() -> pauseOnHeadsetDisconnect != UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout())); @@ -132,10 +156,12 @@ 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) { solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title)); - assertTrue(solo.waitForCondition(() -> UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(UserPreferences::isPauseOnHeadsetDisconnect, Timeout.getLargeTimeout())); } final boolean unpauseOnHeadsetReconnect = UserPreferences.isUnpauseOnHeadsetReconnect(); solo.clickOnText(solo.getString(R.string.pref_unpauseOnHeadsetReconnect_title)); @@ -144,10 +170,12 @@ 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) { solo.clickOnText(solo.getString(R.string.pref_pauseOnHeadsetDisconnect_title)); - assertTrue(solo.waitForCondition(() -> UserPreferences.isPauseOnHeadsetDisconnect(), Timeout.getLargeTimeout())); + assertTrue(solo.waitForCondition(UserPreferences::isPauseOnHeadsetDisconnect, Timeout.getLargeTimeout())); } final boolean unpauseOnBluetoothReconnect = UserPreferences.isUnpauseOnBluetoothReconnect(); solo.clickOnText(solo.getString(R.string.pref_unpauseOnBluetoothReconnect_title)); @@ -156,15 +184,21 @@ 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(); + solo.scrollDown(); + solo.scrollDown(); solo.clickOnText(solo.getString(R.string.pref_followQueue_title)); assertTrue(solo.waitForCondition(() -> continuousPlayback != UserPreferences.isFollowQueue(), Timeout.getLargeTimeout())); solo.clickOnText(solo.getString(R.string.pref_followQueue_title)); 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(); solo.clickOnText(solo.getString(R.string.pref_auto_delete_title)); assertTrue(solo.waitForCondition(() -> autoDelete != UserPreferences.isAutoDelete(), Timeout.getLargeTimeout())); @@ -172,15 +206,17 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> autoDelete == UserPreferences.isAutoDelete(), Timeout.getLargeTimeout())); } + @Test public void testPlaybackSpeeds() { - 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(); solo.clickOnText(solo.getString(R.string.pref_pausePlaybackForFocusLoss_title)); assertTrue(solo.waitForCondition(() -> pauseForFocusLoss != UserPreferences.shouldPauseForFocusLoss(), Timeout.getLargeTimeout())); @@ -188,35 +224,40 @@ 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)); solo.waitForDialogToOpen(); solo.clickOnText(solo.getString(R.string.pref_autoUpdateIntervallOrTime_Disable)); assertTrue(solo.waitForCondition(() -> UserPreferences.getUpdateInterval() == 0, 1000)); } + @Test public void testSetUpdateInterval() { - 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() { + 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.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"); @@ -224,8 +265,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.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"); @@ -233,71 +276,74 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference assertTrue(solo.waitForCondition(() -> UserPreferences.getParallelDownloads() == 10, Timeout.getLargeTimeout())); } + @Test public void testSetParallelDownloadsInvalidInput() { - 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.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.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); String maxEntry = entries[entries.length-1]; final int maxValue = Integer.valueOf(values[values.length-1]); + 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.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(); @@ -312,7 +358,10 @@ 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)); solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title)); solo.waitForText(solo.getString(R.string.episode_cleanup_queue_removal)); solo.clickOnText(solo.getString(R.string.episode_cleanup_queue_removal)); @@ -323,7 +372,10 @@ 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)); solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title)); solo.waitForText(solo.getString(R.string.episode_cleanup_never)); solo.clickOnText(solo.getString(R.string.episode_cleanup_never)); @@ -334,7 +386,10 @@ 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)); solo.clickOnText(solo.getString(R.string.pref_episode_cleanup_title)); solo.waitForText(solo.getString(R.string.episode_cleanup_after_listening)); solo.clickOnText(solo.getString(R.string.episode_cleanup_after_listening)); @@ -349,10 +404,14 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference Timeout.getLargeTimeout())); } + @Test public void testEpisodeCleanupNumDays() { - 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) { @@ -364,12 +423,13 @@ public class PreferencesTest extends ActivityInstrumentationTestCase2<Preference 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.pref_rewind)); + clickPreference(withText(R.string.playback_pref)); + clickPreference(withText(R.string.pref_rewind)); solo.waitForDialogToOpen(); int currentIndex = Arrays.binarySearch(deltas, seconds); @@ -377,21 +437,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() { + 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); @@ -400,12 +461,52 @@ 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())); + } + + 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 432d4a4e6..ff5374268 100644 --- a/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java +++ b/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java @@ -1,9 +1,7 @@ package de.test.antennapod.ui; -import android.annotation.TargetApi; import android.content.Context; import android.graphics.Bitmap; -import android.os.Build; import android.util.Log; import junit.framework.Assert; @@ -20,14 +18,12 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; -import de.danoeh.antennapod.R; 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.event.QueueEvent; import de.danoeh.antennapod.core.storage.PodDBAdapter; import de.danoeh.antennapod.core.util.playback.PlaybackController; import de.danoeh.antennapod.fragment.ExternalPlayerFragment; @@ -39,27 +35,25 @@ import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator; * Utility methods for UI tests. * Starts a web server that hosts feeds, episodes and images. */ -@TargetApi(Build.VERSION_CODES.HONEYCOMB) -public class UITestUtils { +class UITestUtils { private static final String TAG = UITestUtils.class.getSimpleName(); private static final String DATA_FOLDER = "test/UITestUtils"; - public static final int NUM_FEEDS = 5; - public static final int NUM_ITEMS_PER_FEED = 10; + private static final int NUM_FEEDS = 5; + private static final int NUM_ITEMS_PER_FEED = 10; - public static final int HOME_VIEW = (Build.VERSION.SDK_INT >= 11) ? android.R.id.home : R.id.home; - public static final String TEST_FILE_NAME = "3sec.mp3"; + private static final String TEST_FILE_NAME = "3sec.mp3"; - private Context context; - private HTTPBin server = new HTTPBin(); + private final Context context; + private final HTTPBin server = new HTTPBin(); private File destDir; private File hostedFeedDir; private File hostedMediaDir; - public List<Feed> hostedFeeds = new ArrayList<Feed>(); + public final List<Feed> hostedFeeds = new ArrayList<>(); public UITestUtils(Context context) { this.context = context; @@ -141,15 +135,12 @@ public 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<FeedItem>(); + List<FeedItem> items = new ArrayList<>(); for (int j = 0; j < NUM_ITEMS_PER_FEED; j++) { FeedItem item = new FeedItem(j, "Feed " + (i+1) + ": Item " + (j+1), "item" + j, "http://example.com/feed" + i + "/item/" + j, new Date(), FeedItem.UNPLAYED, feed); @@ -192,12 +183,6 @@ public 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/FilenameGeneratorTest.java b/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java index 13e8b9582..a36b3b65a 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/FilenameGeneratorTest.java @@ -1,10 +1,12 @@ package de.test.antennapod.util; +import android.test.AndroidTestCase; +import android.text.TextUtils; + import java.io.File; import java.io.IOException; import de.danoeh.antennapod.core.util.FileNameGenerator; -import android.test.AndroidTestCase; public class FilenameGeneratorTest extends AndroidTestCase { @@ -41,7 +43,12 @@ public class FilenameGeneratorTest extends AndroidTestCase { public void testFeedTitleContainsDash() { String result = FileNameGenerator.generateFileName("Left - Right"); - assertEquals("Left Right", result); + assertEquals("Left - Right", result); + } + + public void testInvalidInput() { + String result = FileNameGenerator.generateFileName("???"); + assertTrue(!TextUtils.isEmpty(result)); } /** diff --git a/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java b/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java index fcfb16eb4..d564d0492 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/RewindAfterPauseUtilTest.java @@ -1,8 +1,8 @@ package de.test.antennapod.util; -import junit.framework.*; +import junit.framework.TestCase; -import de.danoeh.antennapod.core.util.*; +import de.danoeh.antennapod.core.util.RewindAfterPauseUtils; /** * Tests for {@link RewindAfterPauseUtils}. diff --git a/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java b/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java index 7bdcfb898..2cca6b4dc 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/URIUtilTest.java @@ -1,6 +1,7 @@ package de.test.antennapod.util; import android.test.AndroidTestCase; + import de.danoeh.antennapod.core.util.URIUtil; /** diff --git a/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java b/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java index aa197b6e1..1b444bfa9 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/URLCheckerTest.java @@ -1,6 +1,7 @@ package de.test.antennapod.util; import android.test.AndroidTestCase; + import de.danoeh.antennapod.core.util.URLChecker; /** 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 2f2c3fe5b..cde93fd7e 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 @@ -45,11 +45,11 @@ public class HTTPBin extends NanoHTTPD { private static final String MIME_HTML = "text/html"; private static final String MIME_PLAIN = "text/plain"; - private List<File> servedFiles; + private final List<File> servedFiles; public HTTPBin() { super(PORT); - this.servedFiles = new ArrayList<File>(); + this.servedFiles = new ArrayList<>(); } /** diff --git a/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java b/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java index 28ff6694e..61ff65809 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java +++ b/app/src/androidTest/java/de/test/antennapod/util/service/download/NanoHTTPD.java @@ -88,15 +88,15 @@ public abstract class NanoHTTPD { * This is required as the Keep-Alive HTTP connections would otherwise * block the socket reading thread forever (or as long the browser is open). */ - public static final int SOCKET_READ_TIMEOUT = 5000; + private static final int SOCKET_READ_TIMEOUT = 5000; /** * Common mime type for dynamic content: plain text */ - public static final String MIME_PLAINTEXT = "text/plain"; + private static final String MIME_PLAINTEXT = "text/plain"; /** * Common mime type for dynamic content: html */ - public static final String MIME_HTML = "text/html"; + private static final String MIME_HTML = "text/html"; /** * Pseudo-Parameter to use to store the actual query string in the parameters map for later re-processing. */ @@ -104,7 +104,7 @@ public abstract class NanoHTTPD { private final String hostname; private final int myPort; private ServerSocket myServerSocket; - private Set<Socket> openConnections = new HashSet<Socket>(); + private final Set<Socket> openConnections = new HashSet<>(); private Thread myThread; /** * Pluggable strategy for asynchronously executing requests. @@ -118,14 +118,14 @@ public abstract class NanoHTTPD { /** * Constructs an HTTP server on given port. */ - public NanoHTTPD(int port) { + NanoHTTPD(int port) { this(null, port); } /** * Constructs an HTTP server on given hostname and port. */ - public NanoHTTPD(String hostname, int port) { + private NanoHTTPD(String hostname, int port) { this.hostname = hostname; this.myPort = port; setTempFileManagerFactory(new DefaultTempFileManagerFactory()); @@ -168,44 +168,38 @@ public abstract class NanoHTTPD { myServerSocket = new ServerSocket(); myServerSocket.bind((hostname != null) ? new InetSocketAddress(hostname, myPort) : new InetSocketAddress(myPort)); - myThread = new Thread(new Runnable() { - @Override - public void run() { - do { - try { - final Socket finalAccept = myServerSocket.accept(); - registerConnection(finalAccept); - finalAccept.setSoTimeout(SOCKET_READ_TIMEOUT); - final InputStream inputStream = finalAccept.getInputStream(); - asyncRunner.exec(new Runnable() { - @Override - public void run() { - OutputStream outputStream = null; - try { - outputStream = finalAccept.getOutputStream(); - TempFileManager tempFileManager = tempFileManagerFactory.create(); - HTTPSession session = new HTTPSession(tempFileManager, inputStream, outputStream, finalAccept.getInetAddress()); - while (!finalAccept.isClosed()) { - session.execute(); - } - } catch (Exception e) { - // When the socket is closed by the client, we throw our own SocketException - // to break the "keep alive" loop above. - if (!(e instanceof SocketException && "NanoHttpd Shutdown".equals(e.getMessage()))) { - e.printStackTrace(); - } - } finally { - safeClose(outputStream); - safeClose(inputStream); - safeClose(finalAccept); - unRegisterConnection(finalAccept); - } + myThread = new Thread(() -> { + do { + try { + final Socket finalAccept = myServerSocket.accept(); + registerConnection(finalAccept); + finalAccept.setSoTimeout(SOCKET_READ_TIMEOUT); + final InputStream inputStream = finalAccept.getInputStream(); + asyncRunner.exec(() -> { + OutputStream outputStream = null; + try { + outputStream = finalAccept.getOutputStream(); + TempFileManager tempFileManager = tempFileManagerFactory.create(); + HTTPSession session = new HTTPSession(tempFileManager, inputStream, outputStream, finalAccept.getInetAddress()); + while (!finalAccept.isClosed()) { + session.execute(); } - }); - } catch (IOException e) { - } - } while (!myServerSocket.isClosed()); - } + } catch (Exception e) { + // When the socket is closed by the client, we throw our own SocketException + // to break the "keep alive" loop above. + if (!(e instanceof SocketException && "NanoHttpd Shutdown".equals(e.getMessage()))) { + e.printStackTrace(); + } + } finally { + safeClose(outputStream); + safeClose(inputStream); + safeClose(finalAccept); + unRegisterConnection(finalAccept); + } + }); + } catch (IOException e) { + } + } while (!myServerSocket.isClosed()); }); myThread.setDaemon(true); myThread.setName("NanoHttpd Main Listener"); @@ -232,7 +226,7 @@ public abstract class NanoHTTPD { * * @param socket the {@link Socket} for the connection. */ - public synchronized void registerConnection(Socket socket) { + private synchronized void registerConnection(Socket socket) { openConnections.add(socket); } @@ -242,14 +236,14 @@ public abstract class NanoHTTPD { * @param socket * the {@link Socket} for the connection. */ - public synchronized void unRegisterConnection(Socket socket) { + private synchronized void unRegisterConnection(Socket socket) { openConnections.remove(socket); } /** * Forcibly closes all connections that are open. */ - public synchronized void closeAllConnections() { + private synchronized void closeAllConnections() { for (Socket socket : openConnections) { safeClose(socket); } @@ -259,7 +253,7 @@ public abstract class NanoHTTPD { return myServerSocket == null ? -1 : myServerSocket.getLocalPort(); } - public final boolean wasStarted() { + private boolean wasStarted() { return myServerSocket != null && myThread != null; } @@ -294,7 +288,7 @@ public abstract class NanoHTTPD { * @param session The HTTP session * @return HTTP response, see class Response for details */ - public Response serve(IHTTPSession session) { + Response serve(IHTTPSession session) { Map<String, String> files = new ArrayMap<>(); Method method = session.getMethod(); if (Method.PUT.equals(method) || Method.POST.equals(method)) { @@ -318,7 +312,7 @@ public abstract class NanoHTTPD { * @param str the percent encoded <code>String</code> * @return expanded form of the input, for example "foo%20bar" becomes "foo bar" */ - protected String decodePercent(String str) { + private String decodePercent(String str) { String decoded = null; try { decoded = URLDecoder.decode(str, "UTF8"); @@ -347,8 +341,8 @@ public abstract class NanoHTTPD { * @param queryString a query string pulled from the URL. * @return a map of <code>String</code> (parameter name) to <code>List<String></code> (a list of the values supplied). */ - protected Map<String, List<String>> decodeParameters(String queryString) { - Map<String, List<String>> parms = new ArrayMap<String, List<String>>(); + private Map<String, List<String>> decodeParameters(String queryString) { + Map<String, List<String>> parms = new ArrayMap<>(); if (queryString != null) { StringTokenizer st = new StringTokenizer(queryString, "&"); while (st.hasMoreTokens()) { @@ -356,7 +350,7 @@ public abstract class NanoHTTPD { int sep = e.indexOf('='); String propertyName = (sep >= 0) ? decodePercent(e.substring(0, sep)).trim() : decodePercent(e).trim(); if (!parms.containsKey(propertyName)) { - parms.put(propertyName, new ArrayList<String>()); + parms.put(propertyName, new ArrayList<>()); } String propertyValue = (sep >= 0) ? decodePercent(e.substring(sep + 1)) : null; if (propertyValue != null) { @@ -378,7 +372,7 @@ public abstract class NanoHTTPD { * * @param asyncRunner new strategy for handling threads. */ - public void setAsyncRunner(AsyncRunner asyncRunner) { + private void setAsyncRunner(AsyncRunner asyncRunner) { this.asyncRunner = asyncRunner; } @@ -393,7 +387,7 @@ public abstract class NanoHTTPD { * * @param tempFileManagerFactory new strategy for handling temp files. */ - public void setTempFileManagerFactory(TempFileManagerFactory tempFileManagerFactory) { + private void setTempFileManagerFactory(TempFileManagerFactory tempFileManagerFactory) { this.tempFileManagerFactory = tempFileManagerFactory; } @@ -448,9 +442,9 @@ public abstract class NanoHTTPD { * themselves up when no longer needed.</p> */ public interface TempFile { - OutputStream open() throws Exception; + OutputStream open(); - void delete() throws Exception; + void delete(); String getName(); } @@ -490,7 +484,7 @@ public abstract class NanoHTTPD { public DefaultTempFileManager() { tmpdir = System.getProperty("java.io.tmpdir"); - tempFiles = new ArrayList<TempFile>(); + tempFiles = new ArrayList<>(); } @Override @@ -528,12 +522,12 @@ public abstract class NanoHTTPD { } @Override - public OutputStream open() throws Exception { + public OutputStream open() { return fstream; } @Override - public void delete() throws Exception { + public void delete() { safeClose(fstream); file.delete(); } @@ -563,7 +557,7 @@ public abstract class NanoHTTPD { /** * Headers for the HTTP response. Use addHeader() to add lines. */ - private Map<String, String> header = new ArrayMap<String, String>(); + private final Map<String, String> header = new ArrayMap<>(); /** * The request method that spawned this response. */ @@ -616,7 +610,7 @@ public abstract class NanoHTTPD { /** * Sends given response to the socket. */ - protected void send(OutputStream outputStream) { + void send(OutputStream outputStream) { String mime = mimeType; SimpleDateFormat gmtFrmt = new SimpleDateFormat("E, d MMM yyyy HH:mm:ss 'GMT'", Locale.US); gmtFrmt.setTimeZone(TimeZone.getTimeZone("GMT")); @@ -661,13 +655,13 @@ public abstract class NanoHTTPD { } } - protected void sendContentLengthHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header, int size) { + void sendContentLengthHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header, int size) { if (!headerAlreadySent(header, "content-length")) { pw.print("Content-Length: "+ size +"\r\n"); } } - protected void sendConnectionHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header) { + void sendConnectionHeaderIfNotAlreadyPresent(PrintWriter pw, Map<String, String> header) { if (!headerAlreadySent(header, "connection")) { pw.print("Connection: keep-alive\r\n"); } @@ -694,7 +688,7 @@ public abstract class NanoHTTPD { outputStream.write(buff, 0, read); outputStream.write(CRLF); } - outputStream.write(String.format("0\r\n\r\n").getBytes()); + outputStream.write("0\r\n\r\n".getBytes()); } private void sendAsFixedLength(OutputStream outputStream, int pending) throws IOException { @@ -844,7 +838,7 @@ public abstract class NanoHTTPD { public static final int BUFSIZE = 8192; private final TempFileManager tempFileManager; private final OutputStream outputStream; - private PushbackInputStream inputStream; + private final PushbackInputStream inputStream; private int splitbyte; private int rlen; private String uri; @@ -865,7 +859,7 @@ public abstract class NanoHTTPD { this.inputStream = new PushbackInputStream(inputStream, BUFSIZE); this.outputStream = outputStream; String remoteIp = inetAddress.isLoopbackAddress() || inetAddress.isAnyLocalAddress() ? "127.0.0.1" : inetAddress.getHostAddress().toString(); - headers = new ArrayMap<String, String>(); + headers = new ArrayMap<>(); headers.put("remote-addr", remoteIp); headers.put("http-client-ip", remoteIp); @@ -909,16 +903,16 @@ public abstract class NanoHTTPD { inputStream.unread(buf, splitbyte, rlen - splitbyte); } - parms = new ArrayMap<String, String>(); + parms = new ArrayMap<>(); if(null == headers) { - headers = new ArrayMap<String, String>(); + headers = new ArrayMap<>(); } // Create a BufferedReader for parsing the header. BufferedReader hin = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(buf, 0, rlen))); // Decode the header into parms and header java properties - Map<String, String> pre = new ArrayMap<String, String>(); + Map<String, String> pre = new ArrayMap<>(); decodeHeader(hin, pre, parms, headers); method = Method.lookup(pre.get("method")); @@ -1116,7 +1110,7 @@ public abstract class NanoHTTPD { throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but next chunk does not start with boundary. Usage: GET /example/file.html"); } boundarycount++; - Map<String, String> item = new ArrayMap<String, String>(); + Map<String, String> item = new ArrayMap<>(); mpline = in.readLine(); while (mpline != null && mpline.trim().length() > 0) { int p = mpline.indexOf(':'); @@ -1131,7 +1125,7 @@ public abstract class NanoHTTPD { throw new ResponseException(Response.Status.BAD_REQUEST, "BAD REQUEST: Content type is multipart/form-data but no content-disposition info found. Usage: GET /example/file.html"); } StringTokenizer st = new StringTokenizer(contentDisposition, ";"); - Map<String, String> disposition = new ArrayMap<String, String>(); + Map<String, String> disposition = new ArrayMap<>(); while (st.hasMoreTokens()) { String token = st.nextToken().trim(); int p = token.indexOf('='); @@ -1144,17 +1138,19 @@ public abstract class NanoHTTPD { String value = ""; if (item.get("content-type") == null) { + StringBuilder tmp = new StringBuilder(); while (mpline != null && !mpline.contains(boundary)) { mpline = in.readLine(); if (mpline != null) { int d = mpline.indexOf(boundary); if (d == -1) { - value += mpline; + tmp.append(mpline); } else { - value += mpline.substring(0, d - 2); + tmp.append(mpline.substring(0, d - 2)); } } } + value = tmp.toString(); } else { if (boundarycount > bpositions.length) { throw new ResponseException(Response.Status.INTERNAL_ERROR, "Error processing request"); @@ -1196,7 +1192,7 @@ public abstract class NanoHTTPD { private int[] getBoundaryPositions(ByteBuffer b, byte[] boundary) { int matchcount = 0; int matchbyte = -1; - List<Integer> matchbytes = new ArrayList<Integer>(); + List<Integer> matchbytes = new ArrayList<>(); for (int i = 0; i < b.limit(); i++) { if (b.get(i) == boundary[matchcount]) { if (matchcount == 0) @@ -1326,7 +1322,9 @@ public abstract class NanoHTTPD { } public static class Cookie { - private String n, v, e; + private final String n; + private final String v; + private final String e; public Cookie(String name, String value, String expires) { n = name; @@ -1366,8 +1364,8 @@ public abstract class NanoHTTPD { * @author LordFokas */ public class CookieHandler implements Iterable<String> { - private ArrayMap<String, String> cookies = new ArrayMap<String, String>(); - private ArrayList<Cookie> queue = new ArrayList<Cookie>(); + private final ArrayMap<String, String> cookies = new ArrayMap<>(); + private final ArrayList<Cookie> queue = new ArrayList<>(); public CookieHandler(Map<String, String> httpHeaders) { String raw = httpHeaders.get("cookie"); diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java index 4e5d0297f..809b9769a 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java +++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/FeedDiscovererTest.java @@ -1,7 +1,7 @@ package de.test.antennapod.util.syndication; import android.test.InstrumentationTestCase; -import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer; + import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; @@ -9,6 +9,8 @@ import java.io.File; import java.io.FileOutputStream; import java.util.Map; +import de.danoeh.antennapod.core.util.syndication.FeedDiscoverer; + /** * Test class for FeedDiscoverer */ 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 bd3df0f9d..afe15f1b2 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 @@ -19,7 +19,7 @@ public class AtomGenerator implements FeedGenerator{ private static final String NS_ATOM = "http://www.w3.org/2005/Atom"; - public static final long FEATURE_USE_RFC3339LOCAL = 1; + private static final long FEATURE_USE_RFC3339LOCAL = 1; @Override public void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException { diff --git a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/FeedGenerator.java b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/FeedGenerator.java index fe5afd847..b63159384 100644 --- a/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/FeedGenerator.java +++ b/app/src/androidTest/java/de/test/antennapod/util/syndication/feedgenerator/FeedGenerator.java @@ -1,10 +1,10 @@ package de.test.antennapod.util.syndication.feedgenerator; -import de.danoeh.antennapod.core.feed.Feed; - import java.io.IOException; import java.io.OutputStream; +import de.danoeh.antennapod.core.feed.Feed; + /** * Generates a machine-readable, platform-independent representation of a Feed object. */ @@ -24,5 +24,5 @@ public interface FeedGenerator { * @param encoding The encoding to use. Must not be null. * @param flags Optional argument for enabling implementation-dependent features. */ - public void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException; + void writeFeed(Feed feed, OutputStream outputStream, String encoding, long flags) throws IOException; } 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 e7cbb1b42..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 @@ -7,7 +7,8 @@ import java.io.IOException; /** * Utility methods for FeedGenerator */ -public class GeneratorUtil { +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 27e89620d..f2d53799d 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 @@ -1,14 +1,16 @@ package de.test.antennapod.util.syndication.feedgenerator; import android.util.Xml; -import de.danoeh.antennapod.core.feed.Feed; -import de.danoeh.antennapod.core.feed.FeedItem; -import de.danoeh.antennapod.core.util.DateUtils; + import org.xmlpull.v1.XmlSerializer; import java.io.IOException; import java.io.OutputStream; +import de.danoeh.antennapod.core.feed.Feed; +import de.danoeh.antennapod.core.feed.FeedItem; +import de.danoeh.antennapod.core.util.DateUtils; + /** * Creates RSS 2.0 feeds. See FeedGenerator for more information. */ |