aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs')
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs119
1 files changed, 116 insertions, 3 deletions
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
index bdb726f06d..93014e7244 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
@@ -119,6 +119,40 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
Assert.Equal(code, culture.ThreeLetterISOLanguageName);
}
+ [Theory]
+ [InlineData("ell", "Greek")] // Comma truncation
+ [InlineData("nld", "Dutch")] // Semicolon truncation
+ [InlineData("ron", "Romanian")] // Semicolon truncation, multiple
+ [InlineData("eng", "English")] // No truncation
+ [InlineData("zh-CN", "Chinese (Simplified)")] // No truncation, with parentheses
+ public async Task GetLanguageDisplayName_DelimitedName_ReturnsTruncatedName(string language, string expected)
+ {
+ var localizationManager = Setup(new ServerConfiguration
+ {
+ UICulture = "en-US"
+ });
+ await localizationManager.LoadAll();
+
+ var result = localizationManager.GetLanguageDisplayName(language);
+ Assert.Equal(expected, result);
+ }
+
+ [Theory]
+ [InlineData(null)]
+ [InlineData("")]
+ [InlineData("xyz")]
+ public async Task GetLanguageDisplayName_InvalidInput_ReturnsNull(string? language)
+ {
+ var localizationManager = Setup(new ServerConfiguration
+ {
+ UICulture = "en-US"
+ });
+ await localizationManager.LoadAll();
+
+ var result = localizationManager.GetLanguageDisplayName(language!);
+ Assert.Null(result);
+ }
+
[Fact]
public async Task GetParentalRatings_Default_Success()
{
@@ -165,6 +199,16 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
[InlineData("Rated: R", "US", 17, 0)]
[InlineData("Rated R", "US", 17, 0)]
[InlineData(" PG-13 ", "US", 13, 0)]
+ [InlineData("T", "IT", 0, null)]
+ [InlineData("VM6", "IT", 6, null)]
+ [InlineData("VM12", "IT", 12, null)]
+ [InlineData("VM14", "IT", 14, null)]
+ [InlineData("VM18", "IT", 18, null)]
+ [InlineData("IT-VM14", "IT", 14, null)] // TMDB style country prefix
+ [InlineData("IT-VM18", "IT", 18, null)]
+ [InlineData("it-vm18", "IT", 18, null)] // Rating strings are case insensitive
+ [InlineData("VM 18", "IT", 18, null)]
+ [InlineData("Vietato ai minori di 18 anni", "IT", 18, null)]
public async Task GetRatingLevel_GivenValidString_Success(string value, string countryCode, int? expectedScore, int? expectedSubScore)
{
var localizationManager = Setup(new ServerConfiguration()
@@ -179,6 +223,30 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
}
[Theory]
+ // Rating strings are stored mixed-case in the *.json rating systems and must match regardless of casing
+ [InlineData("btl", "se", 0, null)] // Direct lookup, lowercase of "Btl"
+ [InlineData("BARNTILLÅTEN", "se", 0, null)] // Direct lookup, uppercase incl. diacritics
+ [InlineData("SE-BTL", "se", 0, null)] // Country prefix stripped against the configured country
+ [InlineData("SE-BTL", "us", 0, null)] // Country prefix resolved via the separator fallback
+ [InlineData("Från 7 År", "se", 7, null)] // Diacritic casing (json has "Från 7 år")
+ [InlineData("SE-Från 7 År", "us", 7, null)] // Same, via the separator fallback
+ [InlineData("fsk-16", "de", 16, null)] // Not Sweden specific: lowercase of "FSK-16"
+ public async Task GetRatingScore_IsCaseInsensitive_Success(string value, string countryCode, int? expectedScore, int? expectedSubScore)
+ {
+ var localizationManager = Setup(new ServerConfiguration
+ {
+ MetadataCountryCode = countryCode
+ });
+ await localizationManager.LoadAll();
+
+ var score = localizationManager.GetRatingScore(value);
+
+ Assert.NotNull(score);
+ Assert.Equal(expectedScore, score.Score);
+ Assert.Equal(expectedSubScore, score.SubScore);
+ }
+
+ [Theory]
[InlineData("0", 0, null)]
[InlineData("1", 1, null)]
[InlineData("6", 6, null)]
@@ -207,6 +275,51 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
Assert.Null(localizationManager.GetRatingScore("unrated"));
Assert.Null(localizationManager.GetRatingScore("Not Rated"));
Assert.Null(localizationManager.GetRatingScore("n/a"));
+ Assert.Null(localizationManager.GetRatingScore("N/A"));
+ Assert.Null(localizationManager.GetRatingScore(" n/a "));
+ }
+
+ [Theory]
+ // "NR" and "UR" are rating strings of some systems, so they must stay unrated when listed alongside others
+ [InlineData("NR / R", 17, 0)]
+ [InlineData("unrated / R", 17, 0)]
+ [InlineData("R / NR", 17, 0)]
+ public async Task GetRatingLevel_SkipsUnratedListEntries_Success(string value, int? expectedScore, int? expectedSubScore)
+ {
+ var localizationManager = Setup(new ServerConfiguration { MetadataCountryCode = "us" });
+ await localizationManager.LoadAll();
+
+ var score = localizationManager.GetRatingScore(value);
+
+ Assert.NotNull(score);
+ Assert.Equal(expectedScore, score.Score);
+ Assert.Equal(expectedSubScore, score.SubScore);
+ }
+
+ [Theory]
+ // Ratings that contain a '/' themselves must not be split into a list of ratings
+ [InlineData("M/3", "pt", 3, null)]
+ [InlineData("M/12", "pt", 12, null)]
+ [InlineData("M/18", "pt", 18, null)]
+ [InlineData("PT-M/12", "pt", 12, null)] // TMDB style country prefix
+ [InlineData("M/12", "us", 12, null)] // Resolved through the all-systems fallback
+ [InlineData("U/A 13+", "in", 13, null)]
+ [InlineData("7/i", "es", 11, null)]
+ [InlineData("7/i/fig", "es", 11, null)]
+ [InlineData("18/fig", "es", 18, null)]
+ public async Task GetRatingScore_RatingContainingSlash_IsNotSplit(string value, string countryCode, int expectedScore, int? expectedSubScore)
+ {
+ var localizationManager = Setup(new ServerConfiguration
+ {
+ MetadataCountryCode = countryCode
+ });
+ await localizationManager.LoadAll();
+
+ var score = localizationManager.GetRatingScore(value);
+
+ Assert.NotNull(score);
+ Assert.Equal(expectedScore, score.Score);
+ Assert.Equal(expectedSubScore, score.SubScore);
}
[Theory]
@@ -315,7 +428,7 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
});
var translated = localizationManager.GetLocalizedString("Artists", "de");
- Assert.Equal("Interpreten", translated);
+ Assert.Equal("Künstler", translated);
}
[Fact]
@@ -372,7 +485,7 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
{
CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo("fr");
var translated = localizationManager.GetServerLocalizedString("Artists");
- Assert.Equal("Interpreten", translated);
+ Assert.Equal("Künstler", translated);
}
finally
{
@@ -393,7 +506,7 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
{
CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo("de");
var translated = localizationManager.GetLocalizedString("Artists");
- Assert.Equal("Interpreten", translated);
+ Assert.Equal("Künstler", translated);
}
finally
{