Skip to content

Commit e510671

Browse files
committed
Add tests for new methods retrieving MediaFormats
Fix failing tests
1 parent f3859ed commit e510671

2 files changed

Lines changed: 169 additions & 4 deletions

File tree

app/src/androidTest/java/org/schabi/newpipe/util/StreamItemAdapterTest.kt

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,21 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
1212
import androidx.test.filters.MediumTest
1313
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
1414
import org.junit.Assert
15+
import org.junit.Assert.assertEquals
16+
import org.junit.Assert.assertFalse
17+
import org.junit.Assert.assertNull
18+
import org.junit.Assert.assertTrue
1519
import org.junit.Before
1620
import org.junit.Test
1721
import org.junit.runner.RunWith
1822
import org.schabi.newpipe.R
1923
import org.schabi.newpipe.extractor.MediaFormat
24+
import org.schabi.newpipe.extractor.downloader.Response
2025
import org.schabi.newpipe.extractor.stream.AudioStream
2126
import org.schabi.newpipe.extractor.stream.Stream
2227
import org.schabi.newpipe.extractor.stream.SubtitlesStream
2328
import org.schabi.newpipe.extractor.stream.VideoStream
29+
import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper
2430

2531
@MediumTest
2632
@RunWith(AndroidJUnit4::class)
@@ -123,6 +129,101 @@ class StreamItemAdapterTest {
123129
}
124130
}
125131

132+
@Test
133+
fun retrieveMediaFormatFromFileTypeHeaders() {
134+
val streams = getIncompleteAudioStreams(5)
135+
val wrapper = StreamInfoWrapper(streams, context)
136+
val retrieveMediaFormat = { stream: AudioStream, response: Response ->
137+
StreamInfoWrapper.retrieveMediaFormatFromFileTypeHeaders(stream, wrapper, response)
138+
}
139+
val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat)
140+
141+
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0)
142+
helper.assertInvalidResponse(getResponse(mapOf(Pair("file-type", "mp0"))), 1)
143+
144+
helper.assertValidResponse(getResponse(mapOf(Pair("x-amz-meta-file-type", "aiff"))), 2, MediaFormat.AIFF)
145+
helper.assertValidResponse(getResponse(mapOf(Pair("file-type", "mp3"))), 3, MediaFormat.MP3)
146+
}
147+
148+
@Test
149+
fun retrieveMediaFormatFromContentDispositionHeader() {
150+
val streams = getIncompleteAudioStreams(11)
151+
val wrapper = StreamInfoWrapper(streams, context)
152+
val retrieveMediaFormat = { stream: AudioStream, response: Response ->
153+
StreamInfoWrapper.retrieveMediaFormatFromContentDispositionHeader(stream, wrapper, response)
154+
}
155+
val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat)
156+
157+
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0)
158+
helper.assertInvalidResponse(
159+
getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.png\""))), 1
160+
)
161+
helper.assertInvalidResponse(
162+
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"data.csv\""))), 2
163+
)
164+
helper.assertInvalidResponse(
165+
getResponse(mapOf(Pair("Content-Disposition", "form-data; filename=\"data.csv\""))), 3
166+
)
167+
helper.assertInvalidResponse(
168+
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"fieldName\"; filename*=\"filename.jpg\""))), 4
169+
)
170+
171+
helper.assertValidResponse(
172+
getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.ogg\""))),
173+
5, MediaFormat.OGG
174+
)
175+
helper.assertValidResponse(
176+
getResponse(mapOf(Pair("Content-Disposition", "some-form-data; filename=\"audio.flac\""))),
177+
6, MediaFormat.FLAC
178+
)
179+
helper.assertValidResponse(
180+
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.aiff\"; filename=\"audio.aiff\""))),
181+
7, MediaFormat.AIFF
182+
)
183+
helper.assertValidResponse(
184+
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"alien?\"; filename*=UTF-8''%CE%B1%CE%BB%CE%B9%CF%B5%CE%BD.m4a"))),
185+
8, MediaFormat.M4A
186+
)
187+
helper.assertValidResponse(
188+
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=UTF-8''alien.opus"))),
189+
9, MediaFormat.OPUS
190+
)
191+
helper.assertValidResponse(
192+
getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=\"UTF-8''alien.opus\""))),
193+
10, MediaFormat.OPUS
194+
)
195+
}
196+
197+
@Test
198+
fun retrieveMediaFormatFromContentTypeHeader() {
199+
val streams = getIncompleteAudioStreams(10)
200+
val wrapper = StreamInfoWrapper(streams, context)
201+
val retrieveMediaFormat = { stream: AudioStream, response: Response ->
202+
StreamInfoWrapper.retrieveMediaFormatFromContentTypeHeader(stream, wrapper, response)
203+
}
204+
val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat)
205+
206+
helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "984501"))), 0)
207+
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/xyz"))), 1)
208+
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 2)
209+
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 3)
210+
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/mpeg"))), 4)
211+
helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/aif"))), 5)
212+
213+
helper.assertValidResponse(
214+
getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 6, MediaFormat.FLAC
215+
)
216+
helper.assertValidResponse(
217+
getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 7, MediaFormat.WAV
218+
)
219+
helper.assertValidResponse(
220+
getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 8, MediaFormat.OPUS
221+
)
222+
helper.assertValidResponse(
223+
getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 9, MediaFormat.AIFF
224+
)
225+
}
226+
126227
/**
127228
* @return a list of video streams, in which their video only property mirrors the provided
128229
* [videoOnly] vararg.
@@ -161,6 +262,19 @@ class StreamItemAdapterTest {
161262
}
162263
)
163264

265+
private fun getIncompleteAudioStreams(size: Int): List<AudioStream> {
266+
val list = ArrayList<AudioStream>(size)
267+
for (i in 1..size) {
268+
list.add(
269+
AudioStream.Builder()
270+
.setId(Stream.ID_UNKNOWN)
271+
.setContent("https://example.com/$i", true)
272+
.build()
273+
)
274+
}
275+
return list
276+
}
277+
164278
/**
165279
* Checks whether the item at [position] in the [spinner] has the correct icon visibility when
166280
* it is shown in normal mode (selected) and in dropdown mode (user is choosing one of a list).
@@ -203,4 +317,49 @@ class StreamItemAdapterTest {
203317
put(index, secondaryStreamHelper)
204318
}
205319
}
320+
321+
private fun getResponse(headers: Map<String, String>): Response {
322+
val listHeaders = HashMap<String, List<String>>()
323+
headers.forEach { entry ->
324+
listHeaders[entry.key] = listOf(entry.value)
325+
}
326+
return Response(200, null, listHeaders, "", "")
327+
}
328+
329+
/**
330+
* Helper class for assertion related to extractions of [MediaFormat]s.
331+
*/
332+
class AssertionHelper<T : Stream>(
333+
private val streams: List<T>,
334+
private val wrapper: StreamInfoWrapper<T>,
335+
private val retrieveMediaFormat: (stream: T, response: Response) -> Boolean
336+
) {
337+
338+
/**
339+
* Assert that an invalid response does not result in wrongly extracted [MediaFormat].
340+
*/
341+
fun assertInvalidResponse(
342+
response: Response,
343+
index: Int
344+
) {
345+
assertFalse(
346+
"invalid header returns valid value", retrieveMediaFormat(streams[index], response)
347+
)
348+
assertNull("Media format extracted although stated otherwise", wrapper.getFormat(index))
349+
}
350+
351+
/**
352+
* Assert that a valid response results in correctly extracted and handled [MediaFormat].
353+
*/
354+
fun assertValidResponse(
355+
response: Response,
356+
index: Int,
357+
format: MediaFormat
358+
) {
359+
assertTrue(
360+
"header was not recognized", retrieveMediaFormat(streams[index], response)
361+
)
362+
assertEquals("Wrong media format extracted", format, wrapper.getFormat(index))
363+
}
364+
}
206365
}

app/src/main/java/org/schabi/newpipe/util/StreamItemAdapter.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
import androidx.annotation.NonNull;
1515
import androidx.annotation.Nullable;
16+
import androidx.annotation.VisibleForTesting;
1617
import androidx.collection.SparseArrayCompat;
1718

1819
import org.schabi.newpipe.DownloaderImpl;
@@ -298,7 +299,8 @@ public static <X extends Stream> Single<Boolean> fetchMoreInfoForWrapper(
298299
* @param response the response of the head request for the given stream
299300
* @return {@code true} if the media format could be retrieved; {@code false} otherwise
300301
*/
301-
private static <X extends Stream> boolean retrieveMediaFormat(
302+
@VisibleForTesting
303+
public static <X extends Stream> boolean retrieveMediaFormat(
302304
@NonNull final X stream,
303305
@NonNull final StreamInfoWrapper<X> streamsWrapper,
304306
@NonNull final Response response) {
@@ -308,7 +310,8 @@ private static <X extends Stream> boolean retrieveMediaFormat(
308310
|| retrieveMediaFormatFromContentTypeHeader(stream, streamsWrapper, response);
309311
}
310312

311-
private static <X extends Stream> boolean retrieveMediaFormatFromFileTypeHeaders(
313+
@VisibleForTesting
314+
public static <X extends Stream> boolean retrieveMediaFormatFromFileTypeHeaders(
312315
@NonNull final X stream,
313316
@NonNull final StreamInfoWrapper<X> streamsWrapper,
314317
@NonNull final Response response) {
@@ -342,6 +345,7 @@ private static <X extends Stream> boolean retrieveMediaFormatFromFileTypeHeaders
342345
* otherwise {@code false}
343346
* @param <X>
344347
*/
348+
@VisibleForTesting
345349
public static <X extends Stream> boolean retrieveMediaFormatFromContentDispositionHeader(
346350
@NonNull final X stream,
347351
@NonNull final StreamInfoWrapper<X> streamsWrapper,
@@ -391,7 +395,8 @@ public static <X extends Stream> boolean retrieveMediaFormatFromContentDispositi
391395
return false;
392396
}
393397

394-
private static <X extends Stream> boolean retrieveMediaFormatFromContentTypeHeader(
398+
@VisibleForTesting
399+
public static <X extends Stream> boolean retrieveMediaFormatFromContentTypeHeader(
395400
@NonNull final X stream,
396401
@NonNull final StreamInfoWrapper<X> streamsWrapper,
397402
@NonNull final Response response) {
@@ -416,7 +421,8 @@ private static <X extends Stream> boolean retrieveMediaFormatFromContentTypeHead
416421
public void resetInfo() {
417422
Arrays.fill(streamSizes, SIZE_UNSET);
418423
for (int i = 0; i < streamsList.size(); i++) {
419-
streamFormats[i] = streamsList.get(i).getFormat();
424+
streamFormats[i] = streamsList.get(i) == null // test for invalid streams
425+
? null : streamsList.get(i).getFormat();
420426
}
421427
}
422428

0 commit comments

Comments
 (0)