Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests to pillarbox-player #432

Merged
merged 6 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ kotlinx-serialization = "1.6.2"
ktor = "2.3.7"
mockk = "1.13.9"
okhttp = "4.12.0"
robolectric = "4.11"
robolectric = "4.11.1"
srg-data-provider = "0.8.0"
tag-commander-core = "5.4.2"
tag-commander-server-side = "5.5.2"
Expand All @@ -58,7 +58,7 @@ androidx-navigation-runtime = { module = "androidx.navigation:navigation-runtime
androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "androidx-navigation" }
androidx-paging-common = { module = "androidx.paging:paging-common", version.ref = "androidx-paging" }
androidx-paging-compose = { module = "androidx.paging:paging-compose", version.ref = "androidx-paging" }
androidx-test-core = { module = "androidx.test:core-ktx", version.ref = "androidx-test-core" }
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" }
Expand All @@ -78,6 +78,8 @@ ktor-serialization = { module = "io.ktor:ktor-serialization", version.ref = "kto
ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-utils = { module = "io.ktor:ktor-utils", version.ref = "ktor" }
robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }
robolectric-annotations = { module = "org.robolectric:annotations", version.ref = "robolectric" }
robolectric-shadows-framework = { module = "org.robolectric:shadows-framework", version.ref = "robolectric" }
srg-data = { module = "ch.srg.data.provider:data", version.ref = "srg-data-provider" }
srg-dataprovider-paging = { module = "ch.srg.data.provider:dataprovider-paging", version.ref = "srg-data-provider" }
srg-dataprovider-retrofit = { module = "ch.srg.data.provider:dataprovider-retrofit", version.ref = "srg-data-provider" }
Expand Down Expand Up @@ -125,7 +127,6 @@ androidx-compose-runtime = { module = "androidx.compose.runtime:runtime" }
androidx-compose-runtime-saveable = { module = "androidx.compose.runtime:runtime-saveable" }
leanback = { group = "androidx.leanback", name = "leanback", version.ref = "androidx-leanback" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-ext-junit" }
androidx-test-ext-junit-ktx = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidx-test-ext-junit" }
guava = { module = "com.google.guava:guava", version.ref = "guava" }
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }

Expand Down
6 changes: 4 additions & 2 deletions pillarbox-analytics/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,17 @@ dependencies {
api(libs.tagcommander.serverside)

testImplementation(libs.androidx.test.core)
testImplementation(libs.androidx.test.ext.junit.ktx)
testImplementation(libs.androidx.test.ext.junit)
testImplementation(libs.json) {
because("The 'org.json' package is included in the Android SDK. Adding this dependency allows us to not mock the Android SDK in unit tests.")
}
testImplementation(libs.junit)
testImplementation(libs.kotlin.test)
testImplementation(libs.mockk)
testImplementation(libs.mockk.dsl)
testImplementation(libs.robolectric)
testRuntimeOnly(libs.robolectric)
testImplementation(libs.robolectric.annotations)
testImplementation(libs.robolectric.shadows.framework)
}

kover {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ package ch.srgssr.pillarbox.analytics.comscore

import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.util.Log
import ch.srgssr.pillarbox.analytics.AnalyticsConfig
import ch.srgssr.pillarbox.analytics.BuildConfig
Expand Down Expand Up @@ -49,14 +48,10 @@ internal object ComScoreSrg : ComScore {
val userConsentLabel = getUserConsentPair(config.userConsent.comScore)
persistentLabels[userConsentLabel.first] = userConsentLabel.second

val versionName: String = try {
// When unit testing from library packageInfo.versionName is null!
context.applicationContext.packageManager.getPackageInfo(context.applicationContext.packageName, 0).versionName
?: BuildConfig.VERSION_NAME
} catch (e: PackageManager.NameNotFoundException) {
Log.e("COMSCORE", "Cannot find package", e)
BuildConfig.VERSION_NAME
}
val applicationContext = context.applicationContext
val versionName: String = applicationContext.packageManager
.getPackageInfo(applicationContext.packageName, 0)
.versionName
persistentLabels[ComScoreLabel.MP_V.label] = versionName
persistentLabels[ComScoreLabel.MP_BRAND.label] = config.vendor.toString()
val publisher = PublisherConfiguration.Builder()
Expand All @@ -76,7 +71,7 @@ internal object ComScoreSrg : ComScore {
if (BuildConfig.DEBUG) {
Analytics.getConfiguration().enableImplementationValidationMode()
}
start(context.applicationContext)
start(applicationContext)
return this
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,26 @@ import com.comscore.Analytics
import io.mockk.mockkStatic
import io.mockk.unmockkAll
import org.junit.runner.RunWith
import org.robolectric.Shadows.shadowOf
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test

@RunWith(AndroidJUnit4::class)
class SRGAnalyticsSingletonTest {

private val config = AnalyticsConfig(
vendor = AnalyticsConfig.Vendor.SRG,
appSiteName = "pillarbox-test-android",
sourceKey = AnalyticsConfig.SOURCE_KEY_SRG_DEBUG
)

private lateinit var context: Context

@BeforeTest
fun setup() {
context = ApplicationProvider.getApplicationContext()
shadowOf(context.packageManager).getInternalMutablePackageInfo(context.packageName).versionName = "1.2.3"

mockkStatic(Analytics::class)
}

Expand All @@ -37,8 +42,8 @@ class SRGAnalyticsSingletonTest {

@Test(expected = IllegalArgumentException::class)
fun testInitTwice() {
val appContext: Context = ApplicationProvider.getApplicationContext()
SRGAnalytics.init(appContext as Application, config)
SRGAnalytics.init(appContext, config.copy(vendor = AnalyticsConfig.Vendor.RSI))
val application = context as Application
SRGAnalytics.init(application, config)
SRGAnalytics.init(application, config.copy(vendor = AnalyticsConfig.Vendor.RSI))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/
package ch.srgssr.pillarbox.analytics.comscore

import android.content.Context
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import ch.srgssr.pillarbox.analytics.AnalyticsConfig
Expand All @@ -16,23 +17,28 @@ import io.mockk.mockkStatic
import io.mockk.unmockkAll
import io.mockk.verify
import org.junit.runner.RunWith
import org.robolectric.Shadows.shadowOf
import kotlin.test.AfterTest
import kotlin.test.BeforeTest
import kotlin.test.Test

@RunWith(AndroidJUnit4::class)
class ComScoreSrgTest {

private val config = AnalyticsConfig(
vendor = AnalyticsConfig.Vendor.SRG,
appSiteName = "pillarbox-test-android",
sourceKey = AnalyticsConfig.SOURCE_KEY_SRG_DEBUG
)

private lateinit var context: Context

@BeforeTest
fun setup() {
context = ApplicationProvider.getApplicationContext()
shadowOf(context.packageManager).getInternalMutablePackageInfo(context.packageName).versionName = "1.2.3"

mockkStatic(Analytics::class)
ComScoreSrg.init(config = config, context = ApplicationProvider.getApplicationContext())
ComScoreSrg.init(config = config, context = context)
}

@AfterTest
Expand All @@ -42,7 +48,7 @@ class ComScoreSrgTest {

@Test(expected = IllegalArgumentException::class)
fun `init a second time with other config should throw exception`() {
ComScoreSrg.init(config = config.copy(vendor = AnalyticsConfig.Vendor.RTS), context = ApplicationProvider.getApplicationContext())
ComScoreSrg.init(config = config.copy(vendor = AnalyticsConfig.Vendor.RTS), context = context)
}

@Test
Expand Down
8 changes: 5 additions & 3 deletions pillarbox-core-business/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ android {
}
}
testOptions {
unitTests.isReturnDefaultValues = true
unitTests {
isIncludeAndroidResources = true
}
}
}

Expand Down Expand Up @@ -77,14 +79,14 @@ dependencies {
api(libs.tagcommander.core)

testImplementation(libs.androidx.test.core)
testImplementation(libs.androidx.test.ext.junit.ktx)
testImplementation(libs.androidx.test.ext.junit)
testImplementation(libs.junit)
testImplementation(libs.kotlin.test)
testImplementation(libs.kotlinx.coroutines.test)
testImplementation(libs.ktor.client.mock)
testImplementation(libs.mockk)
testImplementation(libs.mockk.dsl)
testImplementation(libs.robolectric)
testRuntimeOnly(libs.robolectric)

androidTestImplementation(project(":pillarbox-player-testutils"))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package ch.srgssr.pillarbox.core.business

import androidx.media3.common.MediaItem
import androidx.media3.common.MediaMetadata
import androidx.test.ext.junit.runners.AndroidJUnit4
import ch.srgssr.pillarbox.core.business.exception.BlockReasonException
import ch.srgssr.pillarbox.core.business.exception.ResourceNotFoundException
import ch.srgssr.pillarbox.core.business.integrationlayer.data.BlockReason
Expand All @@ -14,64 +15,61 @@ import ch.srgssr.pillarbox.core.business.integrationlayer.data.MediaComposition
import ch.srgssr.pillarbox.core.business.integrationlayer.data.Resource
import ch.srgssr.pillarbox.core.business.integrationlayer.data.Segment
import ch.srgssr.pillarbox.core.business.integrationlayer.service.MediaCompositionDataSource
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import org.junit.runner.RunWith
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

@RunWith(AndroidJUnit4::class)
class MediaCompositionMediaItemSourceTest {

private val mediaItemSource = MediaCompositionMediaItemSource(
mediaCompositionDataSource = DummyMediaCompositionProvider(),
)

@Test(expected = IllegalArgumentException::class)
fun testNoMediaId() = runBlocking {
fun testNoMediaId() = runTest {
mediaItemSource.loadMediaItem(MediaItem.Builder().build())
Unit
}

@Test(expected = IllegalArgumentException::class)
fun testInvalidMediaId() = runBlocking {
fun testInvalidMediaId() = runTest {
mediaItemSource.loadMediaItem(MediaItem.Builder().setMediaId("urn:rts:show:radio:1234").build())
Unit
}

@Test(expected = ResourceNotFoundException::class)
fun testNoResource() = runBlocking {
fun testNoResource() = runTest {
mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_NO_RESOURCES))
Unit
}

@Test(expected = ResourceNotFoundException::class)
fun testNoCompatibleResource() = runBlocking {
fun testNoCompatibleResource() = runTest {
mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_INCOMPATIBLE_RESOURCE))
Unit
}

@Test
fun testCompatibleResource() = runBlocking {
fun testCompatibleResource() = runTest {
val mediaItem = mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_HLS_RESOURCE))
assertNotNull(mediaItem)
Unit
}

@Test
fun testMetadata() = runBlocking {
fun testMetadata() = runTest {
val mediaItem = mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_METADATA))
assertNotNull(mediaItem)
val metadata = mediaItem.mediaMetadata
val expected = MediaMetadata.Builder()
.setTitle("Title")
.setSubtitle("Lead")
.setDescription("Description")
.setArtworkUri(metadata.artworkUri)
.build()
assertEquals(expected, metadata)
}

@Test
fun testWithCustomMetadata() = runBlocking {
fun testWithCustomMetadata() = runTest {
val input = MediaMetadata.Builder()
.setTitle("CustomTitle")
.setSubtitle("CustomSubtitle")
Expand All @@ -80,12 +78,14 @@ class MediaCompositionMediaItemSourceTest {
val mediaItem = mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_METADATA, input))
assertNotNull(mediaItem)
val metadata = mediaItem.mediaMetadata
val expected = input.buildUpon().build()
val expected = input.buildUpon()
.setArtworkUri(metadata.artworkUri)
.build()
assertEquals(expected, metadata)
}

@Test
fun testWithPartialCustomMetadata() = runBlocking {
fun testWithPartialCustomMetadata() = runTest {
val input = MediaMetadata.Builder()
.setTitle("CustomTitle")
.build()
Expand All @@ -96,22 +96,21 @@ class MediaCompositionMediaItemSourceTest {
.setTitle("CustomTitle")
.setSubtitle("Lead")
.setDescription("Description")
.setArtworkUri(metadata.artworkUri)
.build()
assertEquals(expected, metadata)
}

@Test(expected = BlockReasonException::class)
fun testBlockReason() = runBlocking {
fun testBlockReason() = runTest {
val input = MediaMetadata.Builder().build()
mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_BLOCK_REASON, input))
assertTrue(false)
}

@Test(expected = BlockReasonException::class)
fun testBlockedSegment() = runBlocking {
fun testBlockedSegment() = runTest {
val input = MediaMetadata.Builder().build()
mediaItemSource.loadMediaItem(createMediaItem(DummyMediaCompositionProvider.URN_SEGMENT_BLOCK_REASON, input))
assertTrue(false)
}

internal class DummyMediaCompositionProvider : MediaCompositionDataSource {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
package ch.srgssr.pillarbox.core.business

import androidx.core.net.toUri
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull

@RunWith(AndroidJUnit4::class)
class MediaItemUrnTest {
@Test
fun `MediaItemUrn with all parameters`() {
Expand Down
Loading
Loading