|
@@ -0,0 +1,73 @@
|
|
|
+using System.Linq;
|
|
|
+using Emby.Naming.Common;
|
|
|
+using Emby.Server.Implementations.Library.Resolvers.Audio;
|
|
|
+using MediaBrowser.Controller.Entities.Audio;
|
|
|
+using MediaBrowser.Controller.Library;
|
|
|
+using MediaBrowser.Model.IO;
|
|
|
+using Moq;
|
|
|
+using Xunit;
|
|
|
+
|
|
|
+namespace Jellyfin.Server.Implementations.Tests.Library;
|
|
|
+
|
|
|
+public class AudioResolverTests
|
|
|
+{
|
|
|
+ private static readonly NamingOptions _namingOptions = new();
|
|
|
+
|
|
|
+ [Theory]
|
|
|
+ [InlineData("words.mp3")] // single non-tagged file
|
|
|
+ [InlineData("chapter 01.mp3")]
|
|
|
+ [InlineData("part 1.mp3")]
|
|
|
+ [InlineData("chapter 01.mp3", "non-media.txt")]
|
|
|
+ [InlineData("title.mp3", "title.epub")]
|
|
|
+ [InlineData("01.mp3", "subdirectory/")] // single media file with sub-directory - note that this will hide any contents in the subdirectory
|
|
|
+ public void Resolve_AudiobookDirectory_SingleResult(params string[] children)
|
|
|
+ {
|
|
|
+ var resolved = TestResolveChildren("/parent/title", children);
|
|
|
+ Assert.NotNull(resolved);
|
|
|
+ }
|
|
|
+
|
|
|
+ [Theory]
|
|
|
+ /* Results that can't be displayed as an audio book. */
|
|
|
+ [InlineData] // no contents
|
|
|
+ [InlineData("subdirectory/")]
|
|
|
+ [InlineData("non-media.txt")]
|
|
|
+ /* Names don't indicate parts of a single book. */
|
|
|
+ [InlineData("Name.mp3", "Another Name.mp3")]
|
|
|
+ /* Results that are an audio book but not currently navigable as such (multiple chapters and/or parts). */
|
|
|
+ [InlineData("01.mp3", "02.mp3")]
|
|
|
+ [InlineData("chapter 01.mp3", "chapter 02.mp3")]
|
|
|
+ [InlineData("part 1.mp3", "part 2.mp3")]
|
|
|
+ [InlineData("chapter 01 part 01.mp3", "chapter 01 part 02.mp3")]
|
|
|
+ /* Mismatched chapters, parts, and named files. */
|
|
|
+ [InlineData("chapter 01.mp3", "part 2.mp3")]
|
|
|
+ public void Resolve_AudiobookDirectory_NoResult(params string[] children)
|
|
|
+ {
|
|
|
+ var resolved = TestResolveChildren("/parent/book title", children);
|
|
|
+ Assert.Null(resolved);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Audio? TestResolveChildren(string parent, string[] children)
|
|
|
+ {
|
|
|
+ var childrenMetadata = children.Select(name => new FileSystemMetadata
|
|
|
+ {
|
|
|
+ FullName = parent + "/" + name,
|
|
|
+ IsDirectory = name.EndsWith('/')
|
|
|
+ }).ToArray();
|
|
|
+
|
|
|
+ var resolver = new AudioResolver(_namingOptions);
|
|
|
+ var itemResolveArgs = new ItemResolveArgs(
|
|
|
+ null,
|
|
|
+ Mock.Of<ILibraryManager>())
|
|
|
+ {
|
|
|
+ CollectionType = "books",
|
|
|
+ FileInfo = new FileSystemMetadata
|
|
|
+ {
|
|
|
+ FullName = parent,
|
|
|
+ IsDirectory = true
|
|
|
+ },
|
|
|
+ FileSystemChildren = childrenMetadata
|
|
|
+ };
|
|
|
+
|
|
|
+ return resolver.Resolve(itemResolveArgs);
|
|
|
+ }
|
|
|
+}
|