| 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; |
| |
| import org.apache.commons.io.FileUtils; |
| import org.apache.commons.io.IOUtils; |
| import org.apache.commons.lang3.StringUtils; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| 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.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; |
| import de.greenrobot.event.EventBus; |
| import de.test.antennapod.util.service.download.HTTPBin; |
| 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 { |
| |
| 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; |
| |
| 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 Context context; |
| private HTTPBin server = new HTTPBin(); |
| private File destDir; |
| private File hostedFeedDir; |
| private File hostedMediaDir; |
| |
| public List<Feed> hostedFeeds = new ArrayList<Feed>(); |
| |
| public UITestUtils(Context context) { |
| this.context = context; |
| } |
| |
| |
| public void setup() throws IOException { |
| destDir = context.getExternalFilesDir(DATA_FOLDER); |
| destDir.mkdir(); |
| hostedFeedDir = new File(destDir, "hostedFeeds"); |
| hostedFeedDir.mkdir(); |
| hostedMediaDir = new File(destDir, "hostedMediaDir"); |
| hostedMediaDir.mkdir(); |
| Assert.assertTrue(destDir.exists()); |
| Assert.assertTrue(hostedFeedDir.exists()); |
| Assert.assertTrue(hostedMediaDir.exists()); |
| server.start(); |
| } |
| |
| public void tearDown() throws IOException { |
| FileUtils.deleteDirectory(destDir); |
| FileUtils.deleteDirectory(hostedMediaDir); |
| FileUtils.deleteDirectory(hostedFeedDir); |
| server.stop(); |
| |
| if (localFeedDataAdded) { |
| PodDBAdapter.deleteDatabase(); |
| } |
| } |
| |
| private String hostFeed(Feed feed) throws IOException { |
| File feedFile = new File(hostedFeedDir, feed.getTitle()); |
| FileOutputStream out = new FileOutputStream(feedFile); |
| RSS2Generator generator = new RSS2Generator(); |
| generator.writeFeed(feed, out, "UTF-8", 0); |
| out.close(); |
| int id = server.serveFile(feedFile); |
| Assert.assertTrue(id != -1); |
| return String.format("%s/files/%d", HTTPBin.BASE_URL, id); |
| } |
| |
| private String hostFile(File file) { |
| int id = server.serveFile(file); |
| Assert.assertTrue(id != -1); |
| return String.format("%s/files/%d", HTTPBin.BASE_URL, id); |
| } |
| |
| private File newBitmapFile(String name) throws IOException { |
| File imgFile = new File(destDir, name); |
| Bitmap bitmap = Bitmap.createBitmap(128, 128, Bitmap.Config.ARGB_8888); |
| FileOutputStream out = new FileOutputStream(imgFile); |
| bitmap.compress(Bitmap.CompressFormat.PNG, 1, out); |
| out.close(); |
| return imgFile; |
| } |
| |
| private File newMediaFile(String name) throws IOException { |
| File mediaFile = new File(hostedMediaDir, name); |
| if(mediaFile.exists()) { |
| mediaFile.delete(); |
| } |
| Assert.assertFalse(mediaFile.exists()); |
| |
| InputStream in = context.getAssets().open(TEST_FILE_NAME); |
| Assert.assertNotNull(in); |
| |
| FileOutputStream out = new FileOutputStream(mediaFile); |
| IOUtils.copy(in, out); |
| out.close(); |
| |
| return mediaFile; |
| } |
| |
| private boolean feedDataHosted = false; |
| |
| /** |
| * Adds feeds, images and episodes to the webserver for testing purposes. |
| */ |
| 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, new Date(), "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/feed/src/" + i, false); |
| image.setOwner(feed); |
| |
| // create items |
| List<FeedItem> items = new ArrayList<FeedItem>(); |
| 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); |
| items.add(item); |
| |
| File mediaFile = newMediaFile("feed-" + i + "-episode-" + j + ".mp3"); |
| item.setMedia(new FeedMedia(j, item, 0, 0, mediaFile.length(), "audio/mp3", null, hostFile(mediaFile), false, null, 0, 0)); |
| |
| } |
| feed.setItems(items); |
| feed.setDownload_url(hostFeed(feed)); |
| hostedFeeds.add(feed); |
| } |
| feedDataHosted = true; |
| } |
| |
| |
| private boolean localFeedDataAdded = false; |
| |
| /** |
| * Adds feeds, images and episodes to the local database. This method will also call addHostedFeedData if it has not |
| * been called yet. |
| * |
| * Adds one item of each feed to the queue and to the playback history. |
| * |
| * This method should NOT be called if the testing class wants to download the hosted feed data. |
| * |
| * @param downloadEpisodes true if episodes should also be marked as downloaded. |
| */ |
| public void addLocalFeedData(boolean downloadEpisodes) throws Exception { |
| if (localFeedDataAdded) { |
| Log.w(TAG, "addLocalFeedData was called twice on the same instance"); |
| // might be a flaky test, this is actually not that severe |
| return; |
| } |
| if (!feedDataHosted) { |
| addHostedFeedData(); |
| } |
| |
| 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()) { |
| FeedMedia media = item.getMedia(); |
| int fileId = Integer.parseInt(StringUtils.substringAfter(media.getDownload_url(), "files/")); |
| media.setFile_url(server.accessFile(fileId).getAbsolutePath()); |
| media.setDownloaded(true); |
| } |
| } |
| } |
| |
| queue.add(feed.getItems().get(0)); |
| feed.getItems().get(1).getMedia().setPlaybackCompletionDate(new Date()); |
| } |
| localFeedDataAdded = true; |
| |
| PodDBAdapter adapter = PodDBAdapter.getInstance(); |
| adapter.open(); |
| adapter.setCompleteFeed(hostedFeeds.toArray(new Feed[hostedFeeds.size()])); |
| adapter.setQueue(queue); |
| adapter.close(); |
| EventDistributor.getInstance().sendFeedUpdateBroadcast(); |
| EventBus.getDefault().post(QueueEvent.setQueue(queue)); |
| } |
| |
| public PlaybackController getPlaybackController(MainActivity mainActivity) { |
| ExternalPlayerFragment fragment = (ExternalPlayerFragment)mainActivity.getSupportFragmentManager().findFragmentByTag(ExternalPlayerFragment.TAG); |
| return fragment.getPlaybackControllerTestingOnly(); |
| } |
| |
| public FeedMedia getCurrentMedia(MainActivity mainActivity) { |
| return (FeedMedia)getPlaybackController(mainActivity).getMedia(); |
| } |
| } |