aboutsummaryrefslogtreecommitdiff
path: root/tests/Jellyfin.Server.Implementations.Tests/Library
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Jellyfin.Server.Implementations.Tests/Library')
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs19
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/LibraryManager/FindExtrasTests.cs285
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/MediaSourceManagerTests.cs32
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs18
4 files changed, 344 insertions, 10 deletions
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
index c393742eb..5c7c983c2 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
@@ -1,4 +1,4 @@
-using System;
+using Emby.Naming.Common;
using Emby.Server.Implementations.Library.Resolvers.TV;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
@@ -14,22 +14,21 @@ namespace Jellyfin.Server.Implementations.Tests.Library
{
public class EpisodeResolverTest
{
+ private static readonly NamingOptions _namingOptions = new();
+
[Fact]
public void Resolve_GivenVideoInExtrasFolder_DoesNotResolveToEpisode()
{
- var season = new Season { Name = "Season 1" };
var parent = new Folder { Name = "extras" };
- var libraryManagerMock = new Mock<ILibraryManager>();
- libraryManagerMock.Setup(x => x.GetItemById(It.IsAny<Guid>())).Returns(season);
- var episodeResolver = new EpisodeResolver(libraryManagerMock.Object);
+ var episodeResolver = new EpisodeResolver(_namingOptions);
var itemResolveArgs = new ItemResolveArgs(
Mock.Of<IServerApplicationPaths>(),
Mock.Of<IDirectoryService>())
{
Parent = parent,
CollectionType = CollectionType.TvShows,
- FileInfo = new FileSystemMetadata()
+ FileInfo = new FileSystemMetadata
{
FullName = "All My Children/Season 01/Extras/All My Children S01E01 - Behind The Scenes.mkv"
}
@@ -45,14 +44,14 @@ namespace Jellyfin.Server.Implementations.Tests.Library
// Have to create a mock because of moq proxies not being castable to a concrete implementation
// https://github.com/jellyfin/jellyfin/blob/ab0cff8556403e123642dc9717ba778329554634/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs#L48
- var episodeResolver = new EpisodeResolverMock(Mock.Of<ILibraryManager>());
+ var episodeResolver = new EpisodeResolverMock(_namingOptions);
var itemResolveArgs = new ItemResolveArgs(
Mock.Of<IServerApplicationPaths>(),
Mock.Of<IDirectoryService>())
{
Parent = series,
CollectionType = CollectionType.TvShows,
- FileInfo = new FileSystemMetadata()
+ FileInfo = new FileSystemMetadata
{
FullName = "Extras/Extras S01E01.mkv"
}
@@ -62,11 +61,11 @@ namespace Jellyfin.Server.Implementations.Tests.Library
private class EpisodeResolverMock : EpisodeResolver
{
- public EpisodeResolverMock(ILibraryManager libraryManager) : base(libraryManager)
+ public EpisodeResolverMock(NamingOptions namingOptions) : base(namingOptions)
{
}
- protected override TVideoType ResolveVideo<TVideoType>(ItemResolveArgs args, bool parseName) => new ();
+ protected override TVideoType ResolveVideo<TVideoType>(ItemResolveArgs args, bool parseName) => new();
}
}
}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/LibraryManager/FindExtrasTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/LibraryManager/FindExtrasTests.cs
new file mode 100644
index 000000000..de4421320
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/LibraryManager/FindExtrasTests.cs
@@ -0,0 +1,285 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using AutoFixture;
+using AutoFixture.AutoMoq;
+using Emby.Naming.Common;
+using Emby.Server.Implementations.Library.Resolvers.Audio;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.Resolvers;
+using MediaBrowser.Controller.Sorting;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.IO;
+using Moq;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Library.LibraryManager;
+
+public class FindExtrasTests
+{
+ private readonly Emby.Server.Implementations.Library.LibraryManager _libraryManager;
+ private readonly Mock<IFileSystem> _fileSystemMock;
+
+ public FindExtrasTests()
+ {
+ var fixture = new Fixture().Customize(new AutoMoqCustomization());
+ fixture.Register(() => new NamingOptions());
+ var configMock = fixture.Freeze<Mock<IServerConfigurationManager>>();
+ configMock.Setup(c => c.ApplicationPaths.ProgramDataPath).Returns("/data");
+ var itemRepository = fixture.Freeze<Mock<IItemRepository>>();
+ itemRepository.Setup(i => i.RetrieveItem(It.IsAny<Guid>())).Returns<BaseItem>(null);
+ _fileSystemMock = fixture.Freeze<Mock<IFileSystem>>();
+ _fileSystemMock.Setup(f => f.GetFileInfo(It.IsAny<string>())).Returns<string>(path => new FileSystemMetadata { FullName = path });
+ _libraryManager = fixture.Build<Emby.Server.Implementations.Library.LibraryManager>().Do(s => s.AddParts(
+ fixture.Create<IEnumerable<IResolverIgnoreRule>>(),
+ new List<IItemResolver> { new AudioResolver(fixture.Create<NamingOptions>()) },
+ fixture.Create<IEnumerable<IIntroProvider>>(),
+ fixture.Create<IEnumerable<IBaseItemComparer>>(),
+ fixture.Create<IEnumerable<ILibraryPostScanTask>>()))
+ .Create();
+
+ // This is pretty terrible but unavoidable
+ BaseItem.FileSystem ??= fixture.Create<IFileSystem>();
+ BaseItem.MediaSourceManager ??= fixture.Create<IMediaSourceManager>();
+ }
+
+ [Fact]
+ public void FindExtras_SeparateMovieFolder_FindsCorrectExtras()
+ {
+ var owner = new Movie { Name = "Up", Path = "/movies/Up/Up.mkv" };
+ var paths = new List<string>
+ {
+ "/movies/Up/Up.mkv",
+ "/movies/Up/Up - trailer.mkv",
+ "/movies/Up/Up - sample.mkv",
+ "/movies/Up/Up something else.mkv"
+ };
+
+ var files = paths.Select(p => new FileSystemMetadata
+ {
+ FullName = p,
+ IsDirectory = false
+ }).ToList();
+
+ var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
+
+ Assert.Equal(2, extras.Count);
+ Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
+ Assert.Equal(typeof(Trailer), extras[0].GetType());
+ Assert.Equal(ExtraType.Sample, extras[1].ExtraType);
+ }
+
+ [Fact]
+ public void FindExtras_SeparateMovieFolderWithMixedExtras_FindsCorrectExtras()
+ {
+ var owner = new Movie { Name = "Up", Path = "/movies/Up/Up.mkv" };
+ var paths = new List<string>
+ {
+ "/movies/Up/Up.mkv",
+ "/movies/Up/Up - trailer.mkv",
+ "/movies/Up/trailers",
+ "/movies/Up/theme-music",
+ "/movies/Up/theme.mp3",
+ "/movies/Up/not a theme.mp3",
+ "/movies/Up/behind the scenes",
+ "/movies/Up/behind the scenes.mkv",
+ "/movies/Up/Up - sample.mkv",
+ "/movies/Up/Up something else.mkv"
+ };
+
+ _fileSystemMock.Setup(f => f.GetFiles(
+ "/movies/Up/trailers",
+ It.IsAny<string[]>(),
+ false,
+ false))
+ .Returns(new List<FileSystemMetadata>
+ {
+ new()
+ {
+ FullName = "/movies/Up/trailers/some trailer.mkv",
+ Name = "some trailer.mkv",
+ IsDirectory = false
+ }
+ }).Verifiable();
+
+ _fileSystemMock.Setup(f => f.GetFiles(
+ "/movies/Up/behind the scenes",
+ It.IsAny<string[]>(),
+ false,
+ false))
+ .Returns(new List<FileSystemMetadata>
+ {
+ new()
+ {
+ FullName = "/movies/Up/behind the scenes/the making of Up.mkv",
+ Name = "the making of Up.mkv",
+ IsDirectory = false
+ }
+ }).Verifiable();
+
+ _fileSystemMock.Setup(f => f.GetFiles(
+ "/movies/Up/theme-music",
+ It.IsAny<string[]>(),
+ false,
+ false))
+ .Returns(new List<FileSystemMetadata>
+ {
+ new()
+ {
+ FullName = "/movies/Up/theme-music/theme2.mp3",
+ Name = "theme2.mp3",
+ IsDirectory = false
+ }
+ }).Verifiable();
+
+ var files = paths.Select(p => new FileSystemMetadata
+ {
+ FullName = p,
+ Name = Path.GetFileName(p),
+ IsDirectory = !Path.HasExtension(p)
+ }).ToList();
+
+ var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
+
+ _fileSystemMock.Verify();
+ Assert.Equal(6, extras.Count);
+ Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
+ Assert.Equal(typeof(Trailer), extras[0].GetType());
+ Assert.Equal(ExtraType.Trailer, extras[1].ExtraType);
+ Assert.Equal(typeof(Trailer), extras[1].GetType());
+ Assert.Equal(ExtraType.BehindTheScenes, extras[2].ExtraType);
+ Assert.Equal(ExtraType.Sample, extras[3].ExtraType);
+ Assert.Equal(ExtraType.ThemeSong, extras[4].ExtraType);
+ Assert.Equal(typeof(Audio), extras[4].GetType());
+ Assert.Equal(ExtraType.ThemeSong, extras[5].ExtraType);
+ Assert.Equal(typeof(Audio), extras[5].GetType());
+ }
+
+ [Fact]
+ public void FindExtras_SeparateMovieFolderWithMixedExtras_FindsOnlyExtrasInMovieFolder()
+ {
+ var owner = new Movie { Name = "Up", Path = "/movies/Up/Up.mkv" };
+ var paths = new List<string>
+ {
+ "/movies/Up/Up.mkv",
+ "/movies/Up/trailer.mkv",
+ "/movies/Another Movie/trailer.mkv"
+ };
+
+ var files = paths.Select(p => new FileSystemMetadata
+ {
+ FullName = p,
+ IsDirectory = false
+ }).ToList();
+
+ var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
+
+ Assert.Single(extras);
+ Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
+ Assert.Equal(typeof(Trailer), extras[0].GetType());
+ Assert.Equal("trailer", extras[0].FileNameWithoutExtension);
+ Assert.Equal("/movies/Up/trailer.mkv", extras[0].Path);
+ }
+
+ [Fact]
+ public void FindExtras_SeparateMovieFolderWithParts_FindsCorrectExtras()
+ {
+ var owner = new Movie { Name = "Up", Path = "/movies/Up/Up - part1.mkv" };
+ var paths = new List<string>
+ {
+ "/movies/Up/Up - part1.mkv",
+ "/movies/Up/Up - part2.mkv",
+ "/movies/Up/trailer.mkv",
+ "/movies/Another Movie/trailer.mkv"
+ };
+
+ var files = paths.Select(p => new FileSystemMetadata
+ {
+ FullName = p,
+ IsDirectory = false
+ }).ToList();
+
+ var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
+
+ Assert.Single(extras);
+ Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
+ Assert.Equal(typeof(Trailer), extras[0].GetType());
+ Assert.Equal("trailer", extras[0].FileNameWithoutExtension);
+ Assert.Equal("/movies/Up/trailer.mkv", extras[0].Path);
+ }
+
+ [Fact]
+ public void FindExtras_WrongExtensions_FindsNoExtras()
+ {
+ var owner = new Movie { Name = "Up", Path = "/movies/Up/Up.mkv" };
+ var paths = new List<string>
+ {
+ "/movies/Up/Up.mkv",
+ "/movies/Up/trailer.noext",
+ "/movies/Up/theme.png",
+ "/movies/Up/trailers"
+ };
+
+ var files = paths.Select(p => new FileSystemMetadata
+ {
+ FullName = p,
+ Name = Path.GetFileName(p),
+ IsDirectory = !Path.HasExtension(p)
+ }).ToList();
+
+ _fileSystemMock.Setup(f => f.GetFiles(
+ "/movies/Up/trailers",
+ It.IsAny<string[]>(),
+ false,
+ false))
+ .Returns(new List<FileSystemMetadata>
+ {
+ new()
+ {
+ FullName = "/movies/Up/trailers/trailer.jpg",
+ Name = "trailer.jpg",
+ IsDirectory = false
+ }
+ }).Verifiable();
+
+ var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
+
+ _fileSystemMock.Verify();
+ Assert.Empty(extras);
+ }
+
+ [Fact]
+ public void FindExtras_SeriesWithTrailers_FindsCorrectExtras()
+ {
+ var owner = new Series { Name = "Dexter", Path = "/series/Dexter" };
+ var paths = new List<string>
+ {
+ "/series/Dexter/Season 1/S01E01.mkv",
+ "/series/Dexter/trailer.mkv",
+ "/series/Dexter/trailers/trailer2.mkv",
+ };
+
+ var files = paths.Select(p => new FileSystemMetadata
+ {
+ FullName = p,
+ IsDirectory = string.IsNullOrEmpty(Path.GetExtension(p))
+ }).ToList();
+
+ var extras = _libraryManager.FindExtras(owner, files, new DirectoryService(_fileSystemMock.Object)).OrderBy(e => e.ExtraType).ToList();
+
+ Assert.Equal(2, extras.Count);
+ Assert.Equal(ExtraType.Trailer, extras[0].ExtraType);
+ Assert.Equal(typeof(Trailer), extras[0].GetType());
+ Assert.Equal("trailer", extras[0].FileNameWithoutExtension);
+ Assert.Equal("/series/Dexter/trailer.mkv", extras[0].Path);
+ Assert.Equal("/series/Dexter/trailers/trailer2.mkv", extras[1].Path);
+ }
+}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/MediaSourceManagerTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/MediaSourceManagerTests.cs
new file mode 100644
index 000000000..8ed3d8b94
--- /dev/null
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/MediaSourceManagerTests.cs
@@ -0,0 +1,32 @@
+using AutoFixture;
+using AutoFixture.AutoMoq;
+using Emby.Server.Implementations.IO;
+using Emby.Server.Implementations.Library;
+using MediaBrowser.Model.IO;
+using MediaBrowser.Model.MediaInfo;
+using Xunit;
+
+namespace Jellyfin.Server.Implementations.Tests.Library
+{
+ public class MediaSourceManagerTests
+ {
+ private readonly MediaSourceManager _mediaSourceManager;
+
+ public MediaSourceManagerTests()
+ {
+ IFixture fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
+ fixture.Inject<IFileSystem>(fixture.Create<ManagedFileSystem>());
+ _mediaSourceManager = fixture.Create<MediaSourceManager>();
+ }
+
+ [Theory]
+ [InlineData(@"C:\mydir\myfile.ext", MediaProtocol.File)]
+ [InlineData("/mydir/myfile.ext", MediaProtocol.File)]
+ [InlineData("file:///mydir/myfile.ext", MediaProtocol.File)]
+ [InlineData("http://example.com/stream.m3u8", MediaProtocol.Http)]
+ [InlineData("https://example.com/stream.m3u8", MediaProtocol.Http)]
+ [InlineData("rtsp://media.example.com:554/twister/audiotrack", MediaProtocol.Rtsp)]
+ public void GetPathProtocol_ValidArg_Correct(string path, MediaProtocol expected)
+ => Assert.Equal(expected, _mediaSourceManager.GetPathProtocol(path));
+ }
+}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs
index c5cc056f5..be2dfe0a8 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/PathExtensionsTests.cs
@@ -8,9 +8,27 @@ namespace Jellyfin.Server.Implementations.Tests.Library
{
[Theory]
[InlineData("Superman: Red Son [imdbid=tt10985510]", "imdbid", "tt10985510")]
+ [InlineData("Superman: Red Son [imdbid-tt10985510]", "imdbid", "tt10985510")]
[InlineData("Superman: Red Son - tt10985510", "imdbid", "tt10985510")]
[InlineData("Superman: Red Son", "imdbid", null)]
[InlineData("Superman: Red Son", "something", null)]
+ [InlineData("Superman: Red Son [imdbid1=tt11111111][imdbid=tt10985510]", "imdbid", "tt10985510")]
+ [InlineData("Superman: Red Son [imdbid1-tt11111111][imdbid=tt10985510]", "imdbid", "tt10985510")]
+ [InlineData("Superman: Red Son [tmdbid=618355][imdbid=tt10985510]", "imdbid", "tt10985510")]
+ [InlineData("Superman: Red Son [tmdbid-618355][imdbid-tt10985510]", "imdbid", "tt10985510")]
+ [InlineData("Superman: Red Son [tmdbid-618355][imdbid-tt10985510]", "tmdbid", "618355")]
+ [InlineData("[tmdbid=618355]", "tmdbid", "618355")]
+ [InlineData("[tmdbid-618355]", "tmdbid", "618355")]
+ [InlineData("tmdbid=111111][tmdbid=618355]", "tmdbid", "618355")]
+ [InlineData("[tmdbid=618355]tmdbid=111111]", "tmdbid", "618355")]
+ [InlineData("tmdbid=618355]", "tmdbid", null)]
+ [InlineData("[tmdbid=618355", "tmdbid", null)]
+ [InlineData("tmdbid=618355", "tmdbid", null)]
+ [InlineData("tmdbid=", "tmdbid", null)]
+ [InlineData("tmdbid", "tmdbid", null)]
+ [InlineData("[tmdbid=][imdbid=tt10985510]", "tmdbid", null)]
+ [InlineData("[tmdbid-][imdbid-tt10985510]", "tmdbid", null)]
+ [InlineData("Superman: Red Son [tmdbid-618355][tmdbid=1234567]", "tmdbid", "618355")]
public void GetAttributeValue_ValidArgs_Correct(string input, string attribute, string? expectedResult)
{
Assert.Equal(expectedResult, PathExtensions.GetAttributeValue(input, attribute));