Merge pull request #12798 from JPVenson/feature/EFUserData

Refactor library.db into jellyfin.db and EFCore
This commit is contained in:
Joshua M. Boniface
2025-01-25 02:08:44 -05:00
committed by GitHub
160 changed files with 20076 additions and 7497 deletions

View File

@@ -65,7 +65,7 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
Assert.True(res.VideoStream.IsDefault);
Assert.False(res.VideoStream.IsExternal);
Assert.False(res.VideoStream.IsForced);
Assert.False(res.VideoStream.IsHearingImpaired);
Assert.False(res.VideoStream.IsHearingImpaired.GetValueOrDefault());
Assert.False(res.VideoStream.IsInterlaced);
Assert.False(res.VideoStream.IsTextSubtitleStream);
Assert.Equal(13d, res.VideoStream.Level);
@@ -152,19 +152,19 @@ namespace Jellyfin.MediaEncoding.Tests.Probing
Assert.Equal(MediaStreamType.Subtitle, res.MediaStreams[3].Type);
Assert.Equal("DVDSUB", res.MediaStreams[3].Codec);
Assert.Null(res.MediaStreams[3].Title);
Assert.False(res.MediaStreams[3].IsHearingImpaired);
Assert.False(res.MediaStreams[3].IsHearingImpaired.GetValueOrDefault());
Assert.Equal("eng", res.MediaStreams[4].Language);
Assert.Equal(MediaStreamType.Subtitle, res.MediaStreams[4].Type);
Assert.Equal("mov_text", res.MediaStreams[4].Codec);
Assert.Null(res.MediaStreams[4].Title);
Assert.True(res.MediaStreams[4].IsHearingImpaired);
Assert.True(res.MediaStreams[4].IsHearingImpaired.GetValueOrDefault());
Assert.Equal("eng", res.MediaStreams[5].Language);
Assert.Equal(MediaStreamType.Subtitle, res.MediaStreams[5].Type);
Assert.Equal("mov_text", res.MediaStreams[5].Codec);
Assert.Equal("Commentary", res.MediaStreams[5].Title);
Assert.False(res.MediaStreams[5].IsHearingImpaired);
Assert.False(res.MediaStreams[5].IsHearingImpaired.GetValueOrDefault());
}
[Fact]

View File

@@ -330,7 +330,7 @@ namespace Jellyfin.Providers.Tests.Manager
MetadataService<Movie, MovieInfo>.MergeBaseItemData(source, target, lockedFields, replaceData, false);
actualValue = target.People;
return newValue?.Equals(actualValue) ?? actualValue is null;
return newValue?.SequenceEqual((IEnumerable<PersonInfo>)actualValue!) ?? actualValue is null;
}
/// <summary>

View File

@@ -3,8 +3,10 @@ using System.Collections.Generic;
using AutoFixture;
using AutoFixture.AutoMoq;
using Emby.Server.Implementations.Data;
using Jellyfin.Server.Implementations.Item;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using Microsoft.Extensions.Configuration;
using Moq;
@@ -18,7 +20,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data
public const string MetaDataPath = "/meta/data/path";
private readonly IFixture _fixture;
private readonly SqliteItemRepository _sqliteItemRepository;
private readonly BaseItemRepository _sqliteItemRepository;
public SqliteItemRepositoryTests()
{
@@ -40,7 +42,7 @@ namespace Jellyfin.Server.Implementations.Tests.Data
_fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
_fixture.Inject(appHost);
_fixture.Inject(config);
_sqliteItemRepository = _fixture.Create<SqliteItemRepository>();
_sqliteItemRepository = _fixture.Create<BaseItemRepository>();
}
public static TheoryData<string, ItemImageInfo> ItemImageInfoFromValueString_Valid_TestData()
@@ -97,31 +99,6 @@ namespace Jellyfin.Server.Implementations.Tests.Data
return data;
}
[Theory]
[MemberData(nameof(ItemImageInfoFromValueString_Valid_TestData))]
public void ItemImageInfoFromValueString_Valid_Success(string value, ItemImageInfo expected)
{
var result = _sqliteItemRepository.ItemImageInfoFromValueString(value);
Assert.Equal(expected.Path, result.Path);
Assert.Equal(expected.Type, result.Type);
Assert.Equal(expected.DateModified, result.DateModified);
Assert.Equal(expected.Width, result.Width);
Assert.Equal(expected.Height, result.Height);
Assert.Equal(expected.BlurHash, result.BlurHash);
}
[Theory]
[InlineData("")]
[InlineData("*")]
[InlineData("https://image.tmdb.org/t/p/original/zhB5CHEgqqh4wnEqDNJLfWXJlcL.jpg*0")]
[InlineData("/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg*6374520964785129080*WjQbtJtSO8nhNZ%L_Io#R/oaS<o}-;adXAoIn7j[%hW9s:WGw[nN")] // Invalid modified date
[InlineData("/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg*-637452096478512963*WjQbtJtSO8nhNZ%L_Io#R/oaS<o}-;adXAoIn7j[%hW9s:WGw[nN")] // Negative modified date
[InlineData("/mnt/series/Family Guy/Season 1/Family Guy - S01E01-thumb.jpg*637452096478512963*Invalid*1920*1080*WjQbtJtSO8nhNZ%L_Io#R/oaS6o}-;adXAoIn7j[%hW9s:WGw[nN")] // Invalid type
public void ItemImageInfoFromValueString_Invalid_Null(string value)
{
Assert.Null(_sqliteItemRepository.ItemImageInfoFromValueString(value));
}
public static TheoryData<string, ItemImageInfo[]> DeserializeImages_Valid_TestData()
{
var data = new TheoryData<string, ItemImageInfo[]>();
@@ -202,97 +179,6 @@ namespace Jellyfin.Server.Implementations.Tests.Data
return data;
}
[Theory]
[MemberData(nameof(DeserializeImages_Valid_TestData))]
public void DeserializeImages_Valid_Success(string value, ItemImageInfo[] expected)
{
var result = _sqliteItemRepository.DeserializeImages(value);
Assert.Equal(expected.Length, result.Length);
for (int i = 0; i < expected.Length; i++)
{
Assert.Equal(expected[i].Path, result[i].Path);
Assert.Equal(expected[i].Type, result[i].Type);
Assert.Equal(expected[i].DateModified, result[i].DateModified);
Assert.Equal(expected[i].Width, result[i].Width);
Assert.Equal(expected[i].Height, result[i].Height);
Assert.Equal(expected[i].BlurHash, result[i].BlurHash);
}
}
[Theory]
[MemberData(nameof(DeserializeImages_ValidAndInvalid_TestData))]
public void DeserializeImages_ValidAndInvalid_Success(string value, ItemImageInfo[] expected)
{
var result = _sqliteItemRepository.DeserializeImages(value);
Assert.Equal(expected.Length, result.Length);
for (int i = 0; i < expected.Length; i++)
{
Assert.Equal(expected[i].Path, result[i].Path);
Assert.Equal(expected[i].Type, result[i].Type);
Assert.Equal(expected[i].DateModified, result[i].DateModified);
Assert.Equal(expected[i].Width, result[i].Width);
Assert.Equal(expected[i].Height, result[i].Height);
Assert.Equal(expected[i].BlurHash, result[i].BlurHash);
}
}
[Theory]
[MemberData(nameof(DeserializeImages_Valid_TestData))]
public void SerializeImages_Valid_Success(string expected, ItemImageInfo[] value)
{
Assert.Equal(expected, _sqliteItemRepository.SerializeImages(value));
}
public static TheoryData<string, Dictionary<string, string>> DeserializeProviderIds_Valid_TestData()
{
var data = new TheoryData<string, Dictionary<string, string>>();
data.Add(
"Imdb=tt0119567",
new Dictionary<string, string>()
{
{ "Imdb", "tt0119567" },
});
data.Add(
"Imdb=tt0119567|Tmdb=330|TmdbCollection=328",
new Dictionary<string, string>()
{
{ "Imdb", "tt0119567" },
{ "Tmdb", "330" },
{ "TmdbCollection", "328" },
});
data.Add(
"MusicBrainzAlbum=9d363e43-f24f-4b39-bc5a-7ef305c677c7|MusicBrainzReleaseGroup=63eba062-847c-3b73-8b0f-6baf27bba6fa|AudioDbArtist=111352|AudioDbAlbum=2116560|MusicBrainzAlbumArtist=20244d07-534f-4eff-b4d4-930878889970",
new Dictionary<string, string>()
{
{ "MusicBrainzAlbum", "9d363e43-f24f-4b39-bc5a-7ef305c677c7" },
{ "MusicBrainzReleaseGroup", "63eba062-847c-3b73-8b0f-6baf27bba6fa" },
{ "AudioDbArtist", "111352" },
{ "AudioDbAlbum", "2116560" },
{ "MusicBrainzAlbumArtist", "20244d07-534f-4eff-b4d4-930878889970" },
});
return data;
}
[Theory]
[MemberData(nameof(DeserializeProviderIds_Valid_TestData))]
public void DeserializeProviderIds_Valid_Success(string value, Dictionary<string, string> expected)
{
var result = new ProviderIdsExtensionsTestsObject();
SqliteItemRepository.DeserializeProviderIds(value, result);
Assert.Equal(expected, result.ProviderIds);
}
[Theory]
[MemberData(nameof(DeserializeProviderIds_Valid_TestData))]
public void SerializeProviderIds_Valid_Success(string expected, Dictionary<string, string> values)
{
Assert.Equal(expected, SqliteItemRepository.SerializeProviderIds(values));
}
private sealed class ProviderIdsExtensionsTestsObject : IHasProviderIds
{
public Dictionary<string, string> ProviderIds { get; set; } = new Dictionary<string, string>();

View File

@@ -45,7 +45,7 @@ public sealed class LibraryStructureControllerTests : IClassFixture<JellyfinAppl
}
[Fact]
[Priority(0)]
[Priority(-2)]
public async Task UpdateLibraryOptions_Invalid_NotFound()
{
var client = _factory.CreateClient();
@@ -62,12 +62,23 @@ public sealed class LibraryStructureControllerTests : IClassFixture<JellyfinAppl
}
[Fact]
[Priority(0)]
[Priority(-2)]
public async Task UpdateLibraryOptions_Valid_Success()
{
var client = _factory.CreateClient();
client.DefaultRequestHeaders.AddAuthHeader(_accessToken ??= await AuthHelper.CompleteStartupAsync(client));
var createBody = new AddVirtualFolderDto()
{
LibraryOptions = new LibraryOptions()
{
Enabled = false
}
};
using var createResponse = await client.PostAsJsonAsync("Library/VirtualFolders?name=test&refreshLibrary=true", createBody, _jsonOptions);
Assert.Equal(HttpStatusCode.NoContent, createResponse.StatusCode);
using var response = await client.GetAsync("Library/VirtualFolders");
Assert.Equal(HttpStatusCode.OK, response.StatusCode);

View File

@@ -149,7 +149,7 @@ namespace Jellyfin.XbmcMetadata.Tests.Parsers
Assert.Equal(new DateTime(2019, 8, 6, 9, 1, 18), item.DateCreated);
// userData
var userData = _userDataManager.GetUserData(_testUser, item);
var userData = _userDataManager.GetUserData(_testUser, item)!;
Assert.Equal(2, userData.PlayCount);
Assert.True(userData.Played);
Assert.Equal(new DateTime(2021, 02, 11, 07, 47, 23), userData.LastPlayedDate);