Files
jellyfin-multilang/tests/Jellyfin.Plugin.Multilang.Tests/ItemsProxyTransformerResolutionTests.cs
T
2026-07-15 22:45:54 +00:00

164 lines
4.8 KiB
C#

using Jellyfin.Plugin.Multilang.Data;
using Jellyfin.Plugin.Multilang.Services;
namespace Jellyfin.Plugin.Multilang.Tests;
public sealed class ItemsProxyTransformerResolutionTests
{
private const string TitleField = "title";
private const string OverviewField = "overview";
private const string TaglineField = "tagline";
private const string PosterKind = "poster";
private const string LogoKind = "logo";
private const string OriginalAction = "Original";
private const string LanguagePrefix = "Language:";
[Fact]
public void ResolveFieldUsesFirstLanguageWithData()
{
var translations = TextTranslations(
("sv", OverviewField, ""),
("fi", OverviewField, "Finnish overview"),
("en", OverviewField, "English overview"));
var result = ItemsProxyTransformer.ResolveField(
OverviewField,
[LanguagePrefix + "sv", LanguagePrefix + "fi", LanguagePrefix + "en"],
Facts(),
translations);
Assert.True(result.Change);
Assert.Equal("Finnish overview", result.Value);
}
[Fact]
public void ResolveFieldUsesOriginalTitleBeforeTranslations()
{
var result = ItemsProxyTransformer.ResolveField(
TitleField,
[OriginalAction, LanguagePrefix + "en"],
Facts(originalTitle: "Original title"),
TextTranslations(("en", TitleField, "English title")));
Assert.True(result.Change);
Assert.Equal("Original title", result.Value);
}
[Fact]
public void ResolveFieldFallsBackToJellyfinForMissingTitle()
{
var result = ItemsProxyTransformer.ResolveField(
TitleField,
[LanguagePrefix + "sv"],
Facts(),
TextTranslations());
Assert.False(result.Change);
Assert.Null(result.Value);
}
[Fact]
public void ResolveFieldClearsMissingOptionalText()
{
var result = ItemsProxyTransformer.ResolveField(
TaglineField,
[LanguagePrefix + "sv"],
Facts(),
TextTranslations());
Assert.True(result.Change);
Assert.Equal(string.Empty, result.Value);
}
[Fact]
public void ResolveAssetUsesFirstLanguageWithData()
{
var assets = AssetTranslations(
(PosterKind, "sv", ""),
(PosterKind, "fi", "https://image/fi.jpg"),
(PosterKind, "en", "https://image/en.jpg"));
var result = ItemsProxyTransformer.ResolveAsset(
PosterKind,
[LanguagePrefix + "sv", LanguagePrefix + "fi", LanguagePrefix + "en"],
assets);
Assert.True(result.Change);
Assert.Equal("https://image/fi.jpg", result.Value);
}
[Fact]
public void ResolveAssetFallsBackToJellyfinForMissingPoster()
{
var result = ItemsProxyTransformer.ResolveAsset(
PosterKind,
[LanguagePrefix + "sv"],
AssetTranslations());
Assert.False(result.Change);
Assert.Null(result.Value);
}
[Fact]
public void ResolveAssetClearsMissingOptionalImage()
{
var result = ItemsProxyTransformer.ResolveAsset(
LogoKind,
[LanguagePrefix + "sv"],
AssetTranslations());
Assert.True(result.Change);
Assert.Equal(string.Empty, result.Value);
}
private static Dictionary<string, Dictionary<string, string>> TextTranslations(params (string Lang, string Field, string Value)[] rows)
{
var result = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
foreach (var (lang, field, value) in rows)
{
if (!result.TryGetValue(lang, out var byField))
{
byField = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
result[lang] = byField;
}
byField[field] = value;
}
return result;
}
private static Dictionary<string, Dictionary<string, string>> AssetTranslations(params (string Kind, string Lang, string Value)[] rows)
{
var result = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
foreach (var (kind, lang, value) in rows)
{
if (!result.TryGetValue(kind, out var byLang))
{
byLang = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
result[kind] = byLang;
}
byLang[lang] = value;
}
return result;
}
private static FactsData Facts(string originalTitle = "")
=> new(
"item",
"tmdb",
"movie",
originalTitle,
"",
"",
"[]",
"[]",
"[]",
"",
"[]",
0,
0);
}