0.2.57 - Traliers bug fixes

This commit is contained in:
ponzischeme89
2026-08-12 13:08:53 +12:00
parent f2d052dbf6
commit 64f19aeef2
45 changed files with 1215 additions and 681 deletions
@@ -0,0 +1,52 @@
package com.ponzischeme89.memby.data
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Test
class ClientTrailerResolverTest {
@Test
fun youtubeIdsAcceptRealHostsAndRejectLookalikes() {
val id = "dQw4w9WgXcQ"
assertEquals(id, youtubeVideoId("https://www.youtube.com/watch?v=$id"))
assertEquals(id, youtubeVideoId("https://youtu.be/$id"))
assertEquals(id, youtubeVideoId("https://www.youtube-nocookie.com/embed/$id"))
assertNull(youtubeVideoId("https://notyoutube.com/watch?v=$id"))
}
@Test
fun balancedJsonIgnoresBracesInsideStrings() {
val body = "prefix \"videoRenderer\":{\"title\":\"a } brace\",\"nested\":{\"ok\":true}} suffix"
assertEquals(
"{\"title\":\"a } brace\",\"nested\":{\"ok\":true}}",
balancedObjectAfter(body, "\"videoRenderer\":"),
)
}
@Test
fun smartPreviewRankingFavoursTheExactOfficialEpisode() {
val next = NextEpisode(
itemId = "episode-2",
title = "The Crossing",
seriesName = "Southern Skies",
episodeCode = "S02 E04",
imageUrl = null,
url = "https://emby/episode-2",
)
val official = YouTubeSearchCandidate(
videoId = "abcdefghijk",
title = "Southern Skies S02E04 The Crossing Official Preview",
channel = "Southern Skies",
durationSeconds = 95,
)
val reaction = YouTubeSearchCandidate(
videoId = "zyxwvutsrqp",
title = "Southern Skies S02E04 preview reaction and breakdown",
channel = "Fan Reviews",
durationSeconds = 900,
)
assertTrue(previewScore(official, next) > previewScore(reaction, next))
assertTrue(previewSearchQuery(next).contains("S02E04"))
}
}
@@ -36,12 +36,13 @@ class GatewayPayloadTest {
"""{"available":true,"providers":["local","apple","youtube"]}""",
)
val playback = json.decodeFromString<GatewayTrailerPlayback>(
"""{"candidateId":"youtube-a1","provider":"youtube","url":"https://media.example/trailer.mp4","title":"Arrival trailer","playMethod":"DirectPlay"}""",
"""{"candidateId":"youtube-a1","provider":"youtube","sourceUrl":"https://youtu.be/dQw4w9WgXcQ","title":"Arrival trailer","playMethod":"DirectPlay"}""",
)
assertTrue(availability.available)
assertEquals(listOf("local", "apple", "youtube"), availability.providers)
assertEquals("youtube-a1", playback.candidateId)
assertEquals("https://youtu.be/dQw4w9WgXcQ", playback.sourceUrl)
assertEquals("Arrival trailer", playback.title)
}
@@ -20,6 +20,16 @@ class PlaybackReportMathTest {
assertEquals(0L, millisecondsToTicks(-1L))
}
/**
* Emby lists the device profile's name against a playback session, so it must carry
* the client identity rather than the product name — and it must be the same literal
* the gateway sends, or one television playing both ways appears as two clients.
*/
@Test
fun deviceProfileReportsTheClientIdentityNotTheProductName() {
assertEquals("MbyATV", DeviceProfile.embyAndroidTv().name)
}
@Test
fun deviceProfileExternalizesTextAndEncodesBitmapSubtitles() {
val profiles = DeviceProfile.embyAndroidTv().subtitleProfiles.associate {
@@ -22,4 +22,12 @@ class TrailerSupportTest {
assertTrue(shouldFallbackTrailer(isTrailer = true))
assertFalse(shouldFallbackTrailer(isTrailer = false))
}
@Test
fun nextEpisodePreviewNeedsANaturalTwoMinuteWindow() {
assertTrue(shouldStartNextEpisodePreview(true, false, 120_000, 120_000, true))
assertFalse(shouldStartNextEpisodePreview(false, false, 60_000, 120_000, true))
assertFalse(shouldStartNextEpisodePreview(true, true, 60_000, 120_000, true))
assertFalse(shouldStartNextEpisodePreview(true, false, 120_001, 120_000, true))
}
}
@@ -27,6 +27,7 @@ class UserPreferencesTest {
showTitleLogo = false,
welcomeQuoteStyle = "homicidal",
autoPlayNextEpisode = false,
playNextEpisodePreview = true,
showTenMinuteReminder = false,
seekIntervalSeconds = 30,
skipIntroMode = SKIP_INTRO_AUTO,
@@ -142,6 +143,7 @@ class UserPreferencesTest {
showTitleLogo = false,
welcomeQuoteStyle = "positive",
autoPlayNextEpisode = false,
playNextEpisodePreview = true,
showTenMinuteReminder = false,
forYouMinutes = 30,
homeRowOrder = "recommended\nlatest",
@@ -160,6 +162,7 @@ class UserPreferencesTest {
showTitleLogo = false,
welcomeQuoteStyle = "positive",
autoPlayNextEpisode = false,
playNextEpisodePreview = true,
showTenMinuteReminder = false,
forYouMinutes = 30,
homeRowOrder = listOf("recommended", "latest"),