aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs')
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs121
1 files changed, 120 insertions, 1 deletions
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs
index 535961a66c..9238ec9fd1 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Item/BaseItemRepositoryGroupingTests.cs
@@ -13,13 +13,18 @@ namespace Jellyfin.Server.Implementations.Tests.Item;
public sealed class BaseItemRepositoryGroupingTests : SqliteDbTestFixture
{
+ private static readonly Guid _movieLibraryId = Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa");
+ private static readonly Guid _movie4KLibraryId = Guid.Parse("bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb");
+
private readonly BaseItemRepository _repository;
private readonly string _movieTypeName;
+ private readonly string _folderTypeName;
public BaseItemRepositoryGroupingTests()
{
var itemTypeLookup = new ItemTypeLookup();
_movieTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Movie];
+ _folderTypeName = itemTypeLookup.BaseItemKindNames[BaseItemKind.Folder];
_repository = CreateBaseItemRepository(itemTypeLookup);
}
@@ -67,6 +72,118 @@ public sealed class BaseItemRepositoryGroupingTests : SqliteDbTestFixture
Assert.Equal(firstId, item.Id);
}
+ [Fact]
+ public void GetItemList_LibraryWithoutThePrimaryOfTheGroup_KeepsTheVersionVisible()
+ {
+ var primaryId = Guid.Parse("33333333-3333-3333-3333-333333333333");
+ var versionId = Guid.Parse("44444444-4444-4444-4444-444444444444");
+ var sameLibraryPrimaryId = Guid.Parse("55555555-5555-5555-5555-555555555555");
+ var sameLibraryVersionId = Guid.Parse("66666666-6666-6666-6666-666666666666");
+
+ SeedCrossLibraryGroup(primaryId, versionId, sameLibraryPrimaryId, sameLibraryVersionId);
+
+ var result = _repository.GetItemList(CreateLibraryQuery(_movieLibraryId));
+
+ // The version stands in for the group in the library it lives in, because its primary is in
+ // a library of its own; a group merged inside this library still collapses onto its primary.
+ Assert.Contains(result, i => i.Id.Equals(versionId));
+ Assert.Contains(result, i => i.Id.Equals(sameLibraryPrimaryId));
+ Assert.DoesNotContain(result, i => i.Id.Equals(sameLibraryVersionId));
+ Assert.DoesNotContain(result, i => i.Id.Equals(primaryId));
+ }
+
+ [Fact]
+ public void GetItemList_LibraryHoldingThePrimary_ReturnsThePrimary()
+ {
+ var primaryId = Guid.Parse("33333333-3333-3333-3333-333333333333");
+ var versionId = Guid.Parse("44444444-4444-4444-4444-444444444444");
+
+ SeedCrossLibraryGroup(primaryId, versionId);
+
+ var result = _repository.GetItemList(CreateLibraryQuery(_movie4KLibraryId));
+
+ var item = Assert.Single(result);
+ Assert.Equal(primaryId, item.Id);
+ }
+
+ [Fact]
+ public void GetItemList_BothLibrariesOfACrossLibraryGroup_ReturnsItOnce()
+ {
+ var primaryId = Guid.Parse("33333333-3333-3333-3333-333333333333");
+ var versionId = Guid.Parse("44444444-4444-4444-4444-444444444444");
+
+ SeedCrossLibraryGroup(primaryId, versionId);
+
+ var result = _repository.GetItemList(CreateLibraryQuery(_movieLibraryId, _movie4KLibraryId));
+
+ // With both libraries in scope the presentation key grouping collapses the version.
+ var item = Assert.Single(result);
+ Assert.Equal(primaryId, item.Id);
+ }
+
+ [Fact]
+ public void GetItems_LibraryWithoutThePrimaryOfTheGroup_CountsWhatItLists()
+ {
+ var primaryId = Guid.Parse("33333333-3333-3333-3333-333333333333");
+ var versionId = Guid.Parse("44444444-4444-4444-4444-444444444444");
+
+ SeedCrossLibraryGroup(primaryId, versionId);
+
+ var listed = _repository.GetItemList(CreateLibraryQuery(_movieLibraryId)).Count;
+
+ var query = CreateLibraryQuery(_movieLibraryId);
+ query.EnableTotalRecordCount = true;
+ query.Limit = 1;
+
+ // The total the client pages against has to agree with the listing.
+ Assert.Equal(1, listed);
+ Assert.Equal(listed, _repository.GetItems(query).TotalRecordCount);
+ }
+
+ private static InternalItemsQuery CreateLibraryQuery(params Guid[] topParentIds)
+ {
+ return new InternalItemsQuery(new Database.Implementations.Entities.User("test", "auth", "reset"))
+ {
+ IncludeItemTypes = [BaseItemKind.Movie],
+ TopParentIds = topParentIds
+ };
+ }
+
+ private void SeedCrossLibraryGroup(
+ Guid primaryId,
+ Guid versionId,
+ Guid? sameLibraryPrimaryId = null,
+ Guid? sameLibraryVersionId = null)
+ {
+ using var ctx = CreateDbContext();
+ ctx.BaseItems.Add(CreateFolderEntity(_movieLibraryId, "Movies"));
+ ctx.BaseItems.Add(CreateFolderEntity(_movie4KLibraryId, "Movies-4K"));
+
+ // The 4K version heads the group and lives in a library of its own.
+ ctx.BaseItems.Add(CreateMovieEntity(primaryId, "Movie - 4K", primaryId.ToString("N"), null, _movie4KLibraryId));
+ ctx.BaseItems.Add(CreateMovieEntity(versionId, "Movie", primaryId.ToString("N"), primaryId, _movieLibraryId));
+
+ if (sameLibraryPrimaryId.HasValue && sameLibraryVersionId.HasValue)
+ {
+ ctx.BaseItems.Add(CreateMovieEntity(sameLibraryPrimaryId.Value, "Other - 4K", sameLibraryPrimaryId.Value.ToString("N"), null, _movieLibraryId));
+ ctx.BaseItems.Add(CreateMovieEntity(sameLibraryVersionId.Value, "Other", sameLibraryPrimaryId.Value.ToString("N"), sameLibraryPrimaryId.Value, _movieLibraryId));
+ }
+
+ ctx.SaveChanges();
+ }
+
+ private BaseItemEntity CreateFolderEntity(Guid id, string name)
+ {
+ return new BaseItemEntity
+ {
+ Id = id,
+ Type = _folderTypeName,
+ Name = name,
+ Path = "/" + name,
+ IsFolder = true
+ };
+ }
+
private static InternalItemsQuery CreateQuery()
{
// IncludeOwnedItems keeps the alternate version rows in the query so the
@@ -78,13 +195,15 @@ public sealed class BaseItemRepositoryGroupingTests : SqliteDbTestFixture
};
}
- private BaseItemEntity CreateMovieEntity(Guid id, string name, string presentationKey, Guid? primaryVersionId)
+ private BaseItemEntity CreateMovieEntity(Guid id, string name, string presentationKey, Guid? primaryVersionId, Guid? libraryId = null)
{
return new BaseItemEntity
{
Id = id,
Type = _movieTypeName,
Name = name,
+ ParentId = libraryId,
+ TopParentId = libraryId,
PresentationUniqueKey = presentationKey,
PrimaryVersionId = primaryVersionId,
MediaType = "Video",