Skip to content

Commit

Permalink
Multiplex tests based on MediaProduct arguments via @parameterized
Browse files Browse the repository at this point in the history
This reduces the code required per test. However, since some tests require a
single MediaProduct while others require 2, I have refactored the current class
to be specific to the former (since all of its current tests only use a single
MediaProduct) and then we can have another class for the tests that will use
two MediaProducts to avoid worthless (repeated) test runs.
  • Loading branch information
stoyicker committed Jun 25, 2024
1 parent 9ca5200 commit def2001
Showing 1 changed file with 34 additions and 89 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import com.tidal.sdk.player.events.reflectionComponentFactoryF
import com.tidal.sdk.player.playbackengine.model.Event
import com.tidal.sdk.player.playbackengine.model.Event.MediaProductEnded
import com.tidal.sdk.player.setBodyFromFile
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
Expand All @@ -53,15 +51,20 @@ import org.junit.Before
import org.junit.BeforeClass
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import org.mockito.Mockito.atMost
import org.mockito.Mockito.mock
import org.mockito.Mockito.verifyNoMoreInteractions
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.argThat
import org.mockito.kotlin.eq
import org.mockito.kotlin.verify
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds

class PlayLogTest {
@RunWith(Parameterized::class)
internal class SingleMediaProductPlayLogTest(private val mediaProduct: MediaProduct) {

@get:Rule
val server = MockWebServer()
Expand All @@ -74,6 +77,16 @@ class PlayLogTest {

@Before
fun setUp() {
responseDispatcher[
"https://api.tidal.com/v1/tracks/${mediaProduct.productId}/playbackinfo?playbackmode=STREAM&assetpresentation=FULL&audioquality=LOW&immersiveaudio=true".toHttpUrl(),
] = {
MockResponse().setBodyFromFile(
"api-responses/playbackinfo/tracks/playlogtest/get_1_bts.json",
)
}
responseDispatcher["https://test.audio.tidal.com/1_bts.m4a".toHttpUrl()] = {
MockResponse().setBodyFromFile("raw/playlogtest/1_bts.m4a")
}
EventReporterModuleRoot.reflectionComponentFactoryF = {
PlayLogTestDefaultEventReporterComponentFactory(eventReporterCoroutineScope)
}
Expand Down Expand Up @@ -118,13 +131,23 @@ class PlayLogTest {
companion object {
private lateinit var originalEventReporterComponentFactoryF:
() -> DefaultEventReporterComponent.Factory
private const val MEDIA_PRODUCT_DURATION_SECONDS = 5.055

@BeforeClass
@JvmStatic
fun beforeAll() {
originalEventReporterComponentFactoryF =
EventReporterModuleRoot.reflectionComponentFactoryF
}

@JvmStatic
@Parameterized.Parameters
fun parameters() = setOf(
MediaProduct(ProductType.TRACK, "1", "TESTA", "456"),
MediaProduct(ProductType.TRACK, "1", null, "789"),
MediaProduct(ProductType.TRACK, "1", "TESTB", null),
MediaProduct(ProductType.TRACK, "1", null, null),
)
}

@After
Expand All @@ -143,33 +166,7 @@ class PlayLogTest {
}

@Test
fun loadAndPlayUntilEndNoNulls() =
loadAndPlayUntilEnd(MediaProduct(ProductType.TRACK, "1", "TESTA", "456"))

@Test
fun loadAndPlayUntilEndNullSourceType() =
loadAndPlayUntilEnd(MediaProduct(ProductType.TRACK, "1", null, "789"))

@Test
fun loadAndPlayUntilEndNullSourceId() =
loadAndPlayUntilEnd(MediaProduct(ProductType.TRACK, "1", "TESTB", null))

@Test
fun loadAndPlayUntilEndNullSourceTypeNullSourceId() =
loadAndPlayUntilEnd(MediaProduct(ProductType.TRACK, "1", null, null))

private fun loadAndPlayUntilEnd(mediaProduct: MediaProduct) = runTest {
responseDispatcher[
"https://api.tidal.com/v1/tracks/1/playbackinfo?playbackmode=STREAM&assetpresentation=FULL&audioquality=LOW&immersiveaudio=true".toHttpUrl(),
] = {
MockResponse().setBodyFromFile(
"api-responses/playbackinfo/tracks/playlogtest/get_1_bts.json"
)
}
responseDispatcher["https://test.audio.tidal.com/1_bts.m4a".toHttpUrl()] = {
MockResponse().setBodyFromFile("raw/playlogtest/1_bts.m4a")
}

fun loadAndPlayUntilEnd() = runTest {
player.playbackEngine.load(mediaProduct)
player.playbackEngine.play()
withContext(Dispatchers.Default.limitedParallelism(1)) {
Expand All @@ -188,7 +185,7 @@ class PlayLogTest {
assertThat(get("startAssetPosition").asDouble).isAssetPositionEqualTo(0.0)
// https://github.com/androidx/media/issues/1253
assertThat(get("endAssetPosition").asDouble)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_1_SECONDS)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS)
assertThat(get("actualProductId").asString).isEqualTo(mediaProduct.productId)
assertThat(get("sourceType")?.asString).isEqualTo(mediaProduct.sourceType)
assertThat(get("sourceId")?.asString).isEqualTo(mediaProduct.sourceId)
Expand All @@ -200,35 +197,10 @@ class PlayLogTest {
)
}

@Test
fun loadAndPlayThenPauseThenPlayNoNulls() =
loadAndPlayThenPauseThenPlay(MediaProduct(ProductType.TRACK, "1", "TESTA", "456"))

@Test
fun loadAndPlayThenPauseThenPlayNullSourceType() =
loadAndPlayThenPauseThenPlay(MediaProduct(ProductType.TRACK, "1", null, "789"))

@Test
fun loadAndPlayThenPauseThenPlayNullSourceId() =
loadAndPlayThenPauseThenPlay(MediaProduct(ProductType.TRACK, "1", "TESTB", null))

@Test
fun loadAndPlayThenPauseThenPlayNullSourceTypeNullSourceId() =
loadAndPlayThenPauseThenPlay(MediaProduct(ProductType.TRACK, "1", null, null))

@Suppress("LongMethod")
private fun loadAndPlayThenPauseThenPlay(mediaProduct: MediaProduct) = runTest {
@Test
fun loadAndPlayThenPauseThenPlay() = runTest {
val gson = Gson()
responseDispatcher[
"https://api.tidal.com/v1/tracks/1/playbackinfo?playbackmode=STREAM&assetpresentation=FULL&audioquality=LOW&immersiveaudio=true".toHttpUrl(),
] = {
MockResponse().setBodyFromFile(
"api-responses/playbackinfo/tracks/playlogtest/get_1_bts.json",
)
}
responseDispatcher["https://test.audio.tidal.com/1_bts.m4a".toHttpUrl()] = {
MockResponse().setBodyFromFile("raw/playlogtest/1_bts.m4a")
}

player.playbackEngine.load(mediaProduct)
player.playbackEngine.play()
Expand Down Expand Up @@ -256,7 +228,7 @@ class PlayLogTest {
with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) {
assertThat(get("startAssetPosition").asDouble).isAssetPositionEqualTo(0.0)
assertThat(get("endAssetPosition").asDouble)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_1_SECONDS)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS)
assertThat(get("actualProductId").asString).isEqualTo(mediaProduct.productId)
assertThat(get("sourceType")?.asString).isEqualTo(mediaProduct.sourceType)
assertThat(get("sourceId")?.asString).isEqualTo(mediaProduct.sourceId)
Expand Down Expand Up @@ -285,35 +257,10 @@ class PlayLogTest {
)
}

@Test
fun loadAndPlayThenSeekForwardNoNulls() =
loadAndPlayThenSeekForward(MediaProduct(ProductType.TRACK, "1", "TESTA", "456"))

@Test
fun loadAndPlayThenSeekForwardNullSourceType() =
loadAndPlayThenSeekForward(MediaProduct(ProductType.TRACK, "1", null, "789"))

@Test
fun loadAndPlayThenSeekForwardNullSourceId() =
loadAndPlayThenSeekForward(MediaProduct(ProductType.TRACK, "1", "TESTB", null))

@Test
fun loadAndPlayThenSeekForwardNullSourceTypeNullSourceId() =
loadAndPlayThenSeekForward(MediaProduct(ProductType.TRACK, "1", null, null))

@Suppress("LongMethod")
private fun loadAndPlayThenSeekForward(mediaProduct: MediaProduct) = runTest {
@Test
fun loadAndPlayThenSeekForward() = runTest {
val gson = Gson()
responseDispatcher[
"https://api.tidal.com/v1/tracks/1/playbackinfo?playbackmode=STREAM&assetpresentation=FULL&audioquality=LOW&immersiveaudio=true".toHttpUrl(),
] = {
MockResponse().setBodyFromFile(
"api-responses/playbackinfo/tracks/playlogtest/get_1_bts.json",
)
}
responseDispatcher["https://test.audio.tidal.com/1_bts.m4a".toHttpUrl()] = {
MockResponse().setBodyFromFile("raw/playlogtest/1_bts.m4a")
}

player.playbackEngine.load(mediaProduct)
player.playbackEngine.play()
Expand All @@ -339,7 +286,7 @@ class PlayLogTest {
with(gson.fromJson(this, JsonObject::class.java)["payload"].asJsonObject) {
assertThat(get("startAssetPosition").asDouble).isAssetPositionEqualTo(0.0)
assertThat(get("endAssetPosition").asDouble)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_1_SECONDS)
.isAssetPositionEqualTo(MEDIA_PRODUCT_DURATION_SECONDS)
assertThat(get("actualProductId").asString).isEqualTo(mediaProduct.productId)
assertThat(get("sourceType")?.asString).isEqualTo(mediaProduct.sourceType)
assertThat(get("sourceId")?.asString).isEqualTo(mediaProduct.sourceId)
Expand Down Expand Up @@ -369,5 +316,3 @@ class PlayLogTest {
isCloseTo(targetPosition, 0.5)
}
}

private const val MEDIA_PRODUCT_DURATION_1_SECONDS = 5.055

0 comments on commit def2001

Please sign in to comment.