diff --git a/tests/Jellyfin.Plugin.Multilang.Tests/ItemsProxySortingTests.cs b/tests/Jellyfin.Plugin.Multilang.Tests/ItemsProxySortingTests.cs new file mode 100644 index 0000000..fd2bed7 --- /dev/null +++ b/tests/Jellyfin.Plugin.Multilang.Tests/ItemsProxySortingTests.cs @@ -0,0 +1,106 @@ +using System.Globalization; +using System.Text.Json.Nodes; +using Jellyfin.Plugin.Multilang.Configuration; +using Jellyfin.Plugin.Multilang.Services; + +namespace Jellyfin.Plugin.Multilang.Tests; + +public sealed class ItemsProxySortingTests +{ + [Fact] + public void GetSortArticlesUsesBuiltInLocaleFallback() + { + var articles = ItemsProxySorting.GetSortArticles(new SortArticleCatalog(), [], "sv-FI"); + + Assert.Equal(["en", "ett"], articles); + } + + [Fact] + public void GetSortArticlesUsesConfiguredLanguageFallback() + { + var articles = ItemsProxySorting.GetSortArticles( + new SortArticleCatalog(), + [new SortArticleEntry { Language = "en", Articles = "one, two" }], + "en-CA"); + + Assert.Equal(["one", "two"], articles); + } + + [Fact] + public void GetSortArticlesPrefersConfiguredExactLocale() + { + var articles = ItemsProxySorting.GetSortArticles( + new SortArticleCatalog(), + [ + new SortArticleEntry { Language = "en", Articles = "language" }, + new SortArticleEntry { Language = "en-GB", Articles = "exact" } + ], + "en-GB"); + + Assert.Equal(["exact"], articles); + } + + [Fact] + public void ApplySortsByTitleAfterLeadingArticles() + { + var root = ItemsRoot("The Matrix", "A Beautiful Mind", "Avatar"); + + ItemsProxySorting.Apply( + root, + new ItemsProxyControls("SortName", "Ascending", "", 0, 0, "en-US", ""), + CultureInfo.GetCultureInfo("en-US"), + ["a", "an", "the"]); + + Assert.Equal(["Avatar", "A Beautiful Mind", "The Matrix"], ItemNames(root)); + } + + [Fact] + public void ApplyPadsNumbersDuringTitleSort() + { + var root = ItemsRoot("Movie 10", "Movie 2", "Movie 1"); + + ItemsProxySorting.Apply( + root, + new ItemsProxyControls("SortName", "Ascending", "", 0, 0, "en-US", ""), + CultureInfo.GetCultureInfo("en-US"), + []); + + Assert.Equal(["Movie 1", "Movie 2", "Movie 10"], ItemNames(root)); + } + + [Fact] + public void ApplyFiltersAndSlicesAfterLocalSort() + { + var root = ItemsRoot("The Matrix", "Magnolia", "A Monster Calls", "Avatar"); + + ItemsProxySorting.Apply( + root, + new ItemsProxyControls("SortName", "Ascending", "M", 1, 1, "en-US", ""), + CultureInfo.GetCultureInfo("en-US"), + ["a", "an", "the"]); + + Assert.Equal(["The Matrix"], ItemNames(root)); + Assert.Equal(3, root["TotalRecordCount"]!.GetValue()); + Assert.Equal(1, root["StartIndex"]!.GetValue()); + } + + private static JsonObject ItemsRoot(params string[] names) + { + var items = new JsonArray(); + foreach (var name in names) + items.Add(new JsonObject { ["Name"] = name, ["SortName"] = name }); + + return new JsonObject + { + ["Items"] = items, + ["TotalRecordCount"] = names.Length, + ["StartIndex"] = 0 + }; + } + + private static string[] ItemNames(JsonObject root) + => root["Items"]!.AsArray() + .OfType() + .Select(item => item["Name"]!.GetValue()) + .ToArray(); +}