diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 940410a56..ed0e54247 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -158,6 +158,7 @@ jobs: android-tests: name: Android Tests runs-on: ubuntu-latest + if: ${{ false }} # TODO Remove this line if/when we have Android Tests needs: build env: USERNAME: ${{ github.actor }} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0c1306981..e6c6de425 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -17,7 +17,6 @@ androidx-paging = "3.3.0" androidx-test-core = "1.5.0" androidx-test-ext-junit = "1.1.5" androidx-test-monitor = "1.6.1" -androidx-test-runner = "1.5.2" androidx-tv-foundation = "1.0.0-alpha10" androidx-tv-material = "1.0.0-beta01" coil = "2.6.0" @@ -63,7 +62,6 @@ androidx-paging-common = { module = "androidx.paging:paging-common", version.ref androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "androidx-paging" } androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test-core" } androidx-test-monitor = { module = "androidx.test:monitor", version.ref = "androidx-test-monitor" } -androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidx-test-runner" } androidx-tv-foundation = { module = "androidx.tv:tv-foundation", version.ref = "androidx-tv-foundation" } androidx-tv-material = { module = "androidx.tv:tv-material", version.ref = "androidx-tv-material" } coil = { group = "io.coil-kt", name = "coil-compose", version.ref = "coil" } diff --git a/pillarbox-player/build.gradle.kts b/pillarbox-player/build.gradle.kts index fb81daf13..dd4746f49 100644 --- a/pillarbox-player/build.gradle.kts +++ b/pillarbox-player/build.gradle.kts @@ -14,16 +14,6 @@ android { buildFeatures { buildConfig = true } - - // Mockk includes some licenses information, which may conflict with other license files. This block merges all licenses together. - // Mockk excludes all licenses instead: - // https://github.com/mockk/mockk/blob/f879502a044c83c2a5fd52992f20903209eb34f3/modules/mockk-android/build.gradle.kts#L14-L19 - packaging { - resources { - merges += "META-INF/LICENSE.md" - merges += "META-INF/LICENSE-notice.md" - } - } } dependencies { @@ -54,14 +44,8 @@ dependencies { testImplementation(libs.kotlinx.coroutines.test) testImplementation(libs.mockk) testImplementation(libs.mockk.dsl) - testRuntimeOnly(libs.robolectric) + testImplementation(libs.robolectric) testImplementation(libs.robolectric.annotations) testImplementation(libs.robolectric.shadows.framework) testImplementation(libs.turbine) - - androidTestImplementation(libs.androidx.test.monitor) - androidTestRuntimeOnly(libs.androidx.test.runner) - androidTestImplementation(libs.junit) - androidTestRuntimeOnly(libs.kotlinx.coroutines.android) - androidTestImplementation(libs.mockk) } diff --git a/pillarbox-player/src/androidTest/java/ch/srgssr/pillarbox/player/IsPlayingAllTypeOfContentTest.kt b/pillarbox-player/src/androidTest/java/ch/srgssr/pillarbox/player/IsPlayingAllTypeOfContentTest.kt deleted file mode 100644 index ba2fcef21..000000000 --- a/pillarbox-player/src/androidTest/java/ch/srgssr/pillarbox/player/IsPlayingAllTypeOfContentTest.kt +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.player - -import android.net.Uri -import androidx.media3.common.MediaItem -import androidx.media3.common.PlaybackException -import androidx.media3.common.Player -import androidx.media3.common.util.ConditionVariable -import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation -import ch.srgssr.pillarbox.player.utils.ContentUrls -import org.junit.Assert -import org.junit.Test -import org.junit.runner.RunWith -import org.junit.runners.Parameterized -import java.util.concurrent.atomic.AtomicReference - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(Parameterized::class) -class IsPlayingAllTypeOfContentTest { - @Parameterized.Parameter - lateinit var urlToTest: String - - @Test - fun isPlayingTest() { - // Context of the app under test. - val appContext = getInstrumentation().targetContext - val atomicPlayer = AtomicReference() - val waitIsPlaying = WaitIsPlaying() - getInstrumentation().runOnMainSync { - val player = PillarboxExoPlayer( - appContext - ) - atomicPlayer.set(player) - player.addMediaItem(MediaItem.fromUri(urlToTest)) - player.addListener(waitIsPlaying) - player.prepare() - player.play() - } - - waitIsPlaying.block() - - getInstrumentation().runOnMainSync { - val player = atomicPlayer.get() - // Make test flaky because dependant of internet - if (player.playerError != null) { - throw Exception(player.playerError) - } - Assert.assertEquals(Player.STATE_READY, player.playbackState) - Assert.assertTrue(player.isPlaying) - Assert.assertNotNull(player.currentMediaItem) - Assert.assertEquals(player.currentMediaItem?.localConfiguration?.uri, Uri.parse(urlToTest)) - player.release() - } - } - - private class WaitIsPlaying : Player.Listener { - private val isPlaying = ConditionVariable() - - override fun onIsPlayingChanged(isPlaying: Boolean) { - if (isPlaying) { - this.isPlaying.open() - } - } - - /** - * Don't block test if a player error occurred - * @param error - */ - override fun onPlayerError(error: PlaybackException) { - isPlaying.open() - } - - fun block() { - isPlaying.block() - } - } - - companion object { - @Parameterized.Parameters(name = "{0}") - @JvmStatic - fun parameters(): Iterable { - return listOf( - ContentUrls.VOD_MP4, - ContentUrls.VOD_HLS, - ContentUrls.AOD_MP3, - ContentUrls.VOD_DASH_H264, - ContentUrls.VOD_DASH_H265, - ContentUrls.LIVE_HLS, - ContentUrls.LIVE_DVR_HLS, - ContentUrls.AUDIO_LIVE_DVR_HLS, - ContentUrls.AUDIO_LIVE_MP3 - ) - } - } -} diff --git a/pillarbox-player/src/androidTest/java/ch/srgssr/pillarbox/player/utils/ContentUrls.kt b/pillarbox-player/src/androidTest/java/ch/srgssr/pillarbox/player/utils/ContentUrls.kt deleted file mode 100644 index 9f4e70b82..000000000 --- a/pillarbox-player/src/androidTest/java/ch/srgssr/pillarbox/player/utils/ContentUrls.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) SRG SSR. All rights reserved. - * License information is available from the LICENSE file. - */ -package ch.srgssr.pillarbox.player.utils - -object ContentUrls { - const val VOD_HLS = "https://rts-vod-amd.akamaized.net/ww/14970442/7510ee63-05a4-3d48-8d26-1f1b3a82f6be/master.m3u8" - // From urn:swi:video:48940210 - const val VOD_MP4 = "https://cdn.prod.swi-services.ch/video-projects/141b30ce-3850-424b-9063-a20d5619d342/localised-videos/ENG/renditions/ENG.mp4" - const val VOD_DASH_H264 = "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd" - const val VOD_DASH_H265 = "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears.mpd" - const val LIVE_HLS = "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8?dw=0" - const val LIVE_DVR_HLS = "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8" - const val AOD_MP3 = "https://srfaudio-a.akamaihd.net/delivery/world/af671f12-6f17-415a-9dd8-b8aee24cce8b.mp3" - const val AUDIO_LIVE_MP3 = "https://stream.srg-ssr.ch/m/la-1ere/mp3_128" - const val AUDIO_LIVE_DVR_HLS = "https://lsaplus.swisstxt.ch/audio/couleur3_96.stream/playlist.m3u8" -} diff --git a/pillarbox-player/src/test/java/ch/srgssr/pillarbox/player/IsPlayingAllTypeOfContentTest.kt b/pillarbox-player/src/test/java/ch/srgssr/pillarbox/player/IsPlayingAllTypeOfContentTest.kt new file mode 100644 index 000000000..edb635fd2 --- /dev/null +++ b/pillarbox-player/src/test/java/ch/srgssr/pillarbox/player/IsPlayingAllTypeOfContentTest.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) SRG SSR. All rights reserved. + * License information is available from the LICENSE file. + */ +package ch.srgssr.pillarbox.player + +import android.net.Uri +import android.os.Looper +import androidx.media3.common.MediaItem +import androidx.media3.common.Player +import androidx.media3.test.utils.FakeClock +import androidx.media3.test.utils.robolectric.TestPlayerRunHelper +import androidx.test.core.app.ApplicationProvider +import org.junit.runner.RunWith +import org.robolectric.ParameterizedRobolectricTestRunner +import org.robolectric.ParameterizedRobolectricTestRunner.Parameters +import org.robolectric.Shadows.shadowOf +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +@RunWith(ParameterizedRobolectricTestRunner::class) +class IsPlayingAllTypeOfContentTest( + private val urlToTest: String +) { + private lateinit var player: PillarboxExoPlayer + + @BeforeTest + fun setUp() { + player = PillarboxExoPlayer( + context = ApplicationProvider.getApplicationContext(), + clock = FakeClock(true), + ) + } + + @AfterTest + fun tearDown() { + player.release() + + shadowOf(Looper.getMainLooper()).idle() + } + + @Test + fun `is playing`() { + player.addMediaItem(MediaItem.fromUri(urlToTest)) + player.prepare() + player.play() + + TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY) + + // Make test flaky because dependant of internet + if (player.playerError != null) { + throw IllegalStateException(player.playerError) + } + + assertEquals(Player.STATE_READY, player.playbackState) + assertTrue(player.isPlaying) + assertNotNull(player.currentMediaItem) + assertEquals(player.currentMediaItem?.localConfiguration?.uri, Uri.parse(urlToTest)) + } + + companion object { + // From urn:swi:video:48940210 + private const val VOD_MP4 = + "https://cdn.prod.swi-services.ch/video-projects/141b30ce-3850-424b-9063-a20d5619d342/localised-videos/ENG/renditions/ENG.mp4" + private const val VOD_HLS = "https://rts-vod-amd.akamaized.net/ww/14970442/7510ee63-05a4-3d48-8d26-1f1b3a82f6be/master.m3u8" + private const val AOD_MP3 = "https://srfaudio-a.akamaihd.net/delivery/world/af671f12-6f17-415a-9dd8-b8aee24cce8b.mp3" + private const val VOD_DASH_H264 = "https://storage.googleapis.com/wvmedia/clear/h264/tears/tears.mpd" + private const val VOD_DASH_H265 = "https://storage.googleapis.com/wvmedia/clear/hevc/tears/tears.mpd" + private const val LIVE_HLS = "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8?dw=0" + private const val LIVE_DVR_HLS = "https://rtsc3video.akamaized.net/hls/live/2042837/c3video/3/playlist.m3u8" + private const val AUDIO_LIVE_MP3 = "https://stream.srg-ssr.ch/m/la-1ere/mp3_128" + private const val AUDIO_LIVE_DVR_HLS = "https://lsaplus.swisstxt.ch/audio/couleur3_96.stream/playlist.m3u8" + + @JvmStatic + @Suppress("unused") + @Parameters(name = "{index}: {0}") + fun parameters(): Iterable { + return listOf( + VOD_MP4, + VOD_HLS, + AOD_MP3, + VOD_DASH_H264, + VOD_DASH_H265, + LIVE_HLS, + LIVE_DVR_HLS, + AUDIO_LIVE_MP3, + AUDIO_LIVE_DVR_HLS, + ) + } + } +}