aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Server.Implementations.Tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Jellyfin.Server.Implementations.Tests')
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs122
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/EfMigrations/EfMigrationTests.cs9
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs184
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Item/OrderMapperTests.cs35
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj1
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/DotIgnoreIgnoreRuleTest.cs30
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs95
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Playlists/PlaylistManagerTests.cs40
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs5
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/SessionManager/SessionManagerTests.cs2
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest.json2
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs4
12 files changed, 296 insertions, 233 deletions
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs
index 0d2b488bc..105f5d7af 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Data/SqliteItemRepositoryTests.cs
@@ -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>();
diff --git a/tests/Jellyfin.Server.Implementations.Tests/EfMigrations/EfMigrationTests.cs b/tests/Jellyfin.Server.Implementations.Tests/EfMigrations/EfMigrationTests.cs
index e6ccae183..ba3abd5a2 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/EfMigrations/EfMigrationTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/EfMigrations/EfMigrationTests.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Threading.Tasks;
+using Jellyfin.Database.Providers.Sqlite.Migrations;
using Jellyfin.Server.Implementations.Migrations;
using Microsoft.EntityFrameworkCore;
using Xunit;
@@ -9,10 +8,10 @@ namespace Jellyfin.Server.Implementations.Tests.EfMigrations;
public class EfMigrationTests
{
[Fact]
- public void CheckForUnappliedMigrations()
+ public void CheckForUnappliedMigrations_SqLite()
{
- var dbDesignContext = new DesignTimeJellyfinDbFactory();
+ var dbDesignContext = new SqliteDesignTimeJellyfinDbFactory();
var context = dbDesignContext.CreateDbContext([]);
- Assert.False(context.Database.HasPendingModelChanges(), "There are unapplied changes to the EfCore model. Please create a Migration.");
+ Assert.False(context.Database.HasPendingModelChanges(), "There are unapplied changes to the EFCore model for SQLite. Please create a Migration.");
}
}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs b/tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs
index 95a5b8179..6997b51ac 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/IO/ManagedFileSystemTests.cs
@@ -5,83 +5,119 @@ using System.Runtime.InteropServices;
using AutoFixture;
using AutoFixture.AutoMoq;
using Emby.Server.Implementations.IO;
+using Jellyfin.Extensions;
using Xunit;
-namespace Jellyfin.Server.Implementations.Tests.IO
+namespace Jellyfin.Server.Implementations.Tests.IO;
+
+public class ManagedFileSystemTests
{
- public class ManagedFileSystemTests
+ private readonly IFixture _fixture;
+ private readonly ManagedFileSystem _sut;
+
+ public ManagedFileSystemTests()
+ {
+ _fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
+ _sut = _fixture.Create<ManagedFileSystem>();
+ }
+
+ [Fact]
+ public void MoveDirectory_SameFileSystem_Correct()
+ => MoveDirectoryInternal();
+
+ [SkippableFact]
+ public void MoveDirectory_DifferentFileSystem_Correct()
+ {
+ const string DestinationParent = "/dev/shm";
+
+ Skip.IfNot(Directory.Exists(DestinationParent));
+
+ MoveDirectoryInternal(DestinationParent);
+ }
+
+ internal void MoveDirectoryInternal(string? destinationParent = null)
{
- private readonly IFixture _fixture;
- private readonly ManagedFileSystem _sut;
-
- public ManagedFileSystemTests()
- {
- _fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
- _sut = _fixture.Create<ManagedFileSystem>();
- }
-
- [SkippableTheory]
- [InlineData("/Volumes/Library/Sample/Music/Playlists/", "../Beethoven/Misc/Moonlight Sonata.mp3", "/Volumes/Library/Sample/Music/Beethoven/Misc/Moonlight Sonata.mp3")]
- [InlineData("/Volumes/Library/Sample/Music/Playlists/", "../../Beethoven/Misc/Moonlight Sonata.mp3", "/Volumes/Library/Sample/Beethoven/Misc/Moonlight Sonata.mp3")]
- [InlineData("/Volumes/Library/Sample/Music/Playlists/", "Beethoven/Misc/Moonlight Sonata.mp3", "/Volumes/Library/Sample/Music/Playlists/Beethoven/Misc/Moonlight Sonata.mp3")]
- [InlineData("/Volumes/Library/Sample/Music/Playlists/", "/mnt/Beethoven/Misc/Moonlight Sonata.mp3", "/mnt/Beethoven/Misc/Moonlight Sonata.mp3")]
- public void MakeAbsolutePathCorrectlyHandlesRelativeFilePathsOnUnixLike(
- string folderPath,
- string filePath,
- string expectedAbsolutePath)
- {
- Skip.If(OperatingSystem.IsWindows());
-
- var generatedPath = _sut.MakeAbsolutePath(folderPath, filePath);
- Assert.Equal(expectedAbsolutePath, generatedPath);
- }
-
- [SkippableTheory]
- [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"..\Beethoven\Misc\Moonlight Sonata.mp3", @"C:\Volumes\Library\Sample\Music\Beethoven\Misc\Moonlight Sonata.mp3")]
- [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"..\..\Beethoven\Misc\Moonlight Sonata.mp3", @"C:\Volumes\Library\Sample\Beethoven\Misc\Moonlight Sonata.mp3")]
- [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"Beethoven\Misc\Moonlight Sonata.mp3", @"C:\Volumes\Library\Sample\Music\Playlists\Beethoven\Misc\Moonlight Sonata.mp3")]
- [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"D:\\Beethoven\Misc\Moonlight Sonata.mp3", @"D:\\Beethoven\Misc\Moonlight Sonata.mp3")]
- public void MakeAbsolutePathCorrectlyHandlesRelativeFilePathsOnWindows(
- string folderPath,
- string filePath,
- string expectedAbsolutePath)
- {
- Skip.If(!OperatingSystem.IsWindows());
-
- var generatedPath = _sut.MakeAbsolutePath(folderPath, filePath);
-
- Assert.Equal(expectedAbsolutePath, generatedPath);
- }
-
- [Theory]
- [InlineData("ValidFileName", "ValidFileName")]
- [InlineData("AC/DC", "AC DC")]
- [InlineData("Invalid\0", "Invalid ")]
- [InlineData("AC/DC\0KD/A", "AC DC KD A")]
- public void GetValidFilename_ReturnsValidFilename(string filename, string expectedFileName)
- {
- Assert.Equal(expectedFileName, _sut.GetValidFilename(filename));
- }
-
- [SkippableFact]
- public void GetFileInfo_DanglingSymlink_ExistsFalse()
- {
- Skip.If(OperatingSystem.IsWindows());
-
- string testFileDir = Path.Combine(Path.GetTempPath(), "jellyfin-test-data");
- string testFileName = Path.Combine(testFileDir, Path.GetRandomFileName() + "-danglingsym.link");
-
- Directory.CreateDirectory(testFileDir);
- Assert.Equal(0, symlink("thispathdoesntexist", testFileName));
- Assert.True(File.Exists(testFileName));
-
- var metadata = _sut.GetFileInfo(testFileName);
- Assert.False(metadata.Exists);
- }
-
- [SuppressMessage("Naming Rules", "SA1300:ElementMustBeginWithUpperCaseLetter", Justification = "Have to")]
- [DllImport("libc", SetLastError = true, CharSet = CharSet.Ansi)]
- [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]
- private static extern int symlink(string target, string linkpath);
+ const string TempFile0 = "tempfile0";
+ const string TempFile1 = "tempfile1";
+
+ destinationParent ??= Path.GetTempPath();
+
+ var sourceDir = Directory.CreateTempSubdirectory();
+ var destinationDir = Path.Join(destinationParent, Path.GetRandomFileName());
+ FileHelper.CreateEmpty(Path.Join(sourceDir.FullName, TempFile0));
+ FileHelper.CreateEmpty(Path.Join(sourceDir.FullName, TempFile1));
+
+ _sut.MoveDirectory(sourceDir.FullName, destinationDir);
+
+ Assert.True(Directory.Exists(destinationDir));
+ Assert.True(File.Exists(Path.Join(destinationDir, TempFile0)));
+ Assert.True(File.Exists(Path.Join(destinationDir, TempFile1)));
+ Assert.False(Directory.Exists(sourceDir.FullName));
+
+ Directory.Delete(destinationDir, true);
}
+
+ [SkippableTheory]
+ [InlineData("/Volumes/Library/Sample/Music/Playlists/", "../Beethoven/Misc/Moonlight Sonata.mp3", "/Volumes/Library/Sample/Music/Beethoven/Misc/Moonlight Sonata.mp3")]
+ [InlineData("/Volumes/Library/Sample/Music/Playlists/", "../../Beethoven/Misc/Moonlight Sonata.mp3", "/Volumes/Library/Sample/Beethoven/Misc/Moonlight Sonata.mp3")]
+ [InlineData("/Volumes/Library/Sample/Music/Playlists/", "Beethoven/Misc/Moonlight Sonata.mp3", "/Volumes/Library/Sample/Music/Playlists/Beethoven/Misc/Moonlight Sonata.mp3")]
+ [InlineData("/Volumes/Library/Sample/Music/Playlists/", "/mnt/Beethoven/Misc/Moonlight Sonata.mp3", "/mnt/Beethoven/Misc/Moonlight Sonata.mp3")]
+ public void MakeAbsolutePathCorrectlyHandlesRelativeFilePathsOnUnixLike(
+ string folderPath,
+ string filePath,
+ string expectedAbsolutePath)
+ {
+ Skip.If(OperatingSystem.IsWindows());
+
+ var generatedPath = _sut.MakeAbsolutePath(folderPath, filePath);
+ Assert.Equal(expectedAbsolutePath, generatedPath);
+ }
+
+ [SkippableTheory]
+ [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"..\Beethoven\Misc\Moonlight Sonata.mp3", @"C:\Volumes\Library\Sample\Music\Beethoven\Misc\Moonlight Sonata.mp3")]
+ [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"..\..\Beethoven\Misc\Moonlight Sonata.mp3", @"C:\Volumes\Library\Sample\Beethoven\Misc\Moonlight Sonata.mp3")]
+ [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"Beethoven\Misc\Moonlight Sonata.mp3", @"C:\Volumes\Library\Sample\Music\Playlists\Beethoven\Misc\Moonlight Sonata.mp3")]
+ [InlineData(@"C:\\Volumes\Library\Sample\Music\Playlists\", @"D:\\Beethoven\Misc\Moonlight Sonata.mp3", @"D:\\Beethoven\Misc\Moonlight Sonata.mp3")]
+ public void MakeAbsolutePathCorrectlyHandlesRelativeFilePathsOnWindows(
+ string folderPath,
+ string filePath,
+ string expectedAbsolutePath)
+ {
+ Skip.IfNot(OperatingSystem.IsWindows());
+
+ var generatedPath = _sut.MakeAbsolutePath(folderPath, filePath);
+
+ Assert.Equal(expectedAbsolutePath, generatedPath);
+ }
+
+ [Theory]
+ [InlineData("ValidFileName", "ValidFileName")]
+ [InlineData("AC/DC", "AC DC")]
+ [InlineData("Invalid\0", "Invalid ")]
+ [InlineData("AC/DC\0KD/A", "AC DC KD A")]
+ public void GetValidFilename_ReturnsValidFilename(string filename, string expectedFileName)
+ {
+ Assert.Equal(expectedFileName, _sut.GetValidFilename(filename));
+ }
+
+ [SkippableFact]
+ public void GetFileInfo_DanglingSymlink_ExistsFalse()
+ {
+ Skip.If(OperatingSystem.IsWindows());
+
+ string testFileDir = Path.Combine(Path.GetTempPath(), "jellyfin-test-data");
+ string testFileName = Path.Combine(testFileDir, Path.GetRandomFileName() + "-danglingsym.link");
+
+ Directory.CreateDirectory(testFileDir);
+ Assert.Equal(0, symlink("thispathdoesntexist", testFileName));
+ Assert.True(File.Exists(testFileName));
+
+ var metadata = _sut.GetFileInfo(testFileName);
+ Assert.False(metadata.Exists);
+ }
+
+ [SuppressMessage("Naming Rules", "SA1300:ElementMustBeginWithUpperCaseLetter", Justification = "Have to")]
+ [DllImport("libc", SetLastError = true, CharSet = CharSet.Ansi)]
+ [DefaultDllImportSearchPaths(DllImportSearchPath.UserDirectories)]
+ private static extern int symlink(string target, string linkpath);
}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Item/OrderMapperTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Item/OrderMapperTests.cs
new file mode 100644
index 000000000..caf2b06b7
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Item/OrderMapperTests.cs
@@ -0,0 +1,35 @@
+using System;
+using Jellyfin.Data.Enums;
+using Jellyfin.Database.Implementations.Entities;
+using Jellyfin.Server.Implementations.Item;
+using MediaBrowser.Controller.Entities;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Item;
+
+public class OrderMapperTests
+{
+ [Fact]
+ public void ShouldReturnMappedOrderForSortingByPremierDate()
+ {
+ var orderFunc = OrderMapper.MapOrderByField(ItemSortBy.PremiereDate, new InternalItemsQuery()).Compile();
+
+ var expectedDate = new DateTime(1, 2, 3);
+ var expectedProductionYearDate = new DateTime(4, 1, 1);
+
+ var entityWithOnlyProductionYear = new BaseItemEntity { Id = Guid.NewGuid(), Type = "Test", ProductionYear = expectedProductionYearDate.Year };
+ var entityWithOnlyPremierDate = new BaseItemEntity { Id = Guid.NewGuid(), Type = "Test", PremiereDate = expectedDate };
+ var entityWithBothPremierDateAndProductionYear = new BaseItemEntity { Id = Guid.NewGuid(), Type = "Test", PremiereDate = expectedDate, ProductionYear = expectedProductionYearDate.Year };
+ var entityWithoutEitherPremierDateOrProductionYear = new BaseItemEntity { Id = Guid.NewGuid(), Type = "Test" };
+
+ var resultWithOnlyProductionYear = orderFunc(entityWithOnlyProductionYear);
+ var resultWithOnlyPremierDate = orderFunc(entityWithOnlyPremierDate);
+ var resultWithBothPremierDateAndProductionYear = orderFunc(entityWithBothPremierDateAndProductionYear);
+ var resultWithoutEitherPremierDateOrProductionYear = orderFunc(entityWithoutEitherPremierDateOrProductionYear);
+
+ Assert.Equal(resultWithOnlyProductionYear, expectedProductionYearDate);
+ Assert.Equal(resultWithOnlyPremierDate, expectedDate);
+ Assert.Equal(resultWithBothPremierDateAndProductionYear, expectedDate);
+ Assert.Null(resultWithoutEitherPremierDateOrProductionYear);
+ }
+}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj
index 4f018ba69..4e2604e6e 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj
+++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj
@@ -29,6 +29,7 @@
<ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
<ProjectReference Include="..\..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
<ProjectReference Include="..\Jellyfin.Server.Integration.Tests\Jellyfin.Server.Integration.Tests.csproj" />
+ <ProjectReference Include="..\..\src\Jellyfin.Database\Jellyfin.Database.Implementations\Jellyfin.Database.Implementations.csproj" />
</ItemGroup>
</Project>
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/DotIgnoreIgnoreRuleTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/DotIgnoreIgnoreRuleTest.cs
new file mode 100644
index 000000000..d677c9f09
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/DotIgnoreIgnoreRuleTest.cs
@@ -0,0 +1,30 @@
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Library;
+
+public class DotIgnoreIgnoreRuleTest
+{
+ [Fact]
+ public void Test()
+ {
+ var ignore = new Ignore.Ignore();
+ ignore.Add("SPs");
+ Assert.True(ignore.IsIgnored("f:/cd/sps/ffffff.mkv"));
+ Assert.True(ignore.IsIgnored("cd/sps/ffffff.mkv"));
+ Assert.True(ignore.IsIgnored("/cd/sps/ffffff.mkv"));
+ }
+
+ [Fact]
+ public void TestNegatePattern()
+ {
+ var ignore = new Ignore.Ignore();
+ ignore.Add("SPs");
+ ignore.Add("!thebestshot.mkv");
+ Assert.True(ignore.IsIgnored("f:/cd/sps/ffffff.mkv"));
+ Assert.True(ignore.IsIgnored("cd/sps/ffffff.mkv"));
+ Assert.True(ignore.IsIgnored("/cd/sps/ffffff.mkv"));
+ Assert.True(!ignore.IsIgnored("f:/cd/sps/thebestshot.mkv"));
+ Assert.True(!ignore.IsIgnored("cd/sps/thebestshot.mkv"));
+ Assert.True(!ignore.IsIgnored("/cd/sps/thebestshot.mkv"));
+ }
+}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
index 0afbf7e63..a7a1e5e81 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Localization/LocalizationManagerTests.cs
@@ -1,7 +1,7 @@
using System;
using System.Linq;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
+using BitFaster.Caching;
using Emby.Server.Implementations.Localization;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Model.Configuration;
@@ -45,15 +45,40 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
var germany = cultures.FirstOrDefault(x => x.TwoLetterISOLanguageName.Equals("de", StringComparison.Ordinal));
Assert.NotNull(germany);
- Assert.Equal("ger", germany!.ThreeLetterISOLanguageName);
+ Assert.Equal("deu", germany!.ThreeLetterISOLanguageName);
Assert.Equal("German", germany.DisplayName);
Assert.Equal("German", germany.Name);
Assert.Contains("deu", germany.ThreeLetterISOLanguageNames);
Assert.Contains("ger", germany.ThreeLetterISOLanguageNames);
}
+ [Fact]
+ public async Task TryGetISO6392TFromB_Success()
+ {
+ var localizationManager = Setup(new ServerConfiguration
+ {
+ UICulture = "de-DE"
+ });
+ await localizationManager.LoadAll();
+
+ string? isoT;
+
+ // Translation ger -> deu
+ Assert.True(localizationManager.TryGetISO6392TFromB("ger", out isoT));
+ Assert.Equal("deu", isoT);
+
+ // chi -> zho
+ Assert.True(localizationManager.TryGetISO6392TFromB("chi", out isoT));
+ Assert.Equal("zho", isoT);
+
+ // eng is already ISO 639-2/T
+ Assert.False(localizationManager.TryGetISO6392TFromB("eng", out isoT));
+ Assert.Null(isoT);
+ }
+
[Theory]
[InlineData("de")]
+ [InlineData("deu")]
[InlineData("ger")]
[InlineData("german")]
public async Task FindLanguageInfo_Valid_Success(string identifier)
@@ -67,7 +92,7 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
var germany = localizationManager.FindLanguageInfo(identifier);
Assert.NotNull(germany);
- Assert.Equal("ger", germany!.ThreeLetterISOLanguageName);
+ Assert.Equal("deu", germany!.ThreeLetterISOLanguageName);
Assert.Equal("German", germany.DisplayName);
Assert.Equal("German", germany.Name);
Assert.Contains("deu", germany.ThreeLetterISOLanguageNames);
@@ -84,11 +109,11 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
await localizationManager.LoadAll();
var ratings = localizationManager.GetParentalRatings().ToList();
- Assert.Equal(54, ratings.Count);
+ Assert.Equal(56, ratings.Count);
var tvma = ratings.FirstOrDefault(x => x.Name.Equals("TV-MA", StringComparison.Ordinal));
Assert.NotNull(tvma);
- Assert.Equal(17, tvma!.Value);
+ Assert.Equal(17, tvma!.RatingScore!.Score);
}
[Fact]
@@ -105,43 +130,49 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
var fsk = ratings.FirstOrDefault(x => x.Name.Equals("FSK-12", StringComparison.Ordinal));
Assert.NotNull(fsk);
- Assert.Equal(12, fsk!.Value);
+ Assert.Equal(12, fsk!.RatingScore!.Score);
}
[Theory]
- [InlineData("CA-R", "CA", 18)]
- [InlineData("FSK-16", "DE", 16)]
- [InlineData("FSK-18", "DE", 18)]
- [InlineData("FSK-18", "US", 18)]
- [InlineData("TV-MA", "US", 17)]
- [InlineData("XXX", "asdf", 1000)]
- [InlineData("Germany: FSK-18", "DE", 18)]
- public async Task GetRatingLevel_GivenValidString_Success(string value, string countryCode, int expectedLevel)
+ [InlineData("CA-R", "CA", 18, 1)]
+ [InlineData("FSK-16", "DE", 16, null)]
+ [InlineData("FSK-18", "DE", 18, null)]
+ [InlineData("FSK-18", "US", 18, null)]
+ [InlineData("TV-MA", "US", 17, 1)]
+ [InlineData("XXX", "asdf", 1000, null)]
+ [InlineData("Germany: FSK-18", "DE", 18, null)]
+ [InlineData("Rated : R", "US", 17, 0)]
+ [InlineData("Rated: R", "US", 17, 0)]
+ [InlineData("Rated R", "US", 17, 0)]
+ [InlineData(" PG-13 ", "US", 13, 0)]
+ public async Task GetRatingLevel_GivenValidString_Success(string value, string countryCode, int? expectedScore, int? expectedSubScore)
{
var localizationManager = Setup(new ServerConfiguration()
{
MetadataCountryCode = countryCode
});
await localizationManager.LoadAll();
- var level = localizationManager.GetRatingLevel(value);
- Assert.NotNull(level);
- Assert.Equal(expectedLevel, level!);
+ var score = localizationManager.GetRatingScore(value);
+ Assert.NotNull(score);
+ Assert.Equal(expectedScore, score.Score);
+ Assert.Equal(expectedSubScore, score.SubScore);
}
[Theory]
- [InlineData("0", 0)]
- [InlineData("1", 1)]
- [InlineData("6", 6)]
- [InlineData("12", 12)]
- [InlineData("42", 42)]
- [InlineData("9999", 9999)]
- public async Task GetRatingLevel_GivenValidAge_Success(string value, int expectedLevel)
+ [InlineData("0", 0, null)]
+ [InlineData("1", 1, null)]
+ [InlineData("6", 6, null)]
+ [InlineData("12", 12, null)]
+ [InlineData("42", 42, null)]
+ [InlineData("9999", 9999, null)]
+ public async Task GetRatingLevel_GivenValidAge_Success(string value, int? expectedScore, int? expectedSubScore)
{
var localizationManager = Setup(new ServerConfiguration { MetadataCountryCode = "nl" });
await localizationManager.LoadAll();
- var level = localizationManager.GetRatingLevel(value);
- Assert.NotNull(level);
- Assert.Equal(expectedLevel, level);
+ var score = localizationManager.GetRatingScore(value);
+ Assert.NotNull(score);
+ Assert.Equal(expectedScore, score.Score);
+ Assert.Equal(expectedSubScore, score.SubScore);
}
[Fact]
@@ -152,10 +183,10 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
UICulture = "de-DE"
});
await localizationManager.LoadAll();
- Assert.Null(localizationManager.GetRatingLevel("NR"));
- Assert.Null(localizationManager.GetRatingLevel("unrated"));
- Assert.Null(localizationManager.GetRatingLevel("Not Rated"));
- Assert.Null(localizationManager.GetRatingLevel("n/a"));
+ Assert.Null(localizationManager.GetRatingScore("NR"));
+ Assert.Null(localizationManager.GetRatingScore("unrated"));
+ Assert.Null(localizationManager.GetRatingScore("Not Rated"));
+ Assert.Null(localizationManager.GetRatingScore("n/a"));
}
[Theory]
@@ -169,7 +200,7 @@ namespace Jellyfin.Server.Implementations.Tests.Localization
});
await localizationManager.LoadAll();
- Assert.Null(localizationManager.GetRatingLevel(value));
+ Assert.Null(localizationManager.GetRatingScore(value));
}
[Theory]
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Playlists/PlaylistManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Playlists/PlaylistManagerTests.cs
new file mode 100644
index 000000000..cc8ca720e
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Playlists/PlaylistManagerTests.cs
@@ -0,0 +1,40 @@
+using Emby.Server.Implementations.Playlists;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Playlists;
+
+public class PlaylistManagerTests
+{
+ [Fact]
+ public void DetermineAdjustedIndexMoveToFirstPositionNoPriorInAllList()
+ {
+ var priorIndexAllChildren = 0;
+ var newIndex = 0;
+
+ var adjustedIndex = PlaylistManager.DetermineAdjustedIndex(priorIndexAllChildren, newIndex);
+
+ Assert.Equal(0, adjustedIndex);
+ }
+
+ [Fact]
+ public void DetermineAdjustedIndexPriorInMiddleOfAllList()
+ {
+ var priorIndexAllChildren = 2;
+ var newIndex = 0;
+
+ var adjustedIndex = PlaylistManager.DetermineAdjustedIndex(priorIndexAllChildren, newIndex);
+
+ Assert.Equal(1, adjustedIndex);
+ }
+
+ [Fact]
+ public void DetermineAdjustedIndexMoveMiddleOfPlaylist()
+ {
+ var priorIndexAllChildren = 2;
+ var newIndex = 1;
+
+ var adjustedIndex = PlaylistManager.DetermineAdjustedIndex(priorIndexAllChildren, newIndex);
+
+ Assert.Equal(3, adjustedIndex);
+ }
+}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs
index 934024826..b289c763b 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Plugins/PluginManagerTests.cs
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using AutoFixture;
using Emby.Server.Implementations.Library;
using Emby.Server.Implementations.Plugins;
+using Jellyfin.Extensions;
using Jellyfin.Extensions.Json;
using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Common.Plugins;
@@ -85,7 +86,7 @@ namespace Jellyfin.Server.Implementations.Tests.Plugins
var dllPath = Path.GetDirectoryName(Path.Combine(_pluginPath, dllFile))!;
Directory.CreateDirectory(dllPath);
- File.Create(Path.Combine(dllPath, filename));
+ FileHelper.CreateEmpty(Path.Combine(dllPath, filename));
var metafilePath = Path.Combine(_pluginPath, "meta.json");
File.WriteAllText(metafilePath, JsonSerializer.Serialize(manifest, _options));
@@ -141,7 +142,7 @@ namespace Jellyfin.Server.Implementations.Tests.Plugins
foreach (var file in files)
{
- File.Create(Path.Combine(_pluginPath, file));
+ FileHelper.CreateEmpty(Path.Combine(_pluginPath, file));
}
var metafilePath = Path.Combine(_pluginPath, "meta.json");
diff --git a/tests/Jellyfin.Server.Implementations.Tests/SessionManager/SessionManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/SessionManager/SessionManagerTests.cs
index 9418edc5d..a5a67046d 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/SessionManager/SessionManagerTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/SessionManager/SessionManagerTests.cs
@@ -1,6 +1,6 @@
using System;
using System.Threading.Tasks;
-using Jellyfin.Data.Entities;
+using Jellyfin.Database.Implementations.Entities;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Devices;
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest.json b/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest.json
index 57367ce88..6aa40c1dd 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest.json
+++ b/tests/Jellyfin.Server.Implementations.Tests/Test Data/Updates/manifest.json
@@ -540,7 +540,7 @@
{
"guid": "022a3003-993f-45f1-8565-87d12af2e12a",
"name": "InfuseSync",
- "description": "This plugin will track all media changes while any Infuse clients are offline to decrease sync times when logging back in to your server.",
+ "description": "This plugin will track all media changes while any Infuse clients are offline to decrease sync times when logging back into your server.",
"overview": "Blazing fast indexing for Infuse",
"owner": "Firecore LLC",
"category": "General",
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs
index 665afe111..4cea53bd3 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Users/UserManagerTests.cs
@@ -23,6 +23,10 @@ namespace Jellyfin.Server.Implementations.Tests.Users
[InlineData(" ")]
[InlineData("")]
[InlineData("special characters like & $ ? are not allowed")]
+ [InlineData("thishasaspaceontheend ")]
+ [InlineData(" thishasaspaceatthestart")]
+ [InlineData(" thishasaspaceatbothends ")]
+ [InlineData(" this has a space at both ends and inbetween ")]
public void ThrowIfInvalidUsername_WhenInvalidUsername_ThrowsArgumentException(string username)
{
Assert.Throws<ArgumentException>(() => UserManager.ThrowIfInvalidUsername(username));