mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-10-31 15:23:00 +00:00 
			
		
		
		
	Add tests for new methods retrieving MediaFormats
Fix failing tests
This commit is contained in:
		| @@ -12,15 +12,21 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 | ||||
| import androidx.test.filters.MediumTest | ||||
| import androidx.test.internal.runner.junit4.statement.UiThreadStatement | ||||
| import org.junit.Assert | ||||
| import org.junit.Assert.assertEquals | ||||
| import org.junit.Assert.assertFalse | ||||
| import org.junit.Assert.assertNull | ||||
| import org.junit.Assert.assertTrue | ||||
| import org.junit.Before | ||||
| import org.junit.Test | ||||
| import org.junit.runner.RunWith | ||||
| import org.schabi.newpipe.R | ||||
| import org.schabi.newpipe.extractor.MediaFormat | ||||
| import org.schabi.newpipe.extractor.downloader.Response | ||||
| import org.schabi.newpipe.extractor.stream.AudioStream | ||||
| import org.schabi.newpipe.extractor.stream.Stream | ||||
| import org.schabi.newpipe.extractor.stream.SubtitlesStream | ||||
| import org.schabi.newpipe.extractor.stream.VideoStream | ||||
| import org.schabi.newpipe.util.StreamItemAdapter.StreamInfoWrapper | ||||
|  | ||||
| @MediumTest | ||||
| @RunWith(AndroidJUnit4::class) | ||||
| @@ -123,6 +129,101 @@ class StreamItemAdapterTest { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     fun retrieveMediaFormatFromFileTypeHeaders() { | ||||
|         val streams = getIncompleteAudioStreams(5) | ||||
|         val wrapper = StreamInfoWrapper(streams, context) | ||||
|         val retrieveMediaFormat = { stream: AudioStream, response: Response -> | ||||
|             StreamInfoWrapper.retrieveMediaFormatFromFileTypeHeaders(stream, wrapper, response) | ||||
|         } | ||||
|         val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat) | ||||
|  | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0) | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("file-type", "mp0"))), 1) | ||||
|  | ||||
|         helper.assertValidResponse(getResponse(mapOf(Pair("x-amz-meta-file-type", "aiff"))), 2, MediaFormat.AIFF) | ||||
|         helper.assertValidResponse(getResponse(mapOf(Pair("file-type", "mp3"))), 3, MediaFormat.MP3) | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     fun retrieveMediaFormatFromContentDispositionHeader() { | ||||
|         val streams = getIncompleteAudioStreams(11) | ||||
|         val wrapper = StreamInfoWrapper(streams, context) | ||||
|         val retrieveMediaFormat = { stream: AudioStream, response: Response -> | ||||
|             StreamInfoWrapper.retrieveMediaFormatFromContentDispositionHeader(stream, wrapper, response) | ||||
|         } | ||||
|         val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat) | ||||
|  | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "mp3"))), 0) | ||||
|         helper.assertInvalidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.png\""))), 1 | ||||
|         ) | ||||
|         helper.assertInvalidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"data.csv\""))), 2 | ||||
|         ) | ||||
|         helper.assertInvalidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; filename=\"data.csv\""))), 3 | ||||
|         ) | ||||
|         helper.assertInvalidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"fieldName\"; filename*=\"filename.jpg\""))), 4 | ||||
|         ) | ||||
|  | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "filename=\"train.ogg\""))), | ||||
|             5, MediaFormat.OGG | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "some-form-data; filename=\"audio.flac\""))), | ||||
|             6, MediaFormat.FLAC | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.aiff\"; filename=\"audio.aiff\""))), | ||||
|             7, MediaFormat.AIFF | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"alien?\"; filename*=UTF-8''%CE%B1%CE%BB%CE%B9%CF%B5%CE%BD.m4a"))), | ||||
|             8, MediaFormat.M4A | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=UTF-8''alien.opus"))), | ||||
|             9, MediaFormat.OPUS | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Disposition", "form-data; name=\"audio.mp3\"; filename=\"audio.opus\"; filename*=\"UTF-8''alien.opus\""))), | ||||
|             10, MediaFormat.OPUS | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     fun retrieveMediaFormatFromContentTypeHeader() { | ||||
|         val streams = getIncompleteAudioStreams(10) | ||||
|         val wrapper = StreamInfoWrapper(streams, context) | ||||
|         val retrieveMediaFormat = { stream: AudioStream, response: Response -> | ||||
|             StreamInfoWrapper.retrieveMediaFormatFromContentTypeHeader(stream, wrapper, response) | ||||
|         } | ||||
|         val helper = AssertionHelper(streams, wrapper, retrieveMediaFormat) | ||||
|  | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("content-length", "984501"))), 0) | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/xyz"))), 1) | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 2) | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "mp3"))), 3) | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/mpeg"))), 4) | ||||
|         helper.assertInvalidResponse(getResponse(mapOf(Pair("Content-Type", "audio/aif"))), 5) | ||||
|  | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Type", "audio/flac"))), 6, MediaFormat.FLAC | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Type", "audio/wav"))), 7, MediaFormat.WAV | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Type", "audio/opus"))), 8, MediaFormat.OPUS | ||||
|         ) | ||||
|         helper.assertValidResponse( | ||||
|             getResponse(mapOf(Pair("Content-Type", "audio/aiff"))), 9, MediaFormat.AIFF | ||||
|         ) | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @return a list of video streams, in which their video only property mirrors the provided | ||||
|      * [videoOnly] vararg. | ||||
| @@ -161,6 +262,19 @@ class StreamItemAdapterTest { | ||||
|             } | ||||
|         ) | ||||
|  | ||||
|     private fun getIncompleteAudioStreams(size: Int): List<AudioStream> { | ||||
|         val list = ArrayList<AudioStream>(size) | ||||
|         for (i in 1..size) { | ||||
|             list.add( | ||||
|                 AudioStream.Builder() | ||||
|                     .setId(Stream.ID_UNKNOWN) | ||||
|                     .setContent("https://example.com/$i", true) | ||||
|                     .build() | ||||
|             ) | ||||
|         } | ||||
|         return list | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Checks whether the item at [position] in the [spinner] has the correct icon visibility when | ||||
|      * it is shown in normal mode (selected) and in dropdown mode (user is choosing one of a list). | ||||
| @@ -203,4 +317,49 @@ class StreamItemAdapterTest { | ||||
|                 put(index, secondaryStreamHelper) | ||||
|             } | ||||
|         } | ||||
|  | ||||
|     private fun getResponse(headers: Map<String, String>): Response { | ||||
|         val listHeaders = HashMap<String, List<String>>() | ||||
|         headers.forEach { entry -> | ||||
|             listHeaders[entry.key] = listOf(entry.value) | ||||
|         } | ||||
|         return Response(200, null, listHeaders, "", "") | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Helper class for assertion related to extractions of [MediaFormat]s. | ||||
|      */ | ||||
|     class AssertionHelper<T : Stream>( | ||||
|         private val streams: List<T>, | ||||
|         private val wrapper: StreamInfoWrapper<T>, | ||||
|         private val retrieveMediaFormat: (stream: T, response: Response) -> Boolean | ||||
|     ) { | ||||
|  | ||||
|         /** | ||||
|          * Assert that an invalid response does not result in wrongly extracted [MediaFormat]. | ||||
|          */ | ||||
|         fun assertInvalidResponse( | ||||
|             response: Response, | ||||
|             index: Int | ||||
|         ) { | ||||
|             assertFalse( | ||||
|                 "invalid header returns valid value", retrieveMediaFormat(streams[index], response) | ||||
|             ) | ||||
|             assertNull("Media format extracted although stated otherwise", wrapper.getFormat(index)) | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * Assert that a valid response results in correctly extracted and handled [MediaFormat]. | ||||
|          */ | ||||
|         fun assertValidResponse( | ||||
|             response: Response, | ||||
|             index: Int, | ||||
|             format: MediaFormat | ||||
|         ) { | ||||
|             assertTrue( | ||||
|                 "header was not recognized", retrieveMediaFormat(streams[index], response) | ||||
|             ) | ||||
|             assertEquals("Wrong media format extracted", format, wrapper.getFormat(index)) | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import android.widget.TextView; | ||||
|  | ||||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.annotation.VisibleForTesting; | ||||
| import androidx.collection.SparseArrayCompat; | ||||
|  | ||||
| import org.schabi.newpipe.DownloaderImpl; | ||||
| @@ -298,7 +299,8 @@ public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseA | ||||
|          * @param response       the response of the head request for the given stream | ||||
|          * @return {@code true} if the media format could be retrieved; {@code false} otherwise | ||||
|          */ | ||||
|         private static <X extends Stream> boolean retrieveMediaFormat( | ||||
|         @VisibleForTesting | ||||
|         public static <X extends Stream> boolean retrieveMediaFormat( | ||||
|                 @NonNull final X stream, | ||||
|                 @NonNull final StreamInfoWrapper<X> streamsWrapper, | ||||
|                 @NonNull final Response response) { | ||||
| @@ -308,7 +310,8 @@ public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseA | ||||
|                     || retrieveMediaFormatFromContentTypeHeader(stream, streamsWrapper, response); | ||||
|         } | ||||
|  | ||||
|         private static <X extends Stream> boolean retrieveMediaFormatFromFileTypeHeaders( | ||||
|         @VisibleForTesting | ||||
|         public static <X extends Stream> boolean retrieveMediaFormatFromFileTypeHeaders( | ||||
|                 @NonNull final X stream, | ||||
|                 @NonNull final StreamInfoWrapper<X> streamsWrapper, | ||||
|                 @NonNull final Response response) { | ||||
| @@ -342,6 +345,7 @@ public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseA | ||||
|          * otherwise {@code false} | ||||
|          * @param <X> | ||||
|          */ | ||||
|         @VisibleForTesting | ||||
|         public static <X extends Stream> boolean retrieveMediaFormatFromContentDispositionHeader( | ||||
|                 @NonNull final X stream, | ||||
|                 @NonNull final StreamInfoWrapper<X> streamsWrapper, | ||||
| @@ -391,7 +395,8 @@ public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseA | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         private static <X extends Stream> boolean retrieveMediaFormatFromContentTypeHeader( | ||||
|         @VisibleForTesting | ||||
|         public static <X extends Stream> boolean retrieveMediaFormatFromContentTypeHeader( | ||||
|                 @NonNull final X stream, | ||||
|                 @NonNull final StreamInfoWrapper<X> streamsWrapper, | ||||
|                 @NonNull final Response response) { | ||||
| @@ -416,7 +421,8 @@ public class StreamItemAdapter<T extends Stream, U extends Stream> extends BaseA | ||||
|         public void resetInfo() { | ||||
|             Arrays.fill(streamSizes, SIZE_UNSET); | ||||
|             for (int i = 0; i < streamsList.size(); i++) { | ||||
|                 streamFormats[i] = streamsList.get(i).getFormat(); | ||||
|                 streamFormats[i] = streamsList.get(i) == null // test for invalid streams | ||||
|                         ? null : streamsList.get(i).getFormat(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 TobiGr
					TobiGr