diff options
| author | Shadowghost <Shadowghost@users.noreply.github.com> | 2026-09-15 11:16:22 -0400 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2026-09-15 11:16:22 -0400 |
| commit | da3031628fda013be20ae4f89906882cc5d72e14 (patch) | |
| tree | 95e60472a8952e7ca028546c39c5a1d09b9e531d | |
| parent | 6937f03dc2c719b730f092fe4a87d8d4b6c2fc93 (diff) | |
Backport pull request #18002 from jellyfin/release-12.z
Fix slashed rating handling
Original-merge: 4405fccda92426b01903e3fe4c5985f1d7c30957
Merged-by: crobibero <cody@robibe.ro>
Backported-by: Cody Robibero <cody@robibe.ro>
4 files changed, 40 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Localization/LocalizationManager.cs b/Emby.Server.Implementations/Localization/LocalizationManager.cs index c77717c76e..3f89237ab2 100644 --- a/Emby.Server.Implementations/Localization/LocalizationManager.cs +++ b/Emby.Server.Implementations/Localization/LocalizationManager.cs @@ -382,9 +382,21 @@ namespace Emby.Server.Implementations.Localization return null; } + // Several rating systems contain a '/' inside a single rating (e.g. "M/12" in PT, + // "U/A 13+" in IN, "7/i/fig" in ES), so the value as a whole always wins over the split below. + var wholeValueScore = GetSingleRatingScore(rating, countryCode); + if (wholeValueScore is not null) + { + return wholeValueScore; + } + // Some providers may list multiple ratings separated by '/' (e.g. "SE:15 / SE:15+ / SE:Från 15 år"). // Try each one in order and use the first that resolves. var ratingValues = rating.Split('/', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); + if (ratingValues.Length == 1) + { + return null; + } foreach (var ratingValue in ratingValues) { diff --git a/tests/Jellyfin.Controller.Tests/Entities/AggregateFolderTests.cs b/tests/Jellyfin.Controller.Tests/Entities/AggregateFolderTests.cs index 6c297673d4..272c434fe9 100644 --- a/tests/Jellyfin.Controller.Tests/Entities/AggregateFolderTests.cs +++ b/tests/Jellyfin.Controller.Tests/Entities/AggregateFolderTests.cs @@ -9,6 +9,7 @@ using Xunit; namespace Jellyfin.Controller.Tests.Entities; +[Collection("LibraryManagerTests")] public class AggregateFolderTests { [Fact] diff --git a/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs b/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs index f363968909..588f9d5530 100644 --- a/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs +++ b/tests/Jellyfin.Controller.Tests/Entities/BaseItemTests.cs @@ -27,6 +27,7 @@ using Xunit; namespace Jellyfin.Controller.Tests.Entities; +[Collection("LibraryManagerTests")] public class BaseItemTests { [Fact] diff --git a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs index 221f1d8ec8..93014e7244 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs @@ -297,6 +297,32 @@ namespace Jellyfin.Server.Implementations.Tests.Localization } [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] [InlineData("-NO RATING SHOWN-")] [InlineData(":NO RATING SHOWN:")] public async Task GetRatingLevel_Split_Success(string value) |
