summaryrefslogtreecommitdiff
path: root/app/src/androidTest/java/de/test/antennapod/ui/UITestUtils.java
blob: e95f0990ea19eefaaf774863bdb97926a0c6d965 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package de.test.antennapod.ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.util.Log;

import de.danoeh.antennapod.core.event.FeedListUpdateEvent;
import de.danoeh.antennapod.core.util.playback.Playable;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;

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.activity.MainActivity;
import de.danoeh.antennapod.core.event.QueueEvent;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.storage.PodDBAdapter;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
import de.danoeh.antennapod.fragment.ExternalPlayerFragment;
import de.test.antennapod.util.service.download.HTTPBin;
import de.test.antennapod.util.syndication.feedgenerator.RSS2Generator;
import org.greenrobot.eventbus.EventBus;
import org.junit.Assert;

/**
 * Utility methods for UI tests.
 * Starts a web server that hosts feeds, episodes and images.
 */
public class UITestUtils {

    private static final String TAG = UITestUtils.class.getSimpleName();

    private static final int NUM_FEEDS = 5;
    private static final int NUM_ITEMS_PER_FEED = 10;

    private String testFileName = "3sec.mp3";
    private boolean hostTextOnlyFeeds = false;
    private final Context context;
    private final HTTPBin server = new HTTPBin();
    private File destDir;
    private File hostedFeedDir;
    private File hostedMediaDir;

    public final List<Feed> hostedFeeds = new ArrayList<>();

    public UITestUtils(Context context) {
        this.context = context;
    }


    public void setup() throws IOException {
        destDir = new File(context.getFilesDir(), "test/UITestUtils");
        destDir.mkdirs();
        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", server.getBaseUrl(), id);
    }

    private String hostFile(File file) {
        int id = server.serveFile(file);
        Assert.assertTrue(id != -1);
        return String.format("%s/files/%d", server.getBaseUrl(), id);
    }

    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(testFileName);
        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++) {
            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, null, null,
                    "http://example.com/feed/src/" + i, false);

            // create items
            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);
                items.add(item);

                if (!hostTextOnlyFeeds) {
                    File mediaFile = newMediaFile("feed-" + i + "-episode-" + j + ".mp3");
                    item.setMedia(new FeedMedia(j, item, 0, 0, mediaFile.length(), "audio/mp3", null, hostFile(mediaFile), false, null, 0, 0));
                }
            }
            feed.setItems(items);
            feed.setDownload_url(hostFeed(feed));
            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 (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));
            if (feed.getItems().get(1).hasMedia()) {
                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();
        EventBus.getDefault().post(new FeedListUpdateEvent(hostedFeeds));
        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() {
        Playable playable = Playable.PlayableUtils.createInstanceFromPreferences(context);
        return (FeedMedia) playable;
    }

    public void setMediaFileName(String filename) {
        testFileName = filename;
    }

    public void setHostTextOnlyFeeds(boolean hostTextOnlyFeeds) {
        this.hostTextOnlyFeeds = hostTextOnlyFeeds;
    }
}