aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartimarkov <martimarkov@users.noreply.github.com>2026-10-05 19:18:59 -0400
committerCody Robibero <cody@robibe.ro>2026-10-05 19:18:59 -0400
commitabb7a18434f27d1e0b271315b5dae6fdb82bd589 (patch)
treeb9da608a1487d8380347eca8e53309a8ca145296
parent0ca7042ed7220a792651032b8dcee3e16042cbbb (diff)
Backport pull request #18265 from jellyfin/release-12.z
Compare person names without regard to case in the letter range filters Original-merge: 03544979c8892d25b06d62534f17cc8a67bfe1e7 Merged-by: crobibero <cody@robibe.ro> Backported-by: Cody Robibero <cody@robibe.ro>
-rw-r--r--Jellyfin.Server.Implementations/Item/PeopleRepository.cs4
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Item/PeopleRepositoryNameRangeTests.cs53
2 files changed, 55 insertions, 2 deletions
diff --git a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs
index bc79699486..802138ed5e 100644
--- a/Jellyfin.Server.Implementations/Item/PeopleRepository.cs
+++ b/Jellyfin.Server.Implementations/Item/PeopleRepository.cs
@@ -484,12 +484,12 @@ public class PeopleRepository(IDbContextFactory<JellyfinDbContext> dbProvider, I
if (!string.IsNullOrWhiteSpace(filter.NameLessThan))
{
- query = query.Where(e => e.Name.CompareTo(filter.NameLessThan.ToLowerInvariant()) < 0);
+ query = query.Where(e => e.Name.ToLower().CompareTo(filter.NameLessThan.ToLowerInvariant()) < 0);
}
if (!string.IsNullOrWhiteSpace(filter.NameStartsWithOrGreater))
{
- query = query.Where(e => e.Name.CompareTo(filter.NameStartsWithOrGreater.ToLowerInvariant()) >= 0);
+ query = query.Where(e => e.Name.ToLower().CompareTo(filter.NameStartsWithOrGreater.ToLowerInvariant()) >= 0);
}
return query;
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Item/PeopleRepositoryNameRangeTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Item/PeopleRepositoryNameRangeTests.cs
new file mode 100644
index 0000000000..754b388ecf
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Item/PeopleRepositoryNameRangeTests.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Linq;
+using Emby.Server.Implementations.Data;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Server.Implementations.Item;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Persistence;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Item;
+
+/// <summary>
+/// The letter picker on the person list filters with <c>NameStartsWithOrGreater</c> and <c>NameLessThan</c>.
+/// Names keep the case a metadata provider wrote them in, so the range has to ignore case the same way
+/// the list is sorted, or a capitalised name lands before every lowercase bound.
+/// </summary>
+public sealed class PeopleRepositoryNameRangeTests : SqliteDbTestFixture
+{
+ private readonly PeopleRepository _repository;
+
+ public PeopleRepositoryNameRangeTests()
+ {
+ using (var context = CreateDbContext())
+ {
+ foreach (var name in new[] { "50 Cent", "alpha centauri", "Brad Pitt", "bob dylan", "Zoe Saldana" })
+ {
+ context.Peoples.Add(new People { Id = Guid.NewGuid(), Name = name, PersonType = "Actor" });
+ }
+
+ context.SaveChanges();
+ }
+
+ _repository = new PeopleRepository(CreateDbContextFactory(), new ItemTypeLookup(), new Mock<IItemQueryHelpers>().Object);
+ }
+
+ [Theory]
+ [InlineData(null, "A", new[] { "50 Cent" })]
+ [InlineData(null, "C", new[] { "50 Cent", "alpha centauri", "bob dylan", "Brad Pitt" })]
+ [InlineData("B", "C", new[] { "bob dylan", "Brad Pitt" })]
+ [InlineData("Y", null, new[] { "Zoe Saldana" })]
+ public void GetPeople_NameRange_IgnoresCase(string? nameStartsWithOrGreater, string? nameLessThan, string[] expected)
+ {
+ var result = _repository.GetPeople(new InternalPeopleQuery
+ {
+ NameStartsWithOrGreater = nameStartsWithOrGreater,
+ NameLessThan = nameLessThan
+ });
+
+ Assert.Equal(expected, result.Items.Select(p => p.Name));
+ Assert.Equal(expected.Length, result.TotalRecordCount);
+ }
+}