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

36 remove rts image workaround #37

Merged
merged 2 commits into from
Apr 8, 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
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ object Config {
const val minSdk = 21

const val major = 0
const val minor = 8
const val patch = 3
const val minor = 9
const val patch = 0
const val versionName = "$major.$minor.$patch"

const val maven_group = "ch.srg.data.provider"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,54 @@
package ch.srg.dataProvider.integrationlayer.request.image

import android.net.Uri
import ch.srg.dataProvider.integrationlayer.data.ImageUrlDecorator
import ch.srg.dataProvider.integrationlayer.request.IlHost

/**
* Copyright (c) SRG SSR. All rights reserved.
* Il host image url decorator
*
* If the image url isn't supported by [DefaultImageUrlDecorator] the same url is returned.
*
* License information is available from the LICENSE file.
*/

/**
* Default image url decorator
* confluence doc : https://srgssr-ch.atlassian.net/wiki/spaces/SRGPLAY/pages/799082429/Project+-+Image+Service)
*
* For specific RTS image url, the old [ScaleWidthImageUrlDecorator] is used, but it should be fixed sooner or later.
*
* @param ilHost The [IlHost] to use with [ilHostImageUrlDecorator].
* @param ilHost The [IlHost] of the integration layer image service.
*/
class DefaultImageUrlDecorator(ilHost: IlHost = IlHost.PROD) : ImageUrlDecorator {
private val ilHostImageUrlDecorator = IlHostImageUrlDecorator(ilHost)
class DefaultImageUrlDecorator(ilHost: IlHost) : ImageUrlDecorator {
private val imageServiceUri: Uri

init {
imageServiceUri = ilHost.hostUri.buildUpon().appendEncodedPath(IMAGES_SEGMENT).build()
}

override fun decorate(sourceUrl: String, widthPixels: Int): String {
// FIXME https://github.com/SRGSSR/srgdataprovider-apple/issues/47 once RTS image service is well connected to Il Play image service.
return if (sourceUrl.contains("rts.ch") && sourceUrl.contains(".image")) {
ScaleWidthImageUrlDecorator.decorate(sourceUrl, widthPixels)
} else {
ilHostImageUrlDecorator.decorate(sourceUrl, widthPixels)
}
// Il image service only support some image url hostnames!
if (!isImageUrlHostCompatible(sourceUrl)) return sourceUrl
// Il image service only support a limited image size!
val imageWidth = ImageWidth.getFromPixels(widthPixels)
return imageServiceUri.buildUpon()
.appendQueryParameter(PARAM_IMAGE_URL, sourceUrl)
.appendQueryParameter(PARAM_FORMAT, FORMAT_WEBP)
.appendQueryParameter(PARAM_WIDTH, imageWidth.widthPixels.toString())
.build()
.toString()
}

/**
* Check that the host of the [imageUrl] is compatible with the il image service.
*
* @param imageUrl The image url to decorate.
*/
fun isImageUrlHostCompatible(imageUrl: String): Boolean {
return Uri.parse(imageUrl)?.host?.contains(SUPPORTED_HOST_NAME_REGEX) ?: false
}

companion object {
private const val FORMAT_WEBP = "webp" // webp, jpg, png
private const val IMAGES_SEGMENT = "images/"
private const val PARAM_IMAGE_URL = "imageUrl"
private const val PARAM_FORMAT = "format"
private const val PARAM_WIDTH = "width"

private val SUPPORTED_HOST_NAME_REGEX = "((rts|srf|rsi|rtr|swissinfo|srgssr)\\.ch)|swi-services-ch".toRegex(RegexOption.IGNORE_CASE)
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,99 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import ch.srg.dataProvider.integrationlayer.data.ImageUrl
import ch.srg.dataProvider.integrationlayer.request.IlHost
import ch.srg.dataProvider.integrationlayer.request.image.DefaultImageUrlDecorator
import org.junit.Assert
import ch.srg.dataProvider.integrationlayer.request.image.ImageSize
import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth
import ch.srg.dataProvider.integrationlayer.request.image.decorated
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class TestDefaultImageUrlDecorator {

private val decorator = DefaultImageUrlDecorator(ilHost = IlHost.PROD)

@Test
fun testNonRtsUrl() {
fun testPixelValid() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
Assert.assertEquals(expected, input.decorated(decorator, 480))
assertEquals(expected, input.decorated(decorator, 480))
}

@Test
fun testRtsUrlWithoutImage() {
val input = ImageUrl("https://ws.rts.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.rts.ch/asset/image/audio/123")
fun testPixelWidthInvalid() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
Assert.assertEquals(expected, input.decorated(decorator, 480))
assertEquals(expected, input.decorated(decorator, 460))
}

@Test
fun testUrlWithImageOnly() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123.image")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123.image")
fun testImageSize() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
Assert.assertEquals(expected, input.decorated(decorator, 480))
assertEquals(expected, input.decorated(decorator, ImageSize.MEDIUM))
}

@Test
fun testRtsUrlWithImage() {
val input = ImageUrl("https://ws.rts.ch/asset/image/audio/123.image")
val expected = "https://ws.rts.ch/asset/image/audio/123.image/scale/width/460"
Assert.assertEquals(expected, input.decorated(decorator, 460))
fun testImageWidth() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=1920"
assertEquals(expected, input.decorated(decorator, ImageWidth.W1920))
}

@Test
fun testOtherIlHost() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il-stage.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=1920"
assertEquals(expected, input.decorated(decorator = DefaultImageUrlDecorator(IlHost.STAGE), width = ImageWidth.W1920))
}

@Test
fun testExtensionImageWidthWithIlHost() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il-stage.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=1920"
assertEquals(expected, input.decorated(ilHost = IlHost.STAGE, width = ImageWidth.W1920))
}

@Test
fun testExtensionImageSizeWithIlHost() {
val input = ImageUrl("https://ws.srf.ch/asset/image/audio/123")
val encodedInput = Uri.encode("https://ws.srf.ch/asset/image/audio/123")
val expected = "https://il-test.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
assertEquals(expected, input.decorated(ilHost = IlHost.TEST, imageSize = ImageSize.MEDIUM))
}

@Test
fun testAllValidatedHostName() {
val tests = listOf(
"https://ws.srf.ch/asset/image/audio/123",
"https://www.srf.ch/asset/image/audio/123",
"https://ws.debug.srf.ch/asset/image/audio/123",
"https://ws.rts.ch/asset/image/audio/123",
"https://ws.rtr.ch/asset/image/audio/123",
"https://ws.rsi.ch/asset/image/audio/123",
"https://ws.swissinfo.ch/asset/image/audio/123",
"https://ws.srgssr.ch/asset/image/audio/123",
"https://swi-services-ch/asset/image/audio/123",
)
for (url in tests) {
val input = ImageUrl(url)
val encodedInput = Uri.encode(url)
val expected = "https://il-test.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
assertEquals(expected, input.decorated(ilHost = IlHost.TEST, imageSize = ImageSize.MEDIUM))
}
}

@Test
fun testInvalidHostNameUrlReturnInputUrl() {
val input = ImageUrl("https://akamai.playsuisse.ch/asset/image/audio/123")
val expected = input.rawUrl
assertEquals(expected, input.decorated(ilHost = IlHost.TEST, imageSize = ImageSize.MEDIUM))
}
}

This file was deleted.

Loading
Loading