diff --git a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs index 3c874c62ca..eb9393b0bd 100644 --- a/Emby.Naming/AudioBook/AudioBookFilePathParser.cs +++ b/Emby.Naming/AudioBook/AudioBookFilePathParser.cs @@ -50,27 +50,14 @@ namespace Emby.Naming.AudioBook { if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue)) { - result.ChapterNumber = intValue; + result.PartNumber = intValue; } } } } } - /*var matches = _iRegexProvider.GetRegex("\\d+", RegexOptions.IgnoreCase).Matches(fileName); - if (matches.Count > 0) - { - if (!result.ChapterNumber.HasValue) - { - result.ChapterNumber = int.Parse(matches[0].Groups[0].Value); - } - - if (matches.Count > 1) - { - result.PartNumber = int.Parse(matches[matches.Count - 1].Groups[0].Value); - } - }*/ - result.Success = result.PartNumber.HasValue || result.ChapterNumber.HasValue; + result.Success = result.ChapterNumber.HasValue || result.PartNumber.HasValue; return result; } diff --git a/Emby.Naming/AudioBook/AudioBookResolver.cs b/Emby.Naming/AudioBook/AudioBookResolver.cs index 5466b46379..ed53bd04fa 100644 --- a/Emby.Naming/AudioBook/AudioBookResolver.cs +++ b/Emby.Naming/AudioBook/AudioBookResolver.cs @@ -55,8 +55,8 @@ namespace Emby.Naming.AudioBook { Path = path, Container = container, - PartNumber = parsingResult.PartNumber, ChapterNumber = parsingResult.ChapterNumber, + PartNumber = parsingResult.PartNumber, IsDirectory = isDirectory }; } diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs new file mode 100644 index 0000000000..541bb321cd --- /dev/null +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs @@ -0,0 +1,90 @@ +using System.Linq; +using Emby.Naming.AudioBook; +using Emby.Naming.Common; +using MediaBrowser.Model.IO; +using Xunit; + +namespace Jellyfin.Naming.Tests.AudioBook +{ + public class AudioBookListResolverTests + { + private readonly NamingOptions _namingOptions = new NamingOptions(); + + [Fact] + public void TestStackAndExtras() + { + // No stacking here because there is no part/disc/etc + var files = new[] + { + "Harry Potter and the Deathly Hallows/Part 1.mp3", + "Harry Potter and the Deathly Hallows/Part 2.mp3", + "Harry Potter and the Deathly Hallows/book.nfo", + + "Batman/Chapter 1.mp3", + "Batman/Chapter 2.mp3", + "Batman/Chapter 3.mp3", + }; + + var resolver = GetResolver(); + + var result = resolver.Resolve(files.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i + }).ToList()).ToList(); + + Assert.Equal(2, result[0].Files.ToList().Count); + // Assert.Empty(result[0].Extras); FIXME: AudioBookListResolver should resolve extra files properly + Assert.Equal("Harry Potter and the Deathly Hallows", result[0].Name); + + Assert.Equal(3, result[1].Files.ToList().Count); + Assert.Empty(result[1].Extras); + Assert.Equal("Batman", result[1].Name); + } + + [Fact] + public void TestWithMetadata() + { + var files = new[] + { + "Harry Potter and the Deathly Hallows/Chapter 1.ogg", + "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows.nfo" + }; + + var resolver = GetResolver(); + + var result = resolver.Resolve(files.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i + }).ToList()).ToList(); + + Assert.Single(result); + } + + [Fact] + public void TestWithExtra() + { + var files = new[] + { + "Harry Potter and the Deathly Hallows/Chapter 1.mp3", + "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows trailer.mp3" + }; + + var resolver = GetResolver(); + + var result = resolver.Resolve(files.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i + }).ToList()).ToList(); + + Assert.Single(result); + } + + private AudioBookListResolver GetResolver() + { + return new AudioBookListResolver(_namingOptions); + } + } +} diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs new file mode 100644 index 0000000000..5da2e93d8d --- /dev/null +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using Emby.Naming.AudioBook; +using Emby.Naming.Common; +using MediaBrowser.Model.Entities; +using Xunit; + +namespace Jellyfin.Naming.Tests.AudioBook +{ + public class AudioBookResolverTests + { + private readonly NamingOptions _namingOptions = new NamingOptions(); + + public static IEnumerable GetResolveFileTestData() + { + yield return new object[] + { + new AudioBookFileInfo() + { + Path = @"/server/AudioBooks/Larry Potter/Larry Potter.mp3", + Container = "mp3", + } + }; + yield return new object[] + { + new AudioBookFileInfo() + { + Path = @"/server/AudioBooks/Berry Potter/Chapter 1 .ogg", + Container = "ogg", + ChapterNumber = 1 + } + }; + yield return new object[] + { + new AudioBookFileInfo() + { + Path = @"/server/AudioBooks/Nerry Potter/Part 3 - Chapter 2.mp3", + Container = "mp3", + ChapterNumber = 2, + PartNumber = 3 + } + }; + } + + [Theory] + [MemberData(nameof(GetResolveFileTestData))] + public void ResolveFile_ValidFileName_Success(AudioBookFileInfo expectedResult) + { + var result = new AudioBookResolver(_namingOptions).Resolve(expectedResult.Path); + + Assert.NotNull(result); + Assert.Equal(result?.Path, expectedResult.Path); + Assert.Equal(result?.Container, expectedResult.Container); + Assert.Equal(result?.ChapterNumber, expectedResult.ChapterNumber); + Assert.Equal(result?.PartNumber, expectedResult.PartNumber); + Assert.Equal(result?.IsDirectory, expectedResult.IsDirectory); + } + } +}