diff options
| author | martimarkov <martimarkov@users.noreply.github.com> | 2026-10-05 19:18:59 -0400 |
|---|---|---|
| committer | Cody Robibero <cody@robibe.ro> | 2026-10-05 19:18:59 -0400 |
| commit | abb7a18434f27d1e0b271315b5dae6fdb82bd589 (patch) | |
| tree | b9da608a1487d8380347eca8e53309a8ca145296 | |
| parent | 0ca7042ed7220a792651032b8dcee3e16042cbbb (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.cs | 4 | ||||
| -rw-r--r-- | tests/Jellyfin.Server.Implementations.Tests/Item/PeopleRepositoryNameRangeTests.cs | 53 |
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); + } +} |
