diff --git a/data/build.gradle.kts b/data/build.gradle.kts index fd604fb..62e6541 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -55,7 +55,7 @@ dependencies { api(libs.kotlinx.serialization.json) testRuntimeOnly(libs.robolectric) - testImplementation(libs.junit) + testImplementation(libs.kotlin.test) testImplementation(libs.androidx.test.ext.junit) } diff --git a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatio.kt b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatio.kt index 83fce62..2cf736f 100644 --- a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatio.kt +++ b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatio.kt @@ -24,9 +24,9 @@ data class AspectRatio(val numerator: Int, val denominator: Int) { fun parse(str: String): AspectRatio { val numeratorDenominatorString = str.split(SEPARATOR) require(numeratorDenominatorString.size == 2) { "Expected rational as numerator:denominator but is $str" } - val numerator = numeratorDenominatorString[0].toInt() val denominator = numeratorDenominatorString[1].toInt() if (denominator == 0) return Infinity + val numerator = numeratorDenominatorString[0].toInt() if (numerator == 0) return Zero return AspectRatio(numerator, denominator) } diff --git a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/Chapter.kt b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/Chapter.kt index 8b31859..8a787c4 100644 --- a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/Chapter.kt +++ b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/Chapter.kt @@ -114,11 +114,6 @@ data class Chapter( } fun doesHaveBlockedSegment(): Boolean { - for (segment in segmentList.orEmpty()) { - if (segment.isBlocked()) { - return true - } - } - return false + return segmentList.orEmpty().any { it.isBlocked() } } } diff --git a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResult.kt b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResult.kt index c791f78..4b315f5 100644 --- a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResult.kt +++ b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResult.kt @@ -13,14 +13,10 @@ abstract class ListResult : Iterable { abstract val next: String? val list: List - get() { - return data.orEmpty() - } + get() = data.orEmpty() val size: Int - get() { - return list.size - } + get() = list.size fun isEmpty(): Boolean { return data.isNullOrEmpty() diff --git a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/NowAndNext.kt b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/NowAndNext.kt index e8212df..450de62 100644 --- a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/NowAndNext.kt +++ b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/NowAndNext.kt @@ -27,5 +27,4 @@ data class NowAndNext( override val rawImageUrl: ImageUrl? = null, val now: Program? = null, val next: Program? = null -) : - SRGChannelMetadata +) : SRGChannelMetadata diff --git a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGTypes.kt b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGTypes.kt index ac0cb27..b82fc65 100644 --- a/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGTypes.kt +++ b/data/src/main/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGTypes.kt @@ -44,7 +44,7 @@ enum class BlockReason { companion object { fun parseValue(value: String): BlockReason { return try { - valueOf(value) + enumValueOf(value) } catch (e: IllegalArgumentException) { UNKNOWN } diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/DateParserTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/DateParserTest.kt index 8d1f949..31b07a2 100644 --- a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/DateParserTest.kt +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/DateParserTest.kt @@ -1,12 +1,12 @@ package ch.srg.dataProvider.integrationlayer.data import androidx.test.ext.junit.runners.AndroidJUnit4 -import org.junit.Assert -import org.junit.Ignore -import org.junit.Test import org.junit.runner.RunWith import java.text.ParseException import java.util.Date +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertEquals /** * [Testing Fundamentals](http://d.android.com/tools/testing/testing_android.html) @@ -18,9 +18,9 @@ class DateParserTest { @Test fun test8601() { val parser = ISO8601DateParser() - Assert.assertEquals(Date(1496126175000L), parser.parseDate("2017-05-30T08:36:15.079+02:00")) - Assert.assertEquals(Date(1496126175000L), parser.parseDate("2017-05-30T08:36:15+02:00")) - Assert.assertEquals(Date(1496126175000L), parser.parseDate("2017-05-30T06:36:15Z")) + assertEquals(Date(1496126175000L), parser.parseDate("2017-05-30T08:36:15.079+02:00")) + assertEquals(Date(1496126175000L), parser.parseDate("2017-05-30T08:36:15+02:00")) + assertEquals(Date(1496126175000L), parser.parseDate("2017-05-30T06:36:15Z")) } @Test(expected = ParseException::class) diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatioTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatioTest.kt new file mode 100644 index 0000000..166ff17 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/AspectRatioTest.kt @@ -0,0 +1,83 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +class AspectRatioTest { + @Test + fun parse() { + val aspectRatio = AspectRatio.parse("16:9") + + assertEquals(16, aspectRatio.numerator) + assertEquals(9, aspectRatio.denominator) + } + + @Test + fun `parse denominator 0`() { + val aspectRatio = AspectRatio.parse("16:0") + + assertEquals(AspectRatio.Infinity, aspectRatio) + } + + @Test + fun `parse numerator 0`() { + val aspectRatio = AspectRatio.parse("0:9") + + assertEquals(AspectRatio.Zero, aspectRatio) + } + + @Test(expected = IllegalArgumentException::class) + fun `parse empty string`() { + AspectRatio.parse("") + } + + @Test(expected = IllegalArgumentException::class) + fun `parse blank string`() { + AspectRatio.parse(" ") + } + + @Test(expected = IllegalArgumentException::class) + fun `parse invalid string`() { + AspectRatio.parse("hello") + } + + @Test(expected = IllegalArgumentException::class) + fun `parse string with invalid numerator`() { + AspectRatio.parse("abc:9") + } + + @Test(expected = IllegalArgumentException::class) + fun `parse string with invalid denominator`() { + AspectRatio.parse("16:abc") + } + + @Test(expected = IllegalArgumentException::class) + fun `parse string with too many separators`() { + AspectRatio.parse("1:2:3") + } + + @Test + fun `destruction check`() { + val aspectRatio = AspectRatio(16, 9) + val (numerator, denominator) = aspectRatio + + assertEquals(aspectRatio.numerator, numerator) + assertEquals(aspectRatio.denominator, denominator) + } + + @Test + fun `equals check`() { + assertEquals(AspectRatio.Infinity, AspectRatio(1, 0)) + assertEquals(AspectRatio.Zero, AspectRatio(0, 1)) + assertEquals(AspectRatio(16, 9), AspectRatio(16, 9)) + assertNotEquals(AspectRatio(4, 3), AspectRatio(16, 9)) + } + + @Test + fun `toString format check`() { + assertEquals("1:0", AspectRatio.Infinity.toString()) + assertEquals("0:1", AspectRatio.Zero.toString()) + assertEquals("16:9", AspectRatio(16, 9).toString()) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/BlockReasonTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/BlockReasonTest.kt new file mode 100644 index 0000000..e1ad9c2 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/BlockReasonTest.kt @@ -0,0 +1,20 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import kotlin.test.Test +import kotlin.test.assertEquals + +class BlockReasonTest { + @Test + fun `parse value`() { + assertEquals(BlockReason.UNKNOWN, BlockReason.parseValue("")) + assertEquals(BlockReason.UNKNOWN, BlockReason.parseValue("INVALID_REASON")) + + BlockReason.entries.forEach { blockReason -> + assertEquals(blockReason, BlockReason.parseValue(blockReason.name)) + } + + BlockReason.entries.forEach { blockReason -> + assertEquals(BlockReason.UNKNOWN, BlockReason.parseValue(blockReason.name.lowercase())) + } + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ChapterTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ChapterTest.kt new file mode 100644 index 0000000..e1332b3 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ChapterTest.kt @@ -0,0 +1,144 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import java.util.Date +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.minutes + +class ChapterTest { + @Test + fun `find segment with null segment list`() { + val chapter = createChapter(segmentList = null) + + assertNull(chapter.findSegment("urn:rts:video:123456")) + } + + @Test + fun `find segment with empty segment list`() { + val chapter = createChapter(segmentList = emptyList()) + + assertNull(chapter.findSegment("urn:rts:video:123456")) + } + + @Test + fun `find segment with segment list`() { + val segment = createSegment(SEGMENT_URN) + val chapter = createChapter(segmentList = listOf(createSegment("urn:rts:video:987654"), segment)) + + assertNull(chapter.findSegment("urn:rts:video:123456")) + assertEquals(segment, chapter.findSegment(SEGMENT_URN)) + } + + @Test + fun `find 360 resource with null resource list`() { + val chapter = createChapter(resourceList = null) + + assertNull(chapter.find360Resource()) + assertFalse(chapter.is360()) + } + + @Test + fun `find 360 resource with empty resource list`() { + val chapter = createChapter(resourceList = emptyList()) + + assertNull(chapter.find360Resource()) + assertFalse(chapter.is360()) + } + + @Test + fun `find 360 resource without 360 resource in resource list`() { + val chapter = createChapter(resourceList = listOf(createResource(), createResource())) + + assertNull(chapter.find360Resource()) + assertFalse(chapter.is360()) + } + + @Test + fun `find 360 resource with 360 resource in resource list`() { + val resource = createResource(presentation = Presentation.VIDEO_360) + val chapter = createChapter(resourceList = listOf(createResource(), resource)) + + assertEquals(resource, chapter.find360Resource()) + assertTrue(chapter.is360()) + } + + @Test + fun `does have blocked segment with null segment list`() { + val chapter = createChapter(segmentList = null) + + assertFalse(chapter.doesHaveBlockedSegment()) + } + + @Test + fun `does have blocked segment with empty segment list`() { + val chapter = createChapter(segmentList = emptyList()) + + assertFalse(chapter.doesHaveBlockedSegment()) + } + + @Test + fun `does have blocked segment with segment list`() { + val segment = createSegment(SEGMENT_URN, blocked = true) + val chapter = createChapter(segmentList = listOf(createSegment("urn:rts:video:987654"), segment)) + + assertTrue(chapter.doesHaveBlockedSegment()) + } + + private companion object { + private const val SEGMENT_URN = "urn:rts:video:456789" + + private fun createChapter( + segmentList: List? = null, + resourceList: List? = null, + ): Chapter { + return Chapter( + id = "chapter-id", + mediaType = MediaType.VIDEO, + vendor = Vendor.RTS, + urn = "urn:rts:video:123456", + title = "chapter-title", + imageUrl = ImageUrl("https://image.url"), + type = Type.EPISODE, + date = Date(), + duration = 90.minutes.inWholeMilliseconds, + segmentList = segmentList, + resourceList = resourceList, + ) + } + + private fun createSegment( + urn: String, + blocked: Boolean = false, + ): Segment { + return Segment( + id = "segment-id", + mediaType = MediaType.VIDEO, + vendor = Vendor.RTS, + urn = urn, + title = "segment-title", + markIn = 0L, + markOut = 0L, + type = Type.CLIP, + date = Date(), + duration = 30.minutes.inWholeMilliseconds, + displayable = true, + playableAbroad = true, + imageUrl = ImageUrl("https://image.url"), + blockReason = BlockReason.LEGAL.takeIf { blocked }, + ) + } + + private fun createResource(presentation: Presentation = Presentation.DEFAULT): Resource { + return Resource( + url = "https://resource.url", + quality = Quality.HD, + presentation = presentation, + streamingMethod = StreamingMethod.DASH, + ) + } + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResultTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResultTest.kt new file mode 100644 index 0000000..5e165a0 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ListResultTest.kt @@ -0,0 +1,73 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class ListResultTest { + @Test + fun `list result null data`() { + val listResult = StringListResult(data = null) + + assertEquals(emptyList(), listResult.list) + assertEquals(0, listResult.size) + assertTrue(listResult.isEmpty()) + assertFalse(listResult.contains("")) + assertFalse(listResult.contains("c")) + assertTrue(listResult.containsAll(emptyList())) + assertFalse(listResult.containsAll(listOf("b", "d"))) + assertNotNull(listResult.iterator()) + } + + @Test(expected = IndexOutOfBoundsException::class) + fun `list result null data with get item`() { + val listResult = StringListResult(data = null) + + listResult[0] + } + + @Test + fun `list result empty data`() { + val listResult = StringListResult(data = emptyList()) + + assertEquals(emptyList(), listResult.list) + assertEquals(0, listResult.size) + assertTrue(listResult.isEmpty()) + assertFalse(listResult.contains("")) + assertFalse(listResult.contains("c")) + assertTrue(listResult.containsAll(emptyList())) + assertFalse(listResult.containsAll(listOf("b", "d"))) + assertNotNull(listResult.iterator()) + } + + @Test(expected = IndexOutOfBoundsException::class) + fun `list result empty data with get item`() { + val listResult = StringListResult(data = emptyList()) + + listResult[0] + } + + @Test + fun `list result`() { + val data = listOf("a", "b", "c", "d", "e", "f") + val listResult = StringListResult(data = data) + + assertEquals(data, listResult.list) + assertEquals(data.size, listResult.size) + assertFalse(listResult.isEmpty()) + assertFalse(listResult.contains("")) + assertTrue(listResult.contains("c")) + assertTrue(listResult.containsAll(emptyList())) + assertTrue(listResult.containsAll(listOf("b", "d"))) + assertFalse(listResult.containsAll(listOf("e", "g"))) + assertNotNull(listResult.iterator()) + } + + private class StringListResult( + override val data: List?, + ) : ListResult() { + override val next = null + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/MediaCompositionTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/MediaCompositionTest.kt new file mode 100644 index 0000000..704e29e --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/MediaCompositionTest.kt @@ -0,0 +1,62 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import java.util.Date +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.minutes + +class MediaCompositionTest { + @Test(expected = IllegalStateException::class) + fun `get main chapter with empty chapter list`() { + val mediaComposition = MediaComposition( + chapterUrn = "urn:rts:video:123456", + chapterList = emptyList(), + ) + + mediaComposition.getMainChapter() + } + + @Test(expected = IllegalStateException::class) + fun `get main chapter with chapter list without matching chapter`() { + val mediaComposition = MediaComposition( + chapterUrn = "urn:rts:video:123456", + chapterList = listOf( + createChapter(urn = "urn:rts:video:456789"), + ), + ) + + mediaComposition.getMainChapter() + } + + @Test + fun `get main chapter with chapter list with matching chapter`() { + val mainChapter = createChapter(urn = "urn:rts:video:123456") + val mediaComposition = MediaComposition( + chapterUrn = mainChapter.urn, + chapterList = listOf(createChapter(urn = "urn:rts:video:456789"), mainChapter), + ) + + assertEquals(mainChapter, mediaComposition.getMainChapter()) + } + + private companion object { + private fun createChapter( + urn: String, + segmentList: List? = null, + ): Chapter { + return Chapter( + id = "chapter-id", + mediaType = MediaType.VIDEO, + vendor = Vendor.RTS, + urn = urn, + title = "chapter-title", + imageUrl = ImageUrl("https://image.url"), + type = Type.EPISODE, + date = Date(), + duration = 90.minutes.inWholeMilliseconds, + segmentList = segmentList, + ) + } + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ProgramGuideTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ProgramGuideTest.kt new file mode 100644 index 0000000..cc33e46 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ProgramGuideTest.kt @@ -0,0 +1,49 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import kotlin.test.Test +import kotlin.test.assertEquals + +class ProgramGuideTest { + @Test + fun `find channel list with null program list`() { + val programGuide = ProgramGuide(data = null) + + assertEquals(emptyList(), programGuide.findChannelList()) + } + + @Test + fun `find channel list with empty program list`() { + val programGuide = ProgramGuide(data = emptyList()) + + assertEquals(emptyList(), programGuide.findChannelList()) + } + + @Test + fun `find channel list with program list`() { + val channels = buildList(5) { + repeat(5) { index -> + add( + Channel( + id = "channel-id-$index", + vendor = Vendor.RTS, + urn = "urn:rts:video:$index", + title = "channel-title$index", + imageUrl = ImageUrl("https://image.url/"), + transmission = Transmission.TV, + ) + ) + } + } + val programGuide = ProgramGuide( + data = channels.map { + ProgramCompositionListResult( + channel = it, + data = null, + ) + }, + ) + + assertEquals(channels, programGuide.findChannelList()) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ProgramTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ProgramTest.kt new file mode 100644 index 0000000..0df6240 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ProgramTest.kt @@ -0,0 +1,37 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import java.util.Calendar +import java.util.Calendar.AUGUST +import java.util.Calendar.OCTOBER +import java.util.Calendar.SEPTEMBER +import java.util.Date +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class ProgramTest { + @Test + fun `is date in program time`() { + val startTime = createDate(2024, SEPTEMBER, 1) + val endTime = createDate(2024, SEPTEMBER, 30) + val program = Program( + title = "", + startTime = startTime, + endTime = endTime, + ) + + assertFalse(program.isDateInProgramTime(createDate(2024, AUGUST, 15))) + assertFalse(program.isDateInProgramTime(startTime)) + assertTrue(program.isDateInProgramTime(createDate(2024, SEPTEMBER, 15))) + assertFalse(program.isDateInProgramTime(endTime)) + assertFalse(program.isDateInProgramTime(createDate(2024, OCTOBER, 15))) + } + + private companion object { + private fun createDate(year: Int, month: Int, day: Int): Date { + return Calendar.getInstance().apply { + set(year, month, day) + }.time + } + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/RepresentationTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/RepresentationTest.kt new file mode 100644 index 0000000..67f1546 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/RepresentationTest.kt @@ -0,0 +1,73 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNull + +class RepresentationTest { + @Test + fun `representation with null properties`() { + val representation = Representation( + name = "representation-name", + properties = null, + ) + + assertNull(representation.title) + assertNull(representation.description) + assertNull(representation.label) + assertFalse(representation.hasDetailPage) + assertFalse(representation.pickRandomElement) + assertNull(representation.imageUrl) + assertNull(representation.imageFocalPoint) + assertNull(representation.link) + } + + @Test + fun `representation with empty properties`() { + val representation = Representation( + name = "representation-name", + properties = Representation.Properties(), + ) + + assertNull(representation.title) + assertNull(representation.description) + assertNull(representation.label) + assertFalse(representation.hasDetailPage) + assertFalse(representation.pickRandomElement) + assertNull(representation.imageUrl) + assertNull(representation.imageFocalPoint) + assertNull(representation.link) + } + + @Test + fun `representation with properties`() { + val properties = Representation.Properties( + title = "title", + description = "description", + label = "label", + hasDetailPage = true, + pickRandomElement = true, + imageUrl = ImageUrl("https://image.url/image.jpg"), + imageFocalPoint = FocalPoint(25, 75), + link = Link( + targetType = "target-type", + target = "target", + ), + ) + val representation = Representation( + name = "representation-name", + properties = properties, + ) + + assertEquals(properties.title, representation.title) + assertEquals(properties.description, representation.description) + assertEquals(properties.label, representation.label) + assertEquals(properties.hasDetailPage, representation.hasDetailPage) + assertEquals(properties.pickRandomElement, representation.pickRandomElement) + assertEquals(properties.imageUrl, representation.imageUrl) + assertEquals(properties.imageFocalPoint, representation.imageFocalPoint) + assertEquals(properties.link, representation.link) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ResourceTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ResourceTest.kt new file mode 100644 index 0000000..6ed422f --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/ResourceTest.kt @@ -0,0 +1,68 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.remote.Resource.Drm.Type.FAIRPLAY +import ch.srg.dataProvider.integrationlayer.data.remote.VariantSource.DASH +import ch.srg.dataProvider.integrationlayer.data.remote.VariantType.SDH +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class ResourceTest { + @Test + fun `stream type`() { + val resource = createResource() + + assertEquals(StreamType.ON_DEMAND, resource.copy(dvr = false, live = false).streamType) + assertEquals(StreamType.LIVE, resource.copy(dvr = false, live = true).streamType) + assertEquals(StreamType.LIVE_WITH_DVR, resource.copy(dvr = true, live = false).streamType) + assertEquals(StreamType.LIVE_WITH_DVR, resource.copy(dvr = true, live = true).streamType) + } + + @Test + fun `is local file`() { + val resource = createResource() + + assertFalse(resource.copy(url = "").isLocalFile()) + assertFalse(resource.copy(url = "http://www.srgssr.ch/").isLocalFile()) + assertFalse(resource.copy(url = "https://www.srgssr.ch/").isLocalFile()) + assertTrue(resource.copy(url = "file:///etc/hosts").isLocalFile()) + } + + @Test + fun `has drm`() { + val resource = createResource() + + assertFalse(resource.copy(drmList = null).hasDrm()) + assertFalse(resource.copy(drmList = emptyList()).hasDrm()) + assertTrue(resource.copy(drmList = listOf(Resource.Drm(type = FAIRPLAY, licenseUrl = "", certificateUrl = null))).hasDrm()) + } + + @Test + fun `has subtitles`() { + val resource = createResource() + + assertFalse(resource.copy(subtitleVariants = null).hasSubtitles()) + assertFalse(resource.copy(subtitleVariants = emptyList()).hasSubtitles()) + assertTrue(resource.copy(subtitleVariants = listOf(Variant(locale = "fr_CH", source = DASH, language = "fr", type = SDH))).hasSubtitles()) + } + + @Test + fun `has audio tracks`() { + val resource = createResource() + + assertFalse(resource.copy(audioVariants = null).hasAudioTracks()) + assertFalse(resource.copy(audioVariants = emptyList()).hasAudioTracks()) + assertTrue(resource.copy(audioVariants = listOf(Variant(locale = "fr_CH", source = DASH, language = "fr", type = SDH))).hasAudioTracks()) + } + + private companion object { + private fun createResource(): Resource { + return Resource( + url = "https://url.com/resource", + quality = Quality.HD, + streamingMethod = StreamingMethod.DASH, + ) + } + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGMediaMetadataTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGMediaMetadataTest.kt new file mode 100644 index 0000000..01c33d4 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SRGMediaMetadataTest.kt @@ -0,0 +1,305 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import ch.srg.dataProvider.integrationlayer.data.remote.BlockReason.ENDDATE +import ch.srg.dataProvider.integrationlayer.data.remote.BlockReason.STARTDATE +import ch.srg.dataProvider.integrationlayer.data.remote.TimeAvailability.AVAILABLE +import ch.srg.dataProvider.integrationlayer.data.remote.TimeAvailability.NOT_AVAILABLE_ANYMORE +import ch.srg.dataProvider.integrationlayer.data.remote.TimeAvailability.NOT_YET_AVAILABLE +import java.util.Calendar +import java.util.Calendar.AUGUST +import java.util.Calendar.JULY +import java.util.Calendar.SEPTEMBER +import java.util.Date +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertNull +import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.minutes + +class SRGMediaMetadataTest { + @Test + fun `get download uri`() { + val metadata = createMediaMetadata() + + assertNull(metadata.copy(podcastSdUrl = null, podcastHdUrl = null).getDownloadUri()) + assertEquals(HD_URL, metadata.copy(podcastSdUrl = null, podcastHdUrl = HD_URL).getDownloadUri()) + assertEquals(SD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = null).getDownloadUri()) + assertEquals(HD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = HD_URL).getDownloadUri()) + + assertNull(metadata.copy(podcastSdUrl = null, podcastHdUrl = null).getDownloadUri(Quality.SD)) + assertNull(metadata.copy(podcastSdUrl = null, podcastHdUrl = HD_URL).getDownloadUri(Quality.SD)) + assertEquals(SD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = null).getDownloadUri(Quality.SD)) + assertEquals(SD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = HD_URL).getDownloadUri(Quality.SD)) + + assertNull(metadata.copy(podcastSdUrl = null, podcastHdUrl = null).getDownloadUri(Quality.HD)) + assertEquals(HD_URL, metadata.copy(podcastSdUrl = null, podcastHdUrl = HD_URL).getDownloadUri(Quality.HD)) + assertEquals(SD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = null).getDownloadUri(Quality.HD)) + assertEquals(HD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = HD_URL).getDownloadUri(Quality.HD)) + + assertNull(metadata.copy(podcastSdUrl = null, podcastHdUrl = null).getDownloadUri(Quality.HQ)) + assertEquals(HD_URL, metadata.copy(podcastSdUrl = null, podcastHdUrl = HD_URL).getDownloadUri(Quality.HQ)) + assertEquals(SD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = null).getDownloadUri(Quality.HQ)) + assertEquals(HD_URL, metadata.copy(podcastSdUrl = SD_URL, podcastHdUrl = HD_URL).getDownloadUri(Quality.HQ)) + } + + @Test + fun `is blocked`() { + val metadata = createMediaMetadata() + val atBeforeFrom = createDate(2024, JULY, 15) + val atBetweenFromTo = createDate(2024, AUGUST, 15) + val atAfterTo = createDate(2024, SEPTEMBER, 15) + val validFrom = createDate(2024, AUGUST, 1) + val validTo = createDate(2024, AUGUST, 31) + + assertFalse(metadata.copy(blockReason = null, validFrom = null, validTo = null).isBlocked()) + assertFalse(metadata.copy(blockReason = null, validFrom = null, validTo = null).isBlocked(atBeforeFrom)) + assertFalse(metadata.copy(blockReason = null, validFrom = validFrom, validTo = null).isBlocked()) + assertTrue(metadata.copy(blockReason = null, validFrom = validFrom, validTo = null).isBlocked(atBeforeFrom)) + assertFalse(metadata.copy(blockReason = null, validFrom = validFrom, validTo = null).isBlocked(atAfterTo)) + assertTrue(metadata.copy(blockReason = null, validFrom = null, validTo = validTo).isBlocked()) + assertFalse(metadata.copy(blockReason = null, validFrom = null, validTo = validTo).isBlocked(atBeforeFrom)) + assertTrue(metadata.copy(blockReason = null, validFrom = null, validTo = validTo).isBlocked(atAfterTo)) + assertTrue(metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).isBlocked()) + assertTrue(metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).isBlocked(atBeforeFrom)) + assertFalse(metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).isBlocked(atBetweenFromTo)) + assertTrue(metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).isBlocked(atAfterTo)) + + BlockReason.entries.forEach { blockReason -> + assertTrue(metadata.copy(blockReason = blockReason, validFrom = null, validTo = null).isBlocked()) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = null, validTo = null).isBlocked(atBeforeFrom)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = null).isBlocked()) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = null).isBlocked(atBeforeFrom)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = null).isBlocked(atAfterTo)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = null, validTo = validTo).isBlocked()) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = null, validTo = validTo).isBlocked(atBeforeFrom)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = null, validTo = validTo).isBlocked(atAfterTo)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).isBlocked()) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).isBlocked(atBeforeFrom)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).isBlocked(atBetweenFromTo)) + assertTrue(metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).isBlocked(atAfterTo)) + } + } + + @Test + fun `get time availability`() { + val metadata = createMediaMetadata() + val atBeforeFrom = createDate(2024, JULY, 15) + val atBetweenFromTo = createDate(2024, AUGUST, 15) + val atAfterTo = createDate(2024, SEPTEMBER, 15) + val validFrom = createDate(2024, AUGUST, 1) + val validTo = createDate(2024, AUGUST, 31) + + assertEquals(AVAILABLE, metadata.copy(blockReason = null, validFrom = null, validTo = null).getTimeAvailability()) + assertEquals(AVAILABLE, metadata.copy(blockReason = null, validFrom = null, validTo = null).getTimeAvailability(atBeforeFrom)) + assertEquals(AVAILABLE, metadata.copy(blockReason = null, validFrom = validFrom, validTo = null).getTimeAvailability()) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = null, validFrom = validFrom, validTo = null).getTimeAvailability(atBeforeFrom)) + assertEquals(AVAILABLE, metadata.copy(blockReason = null, validFrom = validFrom, validTo = null).getTimeAvailability(atAfterTo)) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = null, validFrom = null, validTo = validTo).getTimeAvailability()) + assertEquals(AVAILABLE, metadata.copy(blockReason = null, validFrom = null, validTo = validTo).getTimeAvailability(atBeforeFrom)) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = null, validFrom = null, validTo = validTo).getTimeAvailability(atAfterTo)) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).getTimeAvailability()) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBeforeFrom)) + assertEquals(AVAILABLE, metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBetweenFromTo)) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = null, validFrom = validFrom, validTo = validTo).getTimeAvailability(atAfterTo) + ) + + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = null, validTo = null).getTimeAvailability()) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = null, validTo = null).getTimeAvailability(atBeforeFrom)) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = null).getTimeAvailability()) + assertEquals( + NOT_YET_AVAILABLE, + metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = null).getTimeAvailability(atBeforeFrom) + ) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = null).getTimeAvailability(atAfterTo)) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = null, validTo = validTo).getTimeAvailability()) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = null, validTo = validTo).getTimeAvailability(atBeforeFrom)) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = null, validTo = validTo).getTimeAvailability(atAfterTo)) + assertEquals(NOT_YET_AVAILABLE, metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability()) + assertEquals( + NOT_YET_AVAILABLE, + metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBeforeFrom) + ) + assertEquals( + NOT_YET_AVAILABLE, + metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBetweenFromTo) + ) + assertEquals( + NOT_YET_AVAILABLE, + metadata.copy(blockReason = STARTDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability(atAfterTo) + ) + + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = ENDDATE, validFrom = null, validTo = null).getTimeAvailability()) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = ENDDATE, validFrom = null, validTo = null).getTimeAvailability(atBeforeFrom)) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = null).getTimeAvailability()) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = null).getTimeAvailability(atBeforeFrom) + ) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = null).getTimeAvailability(atAfterTo) + ) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = ENDDATE, validFrom = null, validTo = validTo).getTimeAvailability()) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = ENDDATE, validFrom = null, validTo = validTo).getTimeAvailability(atBeforeFrom) + ) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = ENDDATE, validFrom = null, validTo = validTo).getTimeAvailability(atAfterTo)) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability()) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBeforeFrom) + ) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBetweenFromTo) + ) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = ENDDATE, validFrom = validFrom, validTo = validTo).getTimeAvailability(atAfterTo) + ) + + (BlockReason.entries - STARTDATE - ENDDATE).forEach { blockReason -> + assertEquals(AVAILABLE, metadata.copy(blockReason = blockReason, validFrom = null, validTo = null).getTimeAvailability()) + assertEquals(AVAILABLE, metadata.copy(blockReason = blockReason, validFrom = null, validTo = null).getTimeAvailability(atBeforeFrom)) + assertEquals(AVAILABLE, metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = null).getTimeAvailability()) + assertEquals( + NOT_YET_AVAILABLE, + metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = null).getTimeAvailability(atBeforeFrom) + ) + assertEquals(AVAILABLE, metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = null).getTimeAvailability(atAfterTo)) + assertEquals(NOT_AVAILABLE_ANYMORE, metadata.copy(blockReason = blockReason, validFrom = null, validTo = validTo).getTimeAvailability()) + assertEquals(AVAILABLE, metadata.copy(blockReason = blockReason, validFrom = null, validTo = validTo).getTimeAvailability(atBeforeFrom)) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = blockReason, validFrom = null, validTo = validTo).getTimeAvailability(atAfterTo) + ) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).getTimeAvailability() + ) + assertEquals( + NOT_YET_AVAILABLE, + metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBeforeFrom) + ) + assertEquals( + AVAILABLE, + metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).getTimeAvailability(atBetweenFromTo) + ) + assertEquals( + NOT_AVAILABLE_ANYMORE, + metadata.copy(blockReason = blockReason, validFrom = validFrom, validTo = validTo).getTimeAvailability(atAfterTo) + ) + } + } + + @Test + fun `is blocked valid from time`() { + val metadata = createMediaMetadata() + val atBeforeFrom = createDate(2024, AUGUST, 15) + val atAfterFrom = createDate(2024, SEPTEMBER, 15) + val validFrom = createDate(2024, SEPTEMBER, 1) + + assertFalse(metadata.copy(validFrom = null).isBlockedValidFromTime()) + assertFalse(metadata.copy(validFrom = null).isBlockedValidFromTime(atBeforeFrom.time)) + assertFalse(metadata.copy(validFrom = null).isBlockedValidFromTime(validFrom.time)) + assertFalse(metadata.copy(validFrom = null).isBlockedValidFromTime(atAfterFrom.time)) + + assertFalse(metadata.copy(validFrom = validFrom).isBlockedValidFromTime()) + assertTrue(metadata.copy(validFrom = validFrom).isBlockedValidFromTime(atBeforeFrom.time)) + assertFalse(metadata.copy(validFrom = validFrom).isBlockedValidFromTime(validFrom.time)) + assertFalse(metadata.copy(validFrom = validFrom).isBlockedValidFromTime(atAfterFrom.time)) + } + + @Test + fun `is block valid to time`() { + val metadata = createMediaMetadata() + val atBeforeTo = createDate(2024, AUGUST, 15) + val atAfterTo = createDate(2024, SEPTEMBER, 15) + val validTo = createDate(2024, SEPTEMBER, 1) + + assertFalse(metadata.copy(validTo = null).isBlockValidToTime()) + assertFalse(metadata.copy(validTo = null).isBlockValidToTime(atBeforeTo.time)) + assertFalse(metadata.copy(validTo = null).isBlockValidToTime(validTo.time)) + assertFalse(metadata.copy(validTo = null).isBlockValidToTime(atAfterTo.time)) + + assertTrue(metadata.copy(validTo = validTo).isBlockValidToTime()) + assertFalse(metadata.copy(validTo = validTo).isBlockValidToTime(atBeforeTo.time)) + assertFalse(metadata.copy(validTo = validTo).isBlockValidToTime(validTo.time)) + assertTrue(metadata.copy(validTo = validTo).isBlockValidToTime(atAfterTo.time)) + } + + @Test + fun `is live`() { + val metadata = createMediaMetadata() + + assertFalse(metadata.copy(type = Type.EPISODE).isLive()) + assertFalse(metadata.copy(type = Type.EXTRACT).isLive()) + assertFalse(metadata.copy(type = Type.TRAILER).isLive()) + assertFalse(metadata.copy(type = Type.CLIP).isLive()) + assertTrue(metadata.copy(type = Type.LIVESTREAM).isLive()) + assertTrue(metadata.copy(type = Type.SCHEDULED_LIVESTREAM).isLive()) + } + + private data class SimpleSRGMediaMetadata( + override val mediaType: MediaType, + override val type: Type, + override val date: Date, + override val duration: Long, + override val blockReason: BlockReason? = null, + override val validFrom: Date? = null, + override val validTo: Date? = null, + override val assignedBy: Referrer? = null, + override val playableAbroad: Boolean, + override val youthProtectionColor: YouthProtectionColor? = null, + override val podcastSdUrl: String? = null, + override val podcastHdUrl: String? = null, + override val relatedContentList: List? = null, + override val socialCountList: List? = null, + override val aspectRatio: AspectRatio? = null, + // SRGIdentifierMetadata + override val urn: String, + // ILObject + override val id: String, + override val vendor: Vendor, + // SRGImageMetadata + override val imageUrl: ImageUrl, + override val imageTitle: String? = null, + override val imageCopyright: String? = null, + override val imageFocalPoint: FocalPoint? = null, + // SRGMetadata + override val title: String, + override val lead: String? = null, + override val description: String? = null, + ) : SRGMediaMetadata + + private companion object { + private const val HD_URL = "https://hd.url/" + private const val SD_URL = "https://sd.url/" + + private fun createMediaMetadata(): SimpleSRGMediaMetadata { + return SimpleSRGMediaMetadata( + mediaType = MediaType.VIDEO, + type = Type.EPISODE, + date = Date(), + duration = 90.minutes.inWholeMilliseconds, + playableAbroad = false, + urn = "urn:rts:video:123456", + id = "media-id", + vendor = Vendor.RTS, + imageUrl = ImageUrl("https://image.url/"), + title = "media-title", + ) + } + + private fun createDate(year: Int, month: Int, day: Int): Date { + return Calendar.getInstance().apply { + set(year, month, day) + }.time + } + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SearchParamsTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SearchParamsTest.kt new file mode 100644 index 0000000..88a67e4 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SearchParamsTest.kt @@ -0,0 +1,77 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class SearchParamsTest { + @Test + fun `MediaParams to default query map`() { + val mediaParams = SearchParams.MediaParams() + val queryMap = mediaParams.toQueryMap() + + assertTrue(queryMap.isEmpty()) + } + + @Test + fun `MediaParams to query map`() { + val mediaParams = SearchParams.MediaParams( + mediaType = MediaType.VIDEO, + topicUrns = listOf("urn:rts:video:123456", "urn:rts:video:456789"), + showUrns = listOf("urn:rts:show:123456", "urn:rts:show:456789"), + subtitlesAvailable = true, + downloadAvailable = false, + playableAbroad = true, + quality = Quality.HD, + durationFromInMinutes = 45, + durationToInMinutes = 90, + publishedDateFrom = "2024-09-01", + publishedDateTo = "2024-09-30", + includeAggregations = true, + includeSuggestions = false, + enableFuzzySearch = true, + operator = SearchParams.Operator.OR, + sortBy = SearchParams.SortBy.DATE, + sortDir = SearchParams.SortDir.ASC, + ) + val queryMap = mediaParams.toQueryMap() + + assertEquals(17, queryMap.size) + assertEquals("VIDEO", queryMap["mediaType"]) + assertEquals("urn:rts:video:123456,urn:rts:video:456789", queryMap["topicUrns"]) + assertEquals("urn:rts:show:123456,urn:rts:show:456789", queryMap["showUrns"]) + assertEquals("true", queryMap["subtitlesAvailable"]) + assertEquals("false", queryMap["downloadAvailable"]) + assertEquals("true", queryMap["playableAbroad"]) + assertEquals("HD", queryMap["quality"]) + assertEquals("45", queryMap["durationFromInMinutes"]) + assertEquals("90", queryMap["durationToInMinutes"]) + assertEquals("2024-09-01", queryMap["publishedDateFrom"]) + assertEquals("2024-09-30", queryMap["publishedDateTo"]) + assertEquals("true", queryMap["includeAggregations"]) + assertEquals("false", queryMap["includeSuggestions"]) + assertEquals("true", queryMap["enableFuzzySearch"]) + assertEquals("or", queryMap["operator"]) + assertEquals("date", queryMap["sortBy"]) + assertEquals("asc", queryMap["sortDir"]) + } + + @Test + fun `ShowParams to default query map`() { + val showParams = SearchParams.ShowParams() + val queryMap = showParams.toQueryMap() + + assertTrue(queryMap.isEmpty()) + } + + @Test + fun `ShowParams to query map`() { + val showParams = SearchParams.ShowParams( + mediaType = MediaType.VIDEO, + ) + val queryMap = showParams.toQueryMap() + + assertEquals(1, queryMap.size) + assertEquals("VIDEO", queryMap["mediaType"]) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SearchResultListTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SearchResultListTest.kt new file mode 100644 index 0000000..faa0e96 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SearchResultListTest.kt @@ -0,0 +1,33 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull + +class SearchResultListTest { + @Test + fun `urns with null data`() { + val searchResultList = SearchResultShowList(data = null) + + assertNull(searchResultList.urns()) + } + + @Test + fun `urns with empty data`() { + val searchResultList = SearchResultShowList(data = emptyList()) + + assertEquals(emptyList(), searchResultList.urns()) + } + + @Test + fun `urns with non-empty data`() { + val data = listOf( + SearchResult(id = "result-id-1", vendor = Vendor.RTS, urn = "urn:rts:video:1"), + SearchResult(id = "result-id-2", vendor = Vendor.RTS, urn = "urn:rts:video:2"), + SearchResult(id = "result-id-3", vendor = Vendor.RTS, urn = "urn:rts:video:3"), + ) + val searchResultList = SearchResultShowList(data = data) + + assertEquals(data.map { it.urn }, searchResultList.urns()) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SegmentTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SegmentTest.kt new file mode 100644 index 0000000..d800f41 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SegmentTest.kt @@ -0,0 +1,44 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import ch.srg.dataProvider.integrationlayer.data.ImageUrl +import java.util.Date +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNull +import kotlin.time.Duration.Companion.minutes + +class SegmentTest { + @Test + fun `resource reference date`() { + val segment = Segment( + id = "segment-id", + mediaType = MediaType.VIDEO, + vendor = Vendor.RTS, + urn = "urn:rts:video:123456", + title = "segment-title", + markIn = 3.minutes.inWholeMilliseconds, + markOut = 5.minutes.inWholeMilliseconds, + type = Type.EPISODE, + date = Date(), + duration = 90.minutes.inWholeMilliseconds, + displayable = true, + playableAbroad = true, + imageUrl = ImageUrl("https://image.url/"), + ) + + assertNull(segment.markInDate) + assertNull(segment.markOutDate) + assertNull(segment.resourceReferenceDate) + + val currentDate = Date() + segment.resourceReferenceDate = currentDate + assertEquals(Date(currentDate.time + segment.markIn), segment.markInDate) + assertEquals(Date(currentDate.time + segment.markOut), segment.markOutDate) + assertEquals(currentDate, segment.resourceReferenceDate) + + segment.resourceReferenceDate = null + assertNull(segment.markInDate) + assertNull(segment.markOutDate) + assertNull(segment.resourceReferenceDate) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SpriteSheetTest.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SpriteSheetTest.kt new file mode 100644 index 0000000..24a90e0 --- /dev/null +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/remote/SpriteSheetTest.kt @@ -0,0 +1,24 @@ +package ch.srg.dataProvider.integrationlayer.data.remote + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.minutes + +class SpriteSheetTest { + @Test + fun `sprite sheet`() { + val spriteSheet = SpriteSheet( + urn = "urn:rts:video:123456", + rows = 3, + columns = 5, + thumbnailHeight = 600, + thumbnailWidth = 800, + interval = 5.minutes.inWholeMilliseconds, + url = "https://url.com/video.mp4", + ) + + assertEquals(15, spriteSheet.count) + // TODO Enable this once #50 is merged + // assertEquals(AspectRatio(800, 600), spriteSheet.aspectRatio) + } +} diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestAspectRatioSerializer.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestAspectRatioSerializer.kt similarity index 91% rename from data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestAspectRatioSerializer.kt rename to data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestAspectRatioSerializer.kt index 41f5f09..7bda2d7 100644 --- a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestAspectRatioSerializer.kt +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestAspectRatioSerializer.kt @@ -1,9 +1,10 @@ -package ch.srg.dataProvider.integrationlayer.data +package ch.srg.dataProvider.integrationlayer.data.serializer +import ch.srg.dataProvider.integrationlayer.data.DataProviderJson import ch.srg.dataProvider.integrationlayer.data.remote.AspectRatio import kotlinx.serialization.encodeToString -import org.junit.Assert.assertEquals -import org.junit.Test +import kotlin.test.Test +import kotlin.test.assertEquals class TestAspectRatioSerializer { diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestBlockReasonSerializer.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestBlockReasonSerializer.kt similarity index 82% rename from data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestBlockReasonSerializer.kt rename to data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestBlockReasonSerializer.kt index 22d5ac8..f397461 100644 --- a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestBlockReasonSerializer.kt +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestBlockReasonSerializer.kt @@ -1,9 +1,10 @@ -package ch.srg.dataProvider.integrationlayer.data +package ch.srg.dataProvider.integrationlayer.data.serializer +import ch.srg.dataProvider.integrationlayer.data.DataProviderJson import ch.srg.dataProvider.integrationlayer.data.remote.BlockReason import kotlinx.serialization.encodeToString -import org.junit.Assert.assertEquals -import org.junit.Test +import kotlin.test.Test +import kotlin.test.assertEquals class TestBlockReasonSerializer { diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestDateSerializer.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestDateSerializer.kt similarity index 57% rename from data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestDateSerializer.kt rename to data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestDateSerializer.kt index a7b4391..a714c3b 100644 --- a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestDateSerializer.kt +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestDateSerializer.kt @@ -1,12 +1,12 @@ -package ch.srg.dataProvider.integrationlayer.data +package ch.srg.dataProvider.integrationlayer.data.serializer import androidx.test.ext.junit.runners.AndroidJUnit4 -import ch.srg.dataProvider.integrationlayer.data.serializer.DateSerializer -import org.junit.Assert -import org.junit.Ignore -import org.junit.Test +import ch.srg.dataProvider.integrationlayer.data.DataProviderJson import org.junit.runner.RunWith import java.util.Date +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertEquals @RunWith(AndroidJUnit4::class) class TestDateSerializer { @@ -16,7 +16,7 @@ class TestDateSerializer { fun testToJSon() { val expectedJson = "\"2017-05-30T08:36:15+02:00\"" val input = Date(1496126175000L) - Assert.assertEquals(expectedJson, DataProviderJson.encodeToString(serializer = DateSerializer(), input)) + assertEquals(expectedJson, DataProviderJson.encodeToString(serializer = DateSerializer(), input)) } @Ignore("robolectric date parsing doesn't use same format") @@ -24,6 +24,6 @@ class TestDateSerializer { fun testFromJson() { val input = "\"2017-05-30T08:36:15+02:00\"" val expectedDate = Date(1496126175000L) - Assert.assertEquals(expectedDate, DataProviderJson.decodeFromString(deserializer = DateSerializer(), input)) + assertEquals(expectedDate, DataProviderJson.decodeFromString(deserializer = DateSerializer(), input)) } } diff --git a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestImageUrlSerializer.kt b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestImageUrlSerializer.kt similarity index 70% rename from data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestImageUrlSerializer.kt rename to data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestImageUrlSerializer.kt index 9d42b54..6e64479 100644 --- a/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/TestImageUrlSerializer.kt +++ b/data/src/test/java/ch/srg/dataProvider/integrationlayer/data/serializer/TestImageUrlSerializer.kt @@ -1,8 +1,10 @@ -package ch.srg.dataProvider.integrationlayer.data +package ch.srg.dataProvider.integrationlayer.data.serializer +import ch.srg.dataProvider.integrationlayer.data.DataProviderJson +import ch.srg.dataProvider.integrationlayer.data.ImageUrl import kotlinx.serialization.encodeToString -import org.junit.Assert.assertEquals -import org.junit.Test +import kotlin.test.Test +import kotlin.test.assertEquals class TestImageUrlSerializer { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d3709d2..8266e39 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,6 +19,7 @@ androidx-paging-common = { module = "androidx.paging:paging-common", version.ref androidx-test-ext-junit = { module = "androidx.test.ext:junit", version.ref = "androidx-test-ext-junit" } detekt-formatting = { module = "io.gitlab.arturbosch.detekt:detekt-formatting", version.ref = "detekt" } junit = { module = "junit:junit", version.ref = "junit" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } okhttp-logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor", version.ref = "okhttp" } retrofit = { module = "com.squareup.retrofit2:retrofit" }