From c31a4ea8f0b12586ac4152d52e0f86216c4b7822 Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Fri, 28 Jun 2024 13:33:38 +0200 Subject: [PATCH] Add PlayLog test 21 --- .../playlog/TwoMediaProductsPlayLogTest.kt | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/player/src/androidTest/kotlin/com/tidal/sdk/player/playlog/TwoMediaProductsPlayLogTest.kt b/player/src/androidTest/kotlin/com/tidal/sdk/player/playlog/TwoMediaProductsPlayLogTest.kt index 8f378cbd..26fc8c33 100644 --- a/player/src/androidTest/kotlin/com/tidal/sdk/player/playlog/TwoMediaProductsPlayLogTest.kt +++ b/player/src/androidTest/kotlin/com/tidal/sdk/player/playlog/TwoMediaProductsPlayLogTest.kt @@ -25,6 +25,7 @@ import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect @@ -522,4 +523,143 @@ internal class TwoMediaProductsPlayLogTest { eq(emptyMap()), ) } + + @Suppress("CyclomaticComplexMethod", "LongMethod") + @Test + fun playAndDoALot() = runTest { + val gson = Gson() + + player.playbackEngine.load(mediaProduct1) + player.playbackEngine.play() + withContext(Dispatchers.Default.limitedParallelism(1)) { + withTimeout(4.seconds) { + player.playbackEngine.events.filter { it is Event.MediaProductTransition }.first() + } + delay(2.seconds) + while (player.playbackEngine.assetPosition < 2) { + delay(10.milliseconds) + } + player.playbackEngine.pause() + player.playbackEngine.seek(3_000F) + player.playbackEngine.play() + player.playbackEngine.setNext(mediaProduct2) + player.playbackEngine.pause() + player.playbackEngine.play() + delay(2.seconds) + while (player.playbackEngine.assetPosition < 4) { + delay(10.milliseconds) + } + withTimeout(4.seconds) { + val waitJob = async { + player.playbackEngine.events + .filter { it is Event.MediaProductTransition } + .first() + } + player.playbackEngine.skipToNext() + waitJob.await() + } + player.playbackEngine.seek(58_000F) + player.playbackEngine.setRepeatOne(true) + withTimeout(4.seconds) { + player.playbackEngine.events.filter { it is Event.MediaProductTransition }.first() + } + delay(1.seconds) + while (player.playbackEngine.assetPosition < 1) { + delay(10.milliseconds) + } + player.playbackEngine.reset() + } + + eventReporterCoroutineScope.advanceUntilIdle() + verify(eventSender).sendEvent( + eq("playback_session"), + eq(ConsentCategory.NECESSARY), + argThat { + with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) { + get("startAssetPosition").asDouble.isAssetPositionEqualTo(0.0) && + get("endAssetPosition").asDouble.isAssetPositionEqualTo(4.0) && + get("actualProductId")?.asString.contentEquals(mediaProduct1.productId) && + get("sourceType")?.asString.contentEquals(mediaProduct1.sourceType) && + get("sourceId")?.asString.contentEquals(mediaProduct1.sourceId) && + get("actions").asJsonArray.run { + val firstStopAction = + gson.fromJson(this[0], PlaybackSession.Payload.Action::class.java) + val firstStartAction = + gson.fromJson(this[1], PlaybackSession.Payload.Action::class.java) + val perfectFirstResumeTimestamp = firstStopAction.timestamp + val secondStopAction = + gson.fromJson(this[2], PlaybackSession.Payload.Action::class.java) + val secondStartAction = + gson.fromJson(this[3], PlaybackSession.Payload.Action::class.java) + val perfectSecondResumeTimestamp = secondStopAction.timestamp + firstStopAction.actionType == + PlaybackSession.Payload.Action.Type.PLAYBACK_STOP && + firstStopAction.assetPositionSeconds.isAssetPositionEqualTo(2.0) && + firstStartAction.actionType == + PlaybackSession.Payload.Action.Type.PLAYBACK_START && + firstStartAction.assetPositionSeconds.isAssetPositionEqualTo(3.0) && + firstStartAction.timestamp in + (perfectFirstResumeTimestamp - 500).. + (perfectFirstResumeTimestamp + 500) && + secondStopAction.actionType == + PlaybackSession.Payload.Action.Type.PLAYBACK_STOP && + secondStopAction.assetPositionSeconds.isAssetPositionEqualTo(3.0) && + secondStartAction.actionType == + PlaybackSession.Payload.Action.Type.PLAYBACK_START && + secondStartAction.assetPositionSeconds + .isAssetPositionEqualTo(3.0) && + secondStartAction.timestamp in + (perfectSecondResumeTimestamp - 500).. + (perfectSecondResumeTimestamp + 500) + } + } + }, + eq(emptyMap()), + ) + verify(eventSender).sendEvent( + eq("playback_session"), + eq(ConsentCategory.NECESSARY), + argThat { + with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) { + get("startAssetPosition").asDouble.isAssetPositionEqualTo(0.0) && + get("endAssetPosition").asDouble + .isAssetPositionEqualTo(MEDIA_PRODUCT_2_DURATION_SECONDS) && + get("actualProductId")?.asString.contentEquals(mediaProduct2.productId) && + get("sourceType")?.asString.contentEquals(mediaProduct2.sourceType) && + get("sourceId")?.asString.contentEquals(mediaProduct2.sourceId) && + get("actions").asJsonArray.run { + val stopAction = + gson.fromJson(this[0], PlaybackSession.Payload.Action::class.java) + val startAction = + gson.fromJson(this[1], PlaybackSession.Payload.Action::class.java) + val perfectResumeTimestamp = stopAction.timestamp + stopAction.actionType == + PlaybackSession.Payload.Action.Type.PLAYBACK_STOP && + stopAction.assetPositionSeconds.isAssetPositionEqualTo(0.0) && + startAction.actionType == + PlaybackSession.Payload.Action.Type.PLAYBACK_START && + startAction.assetPositionSeconds.isAssetPositionEqualTo(58.0) && + startAction.timestamp in + (perfectResumeTimestamp - 500)..(perfectResumeTimestamp + 500) + } + } + }, + eq(emptyMap()), + ) + verify(eventSender).sendEvent( + eq("playback_session"), + eq(ConsentCategory.NECESSARY), + argThat { + with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) { + get("startAssetPosition").asDouble.isAssetPositionEqualTo(0.0) && + get("endAssetPosition").asDouble.isAssetPositionEqualTo(1.0) && + get("actualProductId")?.asString.contentEquals(mediaProduct2.productId) && + get("sourceType")?.asString.contentEquals(mediaProduct2.sourceType) && + get("sourceId")?.asString.contentEquals(mediaProduct2.sourceId) && + get("actions").asJsonArray.isEmpty + } + }, + eq(emptyMap()), + ) + } }