Skip to content

Commit

Permalink
Refactoring service image (#25)
Browse files Browse the repository at this point in the history
# Description

The goal of this PR is to enhance the integrator experience with image
url handling.

The new api allow to write with ease image url like the SRG SSR
required.

### Examples

```kotlin
val media: Media = ...
media.imageUrl.url(ImageWidth.W1920)
media.imageUrl.url(ImageWidth.W1920, IlHost.TEST)

val chapter: Chapter = ...
chapter.imageUrl.url(ImageSize.MEDIUM)
  
val defaultDecorator = DefaultImageUrlDecorator(IlHost.PROD) // or custom decorator
media.imageUrl.url(defaultDecorator, ImageSize.MEDIUM)
```
## Changes
- `ImageUrl.rawUrl` is private now
- Add `ImageUrlDecorator` to decorate image url with a width
- Remove `ImageProvider` replaced by `DefaultImageUrlDecorator`

---------

Co-authored-by: Loïc Dumas <[email protected]>
Co-authored-by: Gaëtan Muller <[email protected]>
  • Loading branch information
3 people authored Nov 28, 2023
1 parent 4c202f3 commit aca31b8
Show file tree
Hide file tree
Showing 17 changed files with 524 additions and 153 deletions.
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 = 6
const val patch = 3
const val minor = 7
const val patch = 2
const val versionName = "$major.$minor.$patch"

const val maven_group = "ch.srg.data.provider"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/*
* Copyright (c) SRG SSR. All rights reserved.
* License information is available from the LICENSE file.
*/
@file:Suppress("MemberVisibilityCanBePrivate")

package ch.srg.dataProvider.integrationlayer.data
Expand All @@ -6,10 +10,9 @@ import ch.srg.dataProvider.integrationlayer.data.serializer.ImageUrlSerializer
import java.io.Serializable

/**
* Copyright (c) SRG SSR. All rights reserved.
*
* Image url
*
* License information is available from the LICENSE file.
* @property rawUrl Internal image url, to retrieve the url use [ImageUrl.decorated].
*/
@Suppress("SerialVersionUIDInSerializableClass")
@kotlinx.serialization.Serializable(with = ImageUrlSerializer::class)
Expand All @@ -19,15 +22,17 @@ data class ImageUrl(
*
* @return the undecorated url
*/
val rawUrl: String
internal val rawUrl: String
) : Serializable {

@JvmOverloads
fun getIlImage(): IlImage {
return IlImage(rawUrl)
}

override fun toString(): String {
return rawUrl
/**
* Decorated
*
* @param decorator The [ImageUrlDecorator] used to decorate the [rawUrl].
* @param widthPixels The width of the image.
* @return The decorated [rawUrl].
*/
fun decorated(decorator: ImageUrlDecorator, widthPixels: Int): String {
return decorator.decorate(rawUrl, widthPixels)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package ch.srg.dataProvider.integrationlayer.data

/**
* Image url decorator
*/
interface ImageUrlDecorator {
/**
* Decorate [sourceUrl] with [widthPixels].
*
* @param sourceUrl The source url.
* @param widthPixels The width size in pixels.
* @return decorated url.
*/
fun decorate(sourceUrl: String, widthPixels: Int): String
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ch.srg.dataProvider.integrationlayer

import android.net.Uri
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 org.junit.Test

class TestDefaultImageUrlDecorator {
private val decorator = DefaultImageUrlDecorator(ilHost = IlHost.PROD)

@Test
fun testNonRtsUrl() {
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))
}

@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")
val expected = "https://il.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
Assert.assertEquals(expected, input.decorated(decorator, 480))
}

@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")
val expected = "https://il.srgssr.ch/images/?imageUrl=${encodedInput}&format=webp&width=480"
Assert.assertEquals(expected, input.decorated(decorator, 480))
}

@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))
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ch.srg.dataProvider.integrationlayer

import android.net.Uri
import ch.srg.dataProvider.integrationlayer.data.ImageUrl
import ch.srg.dataProvider.integrationlayer.request.IlHost
import ch.srg.dataProvider.integrationlayer.request.image.IlHostImageUrlDecorator
import ch.srg.dataProvider.integrationlayer.request.image.ImageSize
import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth
import ch.srg.dataProvider.integrationlayer.request.image.url
import ch.srg.dataProvider.integrationlayer.request.image.decorated
import org.junit.Assert.assertEquals
import org.junit.Test

class TestIlHostImageUrlDecorator {

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

@Test
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"
assertEquals(expected, input.decorated(decorator, 480))
}

@Test
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"
assertEquals(expected, input.decorated(decorator, 460))
}

@Test
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"
assertEquals(expected, input.decorated(decorator, ImageSize.MEDIUM))
}

@Test
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.url(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.url(decorator = IlHostImageUrlDecorator(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))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void createFromValidUrn() {
}

@Test
public void testIsAudioValideUrn() {
public void testIsAudioValidUrn() {
Assert.assertFalse(IlUrn.isAudio("urn:rts:video:123456"));
Assert.assertTrue(IlUrn.isAudio("urn:rts:audio:123456"));
Assert.assertFalse(IlUrn.isAudio("urn:a:b:12345"));
Expand All @@ -58,7 +58,7 @@ public void testIsAudioNullUrn() {


@Test
public void testIsVideoValideUrn() {
public void testIsVideoValidUrn() {
Assert.assertTrue(IlUrn.isVideo("urn:rts:video:123456"));
Assert.assertFalse(IlUrn.isVideo("urn:rts:audio:123456"));
Assert.assertFalse(IlUrn.isVideo("urn:a:b:12345"));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ch.srg.dataProvider.integrationlayer

import ch.srg.dataProvider.integrationlayer.data.ImageUrl
import ch.srg.dataProvider.integrationlayer.request.image.ImageSize
import ch.srg.dataProvider.integrationlayer.request.image.ImageWidth
import ch.srg.dataProvider.integrationlayer.request.image.ScaleWidthImageUrlDecorator
import ch.srg.dataProvider.integrationlayer.request.image.url
import ch.srg.dataProvider.integrationlayer.request.image.decorated
import org.junit.Assert.assertEquals
import org.junit.Test

class TestScaleWidthImageUrlDecorator {

private val decorator = ScaleWidthImageUrlDecorator

@Test
fun testScaleWidth() {
val input = ImageUrl("https://www.data.com/images/images.png")
val width = 458
val expected = "https://www.data.com/images/images.png/scale/width/458"
assertEquals(expected, input.decorated(decorator, width))
}

@Test
fun testScaleWidthImageSize() {
val input = ImageUrl("https://www.data.com/images/images.png")
val expected = "https://www.data.com/images/images.png/scale/width/480"
assertEquals(expected, input.decorated(decorator, ImageSize.MEDIUM))
}

@Test
fun testScaleWidthImageWidth() {
val input = ImageUrl("https://www.data.com/images/images.png")
val expected = "https://www.data.com/images/images.png/scale/width/1920"
assertEquals(expected, input.url(decorator, ImageWidth.W1920))
}
}

This file was deleted.

Loading

0 comments on commit aca31b8

Please sign in to comment.