@@ -825,6 +825,76 @@ internal class SingleMediaProductPlayLogTest {
825825 eq(emptyMap()),
826826 )
827827 }
828+
829+ @Suppress(" CyclomaticComplexMethod" , " LongMethod" )
830+ @Test
831+ fun seekBeyondBoundsWithRepeatOne () = runTest {
832+ val gson = Gson ()
833+
834+ player.playbackEngine.load(mediaProduct)
835+ player.playbackEngine.setRepeatOne(true )
836+ player.playbackEngine.play()
837+ withContext(Dispatchers .Default .limitedParallelism(1 )) {
838+ delay(2 .seconds)
839+ while (player.playbackEngine.assetPosition < 2 ) {
840+ delay(10 .milliseconds)
841+ }
842+ player.playbackEngine.seek(10_000F )
843+ delay(1 .seconds)
844+ while (player.playbackEngine.assetPosition < 1 ) {
845+ delay(10 .milliseconds)
846+ }
847+ player.playbackEngine.reset()
848+ }
849+
850+ eventReporterCoroutineScope.advanceUntilIdle()
851+ verify(eventSender).sendEvent(
852+ eq(" playback_session" ),
853+ eq(ConsentCategory .NECESSARY ),
854+ argThat {
855+ with (gson.fromJson(this , JsonObject ::class .java)[" payload" ].asJsonObject) {
856+ get(" startAssetPosition" ).asDouble.isAssetPositionEqualTo(0.0 ) &&
857+ get(" endAssetPosition" ).asDouble
858+ .isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS ) &&
859+ get(" actualProductId" )?.asString.contentEquals(mediaProduct.productId) &&
860+ get(" sourceType" )?.asString.contentEquals(mediaProduct.sourceType) &&
861+ get(" sourceId" )?.asString.contentEquals(mediaProduct.sourceId) &&
862+ get(" actions" ).asJsonArray.run {
863+ val stopAction =
864+ gson.fromJson(this [0 ], PlaybackSession .Payload .Action ::class .java)
865+ val startAction =
866+ gson.fromJson(this [1 ], PlaybackSession .Payload .Action ::class .java)
867+ val perfectResumeTimestamp = stopAction.timestamp
868+ stopAction.actionType ==
869+ PlaybackSession .Payload .Action .Type .PLAYBACK_STOP &&
870+ stopAction.assetPositionSeconds.isAssetPositionEqualTo(2.0 ) &&
871+ startAction.actionType ==
872+ PlaybackSession .Payload .Action .Type .PLAYBACK_START &&
873+ startAction.assetPositionSeconds
874+ .isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS ) &&
875+ startAction.timestamp in
876+ (perfectResumeTimestamp - 500 ).. (perfectResumeTimestamp + 500 )
877+ }
878+ }
879+ },
880+ eq(emptyMap()),
881+ )
882+ verify(eventSender).sendEvent(
883+ eq(" playback_session" ),
884+ eq(ConsentCategory .NECESSARY ),
885+ argThat {
886+ with (gson.fromJson(this , JsonObject ::class .java)[" payload" ].asJsonObject) {
887+ get(" startAssetPosition" ).asDouble.isAssetPositionEqualTo(0.0 ) &&
888+ get(" endAssetPosition" ).asDouble.isAssetPositionEqualTo(1.0 ) &&
889+ get(" actualProductId" )?.asString.contentEquals(mediaProduct.productId) &&
890+ get(" sourceType" )?.asString.contentEquals(mediaProduct.sourceType) &&
891+ get(" sourceId" )?.asString.contentEquals(mediaProduct.sourceId) &&
892+ get(" actions" ).asJsonArray.isEmpty
893+ }
894+ },
895+ eq(emptyMap()),
896+ )
897+ }
828898}
829899
830900private const val MEDIA_PRODUCT_DURATION_SECONDS = 5.055
0 commit comments