diff options
| author | Greenback <jimcartlidge@yahoo.co.uk> | 2020-11-19 18:27:18 +0000 |
|---|---|---|
| committer | Greenback <jimcartlidge@yahoo.co.uk> | 2020-11-19 18:27:18 +0000 |
| commit | a3e47f3e4eed60b227359e8ae59c8a6659a1942c (patch) | |
| tree | e5af2d5c0e658505f397ed48abc4e5870f3857d7 /tests | |
| parent | 60a6627140a83408b8157b9543e62ff48918ef7a (diff) | |
| parent | e71ab2afb1fda7521c61f860654fd94e3bd5e3e8 (diff) | |
Updated to latest Unstable.
Diffstat (limited to 'tests')
17 files changed, 592 insertions, 245 deletions
diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 5bf322f07..14eed30e0 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -22,7 +22,7 @@ <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> - <PackageReference Include="Moq" Version="4.14.7" /> + <PackageReference Include="Moq" Version="4.15.1" /> </ItemGroup> <!-- Code Analyzers --> diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs index a214bc57c..cf21f964e 100644 --- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookFileInfoTests.cs @@ -1,4 +1,4 @@ -using Emby.Naming.AudioBook; +using Emby.Naming.AudioBook; using Xunit; namespace Jellyfin.Naming.Tests.AudioBook @@ -8,22 +8,22 @@ namespace Jellyfin.Naming.Tests.AudioBook [Fact] public void CompareTo_Same_Success() { - var info = new AudioBookFileInfo(); + var info = new AudioBookFileInfo(string.Empty, string.Empty); Assert.Equal(0, info.CompareTo(info)); } [Fact] public void CompareTo_Null_Success() { - var info = new AudioBookFileInfo(); + var info = new AudioBookFileInfo(string.Empty, string.Empty); Assert.Equal(1, info.CompareTo(null)); } [Fact] public void CompareTo_Empty_Success() { - var info1 = new AudioBookFileInfo(); - var info2 = new AudioBookFileInfo(); + var info1 = new AudioBookFileInfo(string.Empty, string.Empty); + var info2 = new AudioBookFileInfo(string.Empty, string.Empty); Assert.Equal(0, info1.CompareTo(info2)); } } diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs index 1084e20bd..e5768b620 100644 --- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookListResolverTests.cs @@ -1,4 +1,6 @@ -using System.Linq; +using System; +using System.Collections.Generic; +using System.Linq; using Emby.Naming.AudioBook; using Emby.Naming.Common; using MediaBrowser.Model.IO; @@ -18,11 +20,22 @@ namespace Jellyfin.Naming.Tests.AudioBook { "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", + "Harry Potter and the Deathly Hallows/Extra.mp3", "Batman/Chapter 1.mp3", "Batman/Chapter 2.mp3", "Batman/Chapter 3.mp3", + + "Badman/audiobook.mp3", + "Badman/extra.mp3", + + "Superman (2020)/Part 1.mp3", + "Superman (2020)/extra.mp3", + + "Ready Player One (2020)/audiobook.mp3", + "Ready Player One (2020)/extra.mp3", + + ".mp3" }; var resolver = GetResolver(); @@ -33,13 +46,141 @@ namespace Jellyfin.Naming.Tests.AudioBook FullName = i })).ToList(); + Assert.Equal(5, result.Count); + Assert.Equal(2, result[0].Files.Count); - // Assert.Empty(result[0].Extras); FIXME: AudioBookListResolver should resolve extra files properly + Assert.Single(result[0].Extras); Assert.Equal("Harry Potter and the Deathly Hallows", result[0].Name); Assert.Equal(3, result[1].Files.Count); Assert.Empty(result[1].Extras); Assert.Equal("Batman", result[1].Name); + + Assert.Single(result[2].Files); + Assert.Single(result[2].Extras); + Assert.Equal("Badman", result[2].Name); + + Assert.Single(result[3].Files); + Assert.Single(result[3].Extras); + Assert.Equal("Superman", result[3].Name); + + Assert.Single(result[4].Files); + Assert.Single(result[4].Extras); + Assert.Equal("Ready Player One", result[4].Name); + } + + [Fact] + public void TestAlternativeVersions() + { + var files = new[] + { + "Harry Potter and the Deathly Hallows/Chapter 1.ogg", + "Harry Potter and the Deathly Hallows/Chapter 1.mp3", + + "Deadpool.mp3", + "Deadpool [HQ].mp3", + + "Superman/audiobook.mp3", + "Superman/Superman.mp3", + "Superman/Superman [HQ].mp3", + "Superman/extra.mp3", + + "Batman/ Chapter 1 .mp3", + "Batman/Chapter 1[loss-less].mp3" + }; + + var resolver = GetResolver(); + + var result = resolver.Resolve(files.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i + })).ToList(); + + Assert.Equal(5, result.Count); + // HP - Same name so we don't care which file is alternative + Assert.Single(result[0].AlternateVersions); + // DP + Assert.Empty(result[1].AlternateVersions); + // DP HQ (directory missing so we do not group deadpools together) + Assert.Empty(result[2].AlternateVersions); + // Superman + // Priority: + // 1. Name + // 2. audiobook + // 3. Names with modifiers + Assert.Equal(2, result[3].AlternateVersions.Count); + var paths = result[3].AlternateVersions.Select(x => x.Path).ToList(); + Assert.Contains("Superman/audiobook.mp3", paths); + Assert.Contains("Superman/Superman [HQ].mp3", paths); + // Batman + Assert.Single(result[4].AlternateVersions); + } + + [Fact] + public void TestNameYearExtraction() + { + var data = new[] + { + new NameYearPath + { + Name = "Harry Potter and the Deathly Hallows", + Path = "Harry Potter and the Deathly Hallows (2007)/Chapter 1.ogg", + Year = 2007 + }, + new NameYearPath + { + Name = "Batman", + Path = "Batman (2020).ogg", + Year = 2020 + }, + new NameYearPath + { + Name = "Batman", + Path = "Batman( 2021 ).mp3", + Year = 2021 + }, + new NameYearPath + { + Name = "Batman(*2021*)", + Path = "Batman(*2021*).mp3", + Year = null + }, + new NameYearPath + { + Name = "Batman", + Path = "Batman.mp3", + Year = null + }, + new NameYearPath + { + Name = "+ Batman .", + Path = " + Batman . .mp3", + Year = null + }, + new NameYearPath + { + Name = " ", + Path = " .mp3", + Year = null + } + }; + + var resolver = GetResolver(); + + var result = resolver.Resolve(data.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i.Path + })).ToList(); + + Assert.Equal(data.Length, result.Count); + + for (int i = 0; i < data.Length; i++) + { + Assert.Equal(data[i].Name, result[i].Name); + Assert.Equal(data[i].Year, result[i].Year); + } } [Fact] @@ -82,9 +223,51 @@ namespace Jellyfin.Naming.Tests.AudioBook Assert.Single(result); } + [Fact] + public void TestWithoutFolder() + { + var files = new[] + { + "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(); + + Assert.Single(result); + } + + [Fact] + public void TestEmpty() + { + var files = Array.Empty<string>(); + + var resolver = GetResolver(); + + var result = resolver.Resolve(files.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i + })).ToList(); + + Assert.Empty(result); + } + private AudioBookListResolver GetResolver() { return new AudioBookListResolver(_namingOptions); } + + internal struct NameYearPath + { + public string Name; + public string Path; + public int? Year; + } } } diff --git a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs index 673289436..b3257ace3 100644 --- a/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/AudioBook/AudioBookResolverTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using Emby.Naming.AudioBook; using Emby.Naming.Common; @@ -14,30 +14,24 @@ namespace Jellyfin.Naming.Tests.AudioBook { yield return new object[] { - new AudioBookFileInfo() - { - Path = @"/server/AudioBooks/Larry Potter/Larry Potter.mp3", - Container = "mp3", - } + new AudioBookFileInfo( + @"/server/AudioBooks/Larry Potter/Larry Potter.mp3", + "mp3") }; yield return new object[] { - new AudioBookFileInfo() - { - Path = @"/server/AudioBooks/Berry Potter/Chapter 1 .ogg", - Container = "ogg", - ChapterNumber = 1 - } + new AudioBookFileInfo( + @"/server/AudioBooks/Berry Potter/Chapter 1 .ogg", + "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 - } + new AudioBookFileInfo( + @"/server/AudioBooks/Nerry Potter/Part 3 - Chapter 2.mp3", + "mp3", + chapterNumber: 2, + partNumber: 3) }; } @@ -52,13 +46,22 @@ namespace Jellyfin.Naming.Tests.AudioBook Assert.Equal(result!.Container, expectedResult.Container); Assert.Equal(result!.ChapterNumber, expectedResult.ChapterNumber); Assert.Equal(result!.PartNumber, expectedResult.PartNumber); - Assert.Equal(result!.IsDirectory, expectedResult.IsDirectory); } [Fact] - public void Resolve_EmptyFileName_ArgumentException() + public void Resolve_InvalidExtension() { - Assert.Throws<ArgumentException>(() => new AudioBookResolver(_namingOptions).Resolve(string.Empty)); + var result = new AudioBookResolver(_namingOptions).Resolve(@"/server/AudioBooks/Larry Potter/Larry Potter.mp9"); + + Assert.Null(result); + } + + [Fact] + public void Resolve_EmptyFileName() + { + var result = new AudioBookResolver(_namingOptions).Resolve(string.Empty); + + Assert.Null(result); } } } diff --git a/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs b/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs new file mode 100644 index 000000000..3892d00f6 --- /dev/null +++ b/tests/Jellyfin.Naming.Tests/Common/NamingOptionsTest.cs @@ -0,0 +1,36 @@ +using Emby.Naming.Common; +using Xunit; + +namespace Jellyfin.Naming.Tests.Common +{ + public class NamingOptionsTest + { + [Fact] + public void TestNamingOptionsCompile() + { + var options = new NamingOptions(); + + Assert.NotEmpty(options.VideoFileStackingRegexes); + Assert.NotEmpty(options.CleanDateTimeRegexes); + Assert.NotEmpty(options.CleanStringRegexes); + Assert.NotEmpty(options.EpisodeWithoutSeasonRegexes); + Assert.NotEmpty(options.EpisodeMultiPartRegexes); + } + + [Fact] + public void TestNamingOptionsEpisodeExpressions() + { + var exp = new EpisodeExpression(string.Empty); + + Assert.False(exp.IsOptimistic); + exp.IsOptimistic = true; + Assert.True(exp.IsOptimistic); + + Assert.Equal(string.Empty, exp.Expression); + Assert.NotNull(exp.Regex); + exp.Expression = "test"; + Assert.Equal("test", exp.Expression); + Assert.NotNull(exp.Regex); + } + } +} diff --git a/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs b/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs index d11809de1..f3abacb4f 100644 --- a/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs +++ b/tests/Jellyfin.Naming.Tests/Subtitles/SubtitleParserTests.cs @@ -1,4 +1,4 @@ -using System; +using System; using Emby.Naming.Common; using Emby.Naming.Subtitles; using Xunit; @@ -26,21 +26,17 @@ namespace Jellyfin.Naming.Tests.Subtitles Assert.Equal(language, result?.Language, true); Assert.Equal(isDefault, result?.IsDefault); Assert.Equal(isForced, result?.IsForced); + Assert.Equal(input, result?.Path); } [Theory] [InlineData("The Skin I Live In (2011).mp4")] + [InlineData("")] public void SubtitleParser_InvalidFileName_ReturnsNull(string input) { var parser = new SubtitleParser(_namingOptions); Assert.Null(parser.ParseFile(input)); } - - [Fact] - public void SubtitleParser_EmptyFileName_ThrowsArgumentException() - { - Assert.Throws<ArgumentException>(() => new SubtitleParser(_namingOptions).ParseFile(string.Empty)); - } } } diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs index 03aeb7f76..12fc19bc4 100644 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs +++ b/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs @@ -1,4 +1,4 @@ -using Emby.Naming.Common; +using Emby.Naming.Common; using Emby.Naming.TV; using Xunit; @@ -7,43 +7,98 @@ namespace Jellyfin.Naming.Tests.TV public class EpisodePathParserTest { [Theory] - [InlineData("/media/Foo/Foo-S01E01", "Foo", 1, 1)] - [InlineData("/media/Foo - S04E011", "Foo", 4, 11)] - [InlineData("/media/Foo/Foo s01x01", "Foo", 1, 1)] - [InlineData("/media/Foo (2019)/Season 4/Foo (2019).S04E03", "Foo (2019)", 4, 3)] - [InlineData("D:\\media\\Foo\\Foo-S01E01", "Foo", 1, 1)] - [InlineData("D:\\media\\Foo - S04E011", "Foo", 4, 11)] - [InlineData("D:\\media\\Foo\\Foo s01x01", "Foo", 1, 1)] - [InlineData("D:\\media\\Foo (2019)\\Season 4\\Foo (2019).S04E03", "Foo (2019)", 4, 3)] - [InlineData("/Season 2/Elementary - 02x03-04-15 - Ep Name.mp4", "Elementary", 2, 3)] - [InlineData("/Season 1/seriesname S01E02 blah.avi", "seriesname", 1, 2)] - [InlineData("/Running Man/Running Man S2017E368.mkv", "Running Man", 2017, 368)] - [InlineData("/Season 1/seriesname 01x02 blah.avi", "seriesname", 1, 2)] - [InlineData("/Season 25/The Simpsons.S25E09.Steal this episode.mp4", "The Simpsons", 25, 9)] - [InlineData("/Season 1/seriesname S01x02 blah.avi", "seriesname", 1, 2)] - [InlineData("/Season 2/Elementary - 02x03 - 02x04 - 02x15 - Ep Name.mp4", "Elementary", 2, 3)] - [InlineData("/Season 1/seriesname S01xE02 blah.avi", "seriesname", 1, 2)] - [InlineData("/Season 02/Elementary - 02x03 - x04 - x15 - Ep Name.mp4", "Elementary", 2, 3)] - [InlineData("/Season 02/Elementary - 02x03x04x15 - Ep Name.mp4", "Elementary", 2, 3)] - [InlineData("/Season 02/Elementary - 02x03-E15 - Ep Name.mp4", "Elementary", 2, 3)] - [InlineData("/Season 1/Elementary - S01E23-E24-E26 - The Woman.mp4", "Elementary", 1, 23)] - [InlineData("/The Wonder Years/The.Wonder.Years.S04.PDTV.x264-JCH/The Wonder Years s04e07 Christmas Party NTSC PDTV.avi", "The Wonder Years", 4, 7)] + [InlineData("/media/Foo/Foo-S01E01", true, "Foo", 1, 1)] + [InlineData("/media/Foo - S04E011", true, "Foo", 4, 11)] + [InlineData("/media/Foo/Foo s01x01", true, "Foo", 1, 1)] + [InlineData("/media/Foo (2019)/Season 4/Foo (2019).S04E03", true, "Foo (2019)", 4, 3)] + [InlineData("D:\\media\\Foo\\Foo-S01E01", true, "Foo", 1, 1)] + [InlineData("D:\\media\\Foo - S04E011", true, "Foo", 4, 11)] + [InlineData("D:\\media\\Foo\\Foo s01x01", true, "Foo", 1, 1)] + [InlineData("D:\\media\\Foo (2019)\\Season 4\\Foo (2019).S04E03", true, "Foo (2019)", 4, 3)] + [InlineData("/Season 2/Elementary - 02x03-04-15 - Ep Name.mp4", false, "Elementary", 2, 3)] + [InlineData("/Season 1/seriesname S01E02 blah.avi", false, "seriesname", 1, 2)] + [InlineData("/Running Man/Running Man S2017E368.mkv", false, "Running Man", 2017, 368)] + [InlineData("/Season 1/seriesname 01x02 blah.avi", false, "seriesname", 1, 2)] + [InlineData("/Season 25/The Simpsons.S25E09.Steal this episode.mp4", false, "The Simpsons", 25, 9)] + [InlineData("/Season 1/seriesname S01x02 blah.avi", false, "seriesname", 1, 2)] + [InlineData("/Season 2/Elementary - 02x03 - 02x04 - 02x15 - Ep Name.mp4", false, "Elementary", 2, 3)] + [InlineData("/Season 1/seriesname S01xE02 blah.avi", false, "seriesname", 1, 2)] + [InlineData("/Season 02/Elementary - 02x03 - x04 - x15 - Ep Name.mp4", false, "Elementary", 2, 3)] + [InlineData("/Season 02/Elementary - 02x03x04x15 - Ep Name.mp4", false, "Elementary", 2, 3)] + [InlineData("/Season 02/Elementary - 02x03-E15 - Ep Name.mp4", false, "Elementary", 2, 3)] + [InlineData("/Season 1/Elementary - S01E23-E24-E26 - The Woman.mp4", false, "Elementary", 1, 23)] + [InlineData("/The Wonder Years/The.Wonder.Years.S04.PDTV.x264-JCH/The Wonder Years s04e07 Christmas Party NTSC PDTV.avi", false, "The Wonder Years", 4, 7)] // TODO: [InlineData("/Castle Rock 2x01 Que el rio siga su curso [WEB-DL HULU 1080p h264 Dual DD5.1 Subs].mkv", "Castle Rock", 2, 1)] // TODO: [InlineData("/After Life 1x06 Episodio 6 [WEB-DL NF 1080p h264 Dual DD 5.1 Sub].mkv", "After Life", 1, 6)] // TODO: [InlineData("/Season 4/Uchuu.Senkan.Yamato.2199.E03.avi", "Uchuu Senkan Yamoto 2199", 4, 3)] // TODO: [InlineData("The Daily Show/The Daily Show 25x22 - [WEBDL-720p][AAC 2.0][x264] Noah Baumbach-TBS.mkv", "The Daily Show", 25, 22)] // TODO: [InlineData("Watchmen (2019)/Watchmen 1x03 [WEBDL-720p][EAC3 5.1][h264][-TBS] - She Was Killed by Space Junk.mkv", "Watchmen (2019)", 1, 3)] // TODO: [InlineData("/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv/The.Legend.of.Condor.Heroes.2017.E07.V2.web-dl.1080p.h264.aac-hdctv.mkv", "The Legend of Condor Heroes 2017", 1, 7)] - public void ParseEpisodesCorrectly(string path, string name, int season, int episode) + public void ParseEpisodesCorrectly(string path, bool isDirectory, string name, int season, int episode) { NamingOptions o = new NamingOptions(); EpisodePathParser p = new EpisodePathParser(o); - var res = p.Parse(path, false); + var res = p.Parse(path, isDirectory); Assert.True(res.Success); Assert.Equal(name, res.SeriesName); Assert.Equal(season, res.SeasonNumber); Assert.Equal(episode, res.EpisodeNumber); } + + [Theory] + [InlineData("/test/01-03.avi", true, true)] + public void EpisodePathParserTest_DifferentExpressionsParameters(string path, bool? isNamed, bool? isOptimistic) + { + NamingOptions o = new NamingOptions(); + EpisodePathParser p = new EpisodePathParser(o); + var res = p.Parse(path, false, isNamed, isOptimistic); + + Assert.True(res.Success); + } + + [Fact] + public void EpisodePathParserTest_FalsePositivePixelRate() + { + NamingOptions o = new NamingOptions(); + EpisodePathParser p = new EpisodePathParser(o); + var res = p.Parse("Series Special (1920x1080).mkv", false); + + Assert.False(res.Success); + } + + [Fact] + public void EpisodeResolverTest_WrongExtension() + { + var res = new EpisodeResolver(new NamingOptions()).Resolve("test.mp3", false); + Assert.Null(res); + } + + [Fact] + public void EpisodeResolverTest_WrongExtensionStub() + { + var res = new EpisodeResolver(new NamingOptions()).Resolve("dvd.disc", false); + Assert.NotNull(res); + Assert.True(res!.IsStub); + } + + /* + * EpisodePathParser.cs:130 is currently unreachable, but the piece of code is useful and could be reached with addition of new EpisodeExpressions. + * In order to preserve it but achieve 100% code coverage the test case below with made up expressions and filename is used. + */ + [Fact] + public void EpisodePathParserTest_EmptyDateParsers() + { + NamingOptions o = new NamingOptions() + { + EpisodeExpressions = new[] { new EpisodeExpression("(([0-9]{4})-([0-9]{2})-([0-9]{2}) [0-9]{2}:[0-9]{2}:[0-9]{2})", true) } + }; + o.Compile(); + + EpisodePathParser p = new EpisodePathParser(o); + var res = p.Parse("ABC_2019_10_21 11:00:00", false); + + Assert.True(res.Success); + } } } diff --git a/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs index 3513050b6..58ea0bec5 100644 --- a/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs @@ -74,7 +74,7 @@ namespace Jellyfin.Naming.Tests.TV var result = new EpisodePathParser(options) .Parse(filename, false); - Assert.Equal(result.EndingEpsiodeNumber, endingEpisodeNumber); + Assert.Equal(result.EndingEpisodeNumber, endingEpisodeNumber); } } } diff --git a/tests/Jellyfin.Naming.Tests/TV/SeasonFolderTests.cs b/tests/Jellyfin.Naming.Tests/TV/SeasonFolderTests.cs index 078f940b2..b7b5b54ec 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeasonFolderTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeasonFolderTests.cs @@ -1,4 +1,4 @@ -using Emby.Naming.TV; +using Emby.Naming.TV; using Xunit; namespace Jellyfin.Naming.Tests.TV @@ -6,26 +6,30 @@ namespace Jellyfin.Naming.Tests.TV public class SeasonFolderTests { [Theory] - [InlineData(@"/Drive/Season 1", 1)] - [InlineData(@"/Drive/Season 2", 2)] - [InlineData(@"/Drive/Season 02", 2)] - [InlineData(@"/Drive/Seinfeld/S02", 2)] - [InlineData(@"/Drive/Seinfeld/2", 2)] - [InlineData(@"/Drive/Season 2009", 2009)] - [InlineData(@"/Drive/Season1", 1)] - [InlineData(@"The Wonder Years/The.Wonder.Years.S04.PDTV.x264-JCH", 4)] - [InlineData(@"/Drive/Season 7 (2016)", 7)] - [InlineData(@"/Drive/Staffel 7 (2016)", 7)] - [InlineData(@"/Drive/Stagione 7 (2016)", 7)] - [InlineData(@"/Drive/Season (8)", null)] - [InlineData(@"/Drive/3.Staffel", 3)] - [InlineData(@"/Drive/s06e05", null)] - [InlineData(@"/Drive/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv", null)] - public void GetSeasonNumberFromPathTest(string path, int? seasonNumber) + [InlineData(@"/Drive/Season 1", 1, true)] + [InlineData(@"/Drive/Season 2", 2, true)] + [InlineData(@"/Drive/Season 02", 2, true)] + [InlineData(@"/Drive/Seinfeld/S02", 2, true)] + [InlineData(@"/Drive/Seinfeld/2", 2, true)] + [InlineData(@"/Drive/Season 2009", 2009, true)] + [InlineData(@"/Drive/Season1", 1, true)] + [InlineData(@"The Wonder Years/The.Wonder.Years.S04.PDTV.x264-JCH", 4, true)] + [InlineData(@"/Drive/Season 7 (2016)", 7, false)] + [InlineData(@"/Drive/Staffel 7 (2016)", 7, false)] + [InlineData(@"/Drive/Stagione 7 (2016)", 7, false)] + [InlineData(@"/Drive/Season (8)", null, false)] + [InlineData(@"/Drive/3.Staffel", 3, false)] + [InlineData(@"/Drive/s06e05", null, false)] + [InlineData(@"/Drive/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv", null, false)] + [InlineData(@"/Drive/extras", 0, true)] + [InlineData(@"/Drive/specials", 0, true)] + public void GetSeasonNumberFromPathTest(string path, int? seasonNumber, bool isSeasonDirectory) { var result = SeasonPathParser.Parse(path, true, true); + Assert.Equal(result.SeasonNumber != null, result.Success); Assert.Equal(result.SeasonNumber, seasonNumber); + Assert.Equal(isSeasonDirectory, result.IsSeasonFolder); } } } diff --git a/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs index 40b41b9f3..89579c037 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs @@ -1,4 +1,5 @@ -using Emby.Naming.Common; +using System.IO; +using Emby.Naming.Common; using Emby.Naming.TV; using Xunit; @@ -15,7 +16,6 @@ namespace Jellyfin.Naming.Tests.TV [InlineData("/server/The Walking Dead 4x01.mp4", "The Walking Dead", 4, 1)] [InlineData("/server/the_simpsons-s02e01_18536.mp4", "the_simpsons", 2, 1)] [InlineData("/server/Temp/S01E02 foo.mp4", "", 1, 2)] - [InlineData("Series/4-12 - The Woman.mp4", "", 4, 12)] [InlineData("Series/4x12 - The Woman.mp4", "", 4, 12)] [InlineData("Series/LA X, Pt. 1_s06e32.mp4", "LA X, Pt. 1", 6, 32)] [InlineData("[Baz-Bar]Foo - [1080p][Multiple Subtitle]/[Baz-Bar] Foo - 05 [1080p][Multiple Subtitle].mkv", "Foo", null, 5)] @@ -24,16 +24,37 @@ namespace Jellyfin.Naming.Tests.TV // TODO: [InlineData("[Baz-Bar]Foo - 01 - 12[1080p][Multiple Subtitle]/[Baz-Bar] Foo - 05 [1080p][Multiple Subtitle].mkv", "Foo", null, 5)] // TODO: [InlineData("E:\\Anime\\Yahari Ore no Seishun Love Comedy wa Machigatteiru\\Yahari Ore no Seishun Love Comedy wa Machigatteiru. Zoku\\Oregairu Zoku 11 - Hayama Hayato Always Renconds to Everyone's Expectations..mkv", "Yahari Ore no Seishun Love Comedy wa Machigatteiru", null, 11)] // TODO: [InlineData(@"/Library/Series/The Grand Tour (2016)/Season 1/S01E01 The Holy Trinity.mkv", "The Grand Tour", 1, 1)] - public void Test(string path, string seriesName, int? seasonNumber, int? episodeNumber) + public void TestSimple(string path, string seriesName, int? seasonNumber, int? episodeNumber) + { + Test(path, seriesName, seasonNumber, episodeNumber, null); + } + + [Theory] + [InlineData("Series/4-12 - The Woman.mp4", "", 4, 12, 12)] + public void TestWithPossibleEpisodeEnd(string path, string seriesName, int? seasonNumber, int? episodeNumber, int? episodeEndNumber) + { + Test(path, seriesName, seasonNumber, episodeNumber, episodeEndNumber); + } + + private void Test(string path, string seriesName, int? seasonNumber, int? episodeNumber, int? episodeEndNumber) { var options = new NamingOptions(); var result = new EpisodeResolver(options) .Resolve(path, false); + Assert.NotNull(result); Assert.Equal(seasonNumber, result?.SeasonNumber); Assert.Equal(episodeNumber, result?.EpisodeNumber); Assert.Equal(seriesName, result?.SeriesName, true); + Assert.Equal(path, result?.Path); + Assert.Equal(Path.GetExtension(path).Substring(1), result?.Container); + Assert.Null(result?.Format3D); + Assert.False(result?.Is3D); + Assert.False(result?.IsStub); + Assert.Null(result?.StubType); + Assert.Equal(episodeEndNumber, result?.EndingEpisodeNumber); + Assert.False(result?.IsByDate); } } } diff --git a/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs b/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs index ed971eed7..15cb5c72f 100644 --- a/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/CleanDateTimeTests.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using Emby.Naming.Common; using Emby.Naming.Video; using Xunit; @@ -51,6 +51,8 @@ namespace Jellyfin.Naming.Tests.Video [InlineData("My Movie 2013-12-09", "My Movie 2013-12-09", null)] [InlineData("My Movie 20131209", "My Movie 20131209", null)] [InlineData("My Movie 2013-12-09 2013", "My Movie 2013-12-09", 2013)] + [InlineData(null, null, null)] + [InlineData("", "", null)] public void CleanDateTimeTest(string input, string expectedName, int? expectedYear) { input = Path.GetFileName(input); diff --git a/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs b/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs index 8dfb8f859..d34f65409 100644 --- a/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/ExtraTests.cs @@ -1,7 +1,9 @@ -using Emby.Naming.Common; +using System; +using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Model.Entities; using Xunit; +using MediaType = Emby.Naming.Common.MediaType; namespace Jellyfin.Naming.Tests.Video { @@ -93,6 +95,23 @@ namespace Jellyfin.Naming.Tests.Video } } + [Fact] + public void TestExtraInfo_InvalidRuleType() + { + var rule = new ExtraRule(ExtraType.Unknown, ExtraRuleType.Regex, @"([eE]x(tra)?\.\w+)", MediaType.Video); + var options = new NamingOptions { VideoExtraRules = new[] { rule } }; + var res = GetExtraTypeParser(options).GetExtraInfo("extra.mp4"); + + Assert.Equal(rule, res.Rule); + } + + [Fact] + public void TestFlagsParser() + { + var flags = new FlagParser(_videoOptions).GetFlags(string.Empty); + Assert.Empty(flags); + } + private ExtraResolver GetExtraTypeParser(NamingOptions videoOptions) { return new ExtraResolver(videoOptions); diff --git a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs index 4198d69ff..9df6904ef 100644 --- a/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/MultiVersionTests.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Model.IO; @@ -11,8 +12,8 @@ namespace Jellyfin.Naming.Tests.Video private readonly NamingOptions _namingOptions = new NamingOptions(); // FIXME - // [Fact] - private void TestMultiEdition1() + [Fact] + public void TestMultiEdition1() { var files = new[] { @@ -35,8 +36,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestMultiEdition2() + [Fact] + public void TestMultiEdition2() { var files = new[] { @@ -81,8 +82,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestLetterFolders() + [Fact] + public void TestLetterFolders() { var files = new[] { @@ -109,8 +110,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestMultiVersionLimit() + [Fact] + public void TestMultiVersionLimit() { var files = new[] { @@ -138,8 +139,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestMultiVersionLimit2() + [Fact] + public void TestMultiVersionLimit2() { var files = new[] { @@ -168,8 +169,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestMultiVersion3() + [Fact] + public void TestMultiVersion3() { var files = new[] { @@ -194,8 +195,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestMultiVersion4() + [Fact] + public void TestMultiVersion4() { // Test for false positive @@ -221,9 +222,8 @@ namespace Jellyfin.Naming.Tests.Video Assert.Empty(result[0].AlternateVersions); } - // FIXME - // [Fact] - private void TestMultiVersion5() + [Fact] + public void TestMultiVersion5() { var files = new[] { @@ -254,8 +254,8 @@ namespace Jellyfin.Naming.Tests.Video } // FIXME - // [Fact] - private void TestMultiVersion6() + [Fact] + public void TestMultiVersion6() { var files = new[] { @@ -285,9 +285,8 @@ namespace Jellyfin.Naming.Tests.Video Assert.True(result[0].AlternateVersions[5].Is3D); } - // FIXME - // [Fact] - private void TestMultiVersion7() + [Fact] + public void TestMultiVersion7() { var files = new[] { @@ -306,12 +305,9 @@ namespace Jellyfin.Naming.Tests.Video Assert.Equal(2, result.Count); } - // FIXME - // [Fact] - private void TestMultiVersion8() + [Fact] + public void TestMultiVersion8() { - // This is not actually supported yet - var files = new[] { @"/movies/Iron Man/Iron Man.mkv", @@ -339,9 +335,8 @@ namespace Jellyfin.Naming.Tests.Video Assert.True(result[0].AlternateVersions[4].Is3D); } - // FIXME - // [Fact] - private void TestMultiVersion9() + [Fact] + public void TestMultiVersion9() { // Test for false positive @@ -367,9 +362,8 @@ namespace Jellyfin.Naming.Tests.Video Assert.Empty(result[0].AlternateVersions); } - // FIXME - // [Fact] - private void TestMultiVersion10() + [Fact] + public void TestMultiVersion10() { var files = new[] { @@ -390,12 +384,9 @@ namespace Jellyfin.Naming.Tests.Video Assert.Single(result[0].AlternateVersions); } - // FIXME - // [Fact] - private void TestMultiVersion11() + [Fact] + public void TestMultiVersion11() { - // Currently not supported but we should probably handle this. - var files = new[] { @"/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016) [1080p] Blu-ray.x264.DTS.mkv", @@ -415,6 +406,16 @@ namespace Jellyfin.Naming.Tests.Video Assert.Single(result[0].AlternateVersions); } + [Fact] + public void TestEmptyList() + { + var resolver = GetResolver(); + + var result = resolver.Resolve(new List<FileSystemMetadata>()).ToList(); + + Assert.Empty(result); + } + private VideoListResolver GetResolver() { return new VideoListResolver(_namingOptions); diff --git a/tests/Jellyfin.Naming.Tests/Video/StubTests.cs b/tests/Jellyfin.Naming.Tests/Video/StubTests.cs index 30ba94136..6e759c6d6 100644 --- a/tests/Jellyfin.Naming.Tests/Video/StubTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/StubTests.cs @@ -1,4 +1,4 @@ -using Emby.Naming.Common; +using Emby.Naming.Common; using Emby.Naming.Video; using Xunit; @@ -23,6 +23,7 @@ namespace Jellyfin.Naming.Tests.Video Test("video.hdtv.disc", true, "tv"); Test("video.pdtv.disc", true, "tv"); Test("video.dsr.disc", true, "tv"); + Test(string.Empty, false, "tv"); } [Fact] diff --git a/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs b/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs index 12c4a50fe..215c7e540 100644 --- a/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/VideoListResolverTests.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Model.IO; @@ -370,6 +370,26 @@ namespace Jellyfin.Naming.Tests.Video } [Fact] + public void TestFourRooms() + { + var files = new[] + { + @"Four Rooms - A.avi", + @"Four Rooms - A.mp4" + }; + + var resolver = GetResolver(); + + var result = resolver.Resolve(files.Select(i => new FileSystemMetadata + { + IsDirectory = false, + FullName = i + }).ToList()).ToList(); + + Assert.Equal(2, result.Count); + } + + [Fact] public void TestMovieTrailer() { var files = new[] @@ -431,6 +451,13 @@ namespace Jellyfin.Naming.Tests.Video Assert.Single(result); } + [Fact] + public void TestDirectoryStack() + { + var stack = new FileStack(); + Assert.False(stack.ContainsFile("XX", true)); + } + private VideoListResolver GetResolver() { return new VideoListResolver(_namingOptions); diff --git a/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs b/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs index 99828b2eb..3bdafa84d 100644 --- a/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/Video/VideoResolverTests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Generic; +using System.Linq; using Emby.Naming.Common; using Emby.Naming.Video; using MediaBrowser.Model.Entities; @@ -14,165 +15,135 @@ namespace Jellyfin.Naming.Tests.Video { yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/7 Psychos.mkv/7 Psychos.mkv", - Container = "mkv", - Name = "7 Psychos" - } + new VideoFileInfo( + path: @"/server/Movies/7 Psychos.mkv/7 Psychos.mkv", + container: "mkv", + name: "7 Psychos") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/3 days to kill (2005)/3 days to kill (2005).mkv", - Container = "mkv", - Name = "3 days to kill", - Year = 2005 - } + new VideoFileInfo( + path: @"/server/Movies/3 days to kill (2005)/3 days to kill (2005).mkv", + container: "mkv", + name: "3 days to kill", + year: 2005) }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/American Psycho/American.Psycho.mkv", - Container = "mkv", - Name = "American.Psycho", - } + new VideoFileInfo( + path: @"/server/Movies/American Psycho/American.Psycho.mkv", + container: "mkv", + name: "American.Psycho") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/brave (2007)/brave (2006).3d.sbs.mkv", - Container = "mkv", - Name = "brave", - Year = 2006, - Is3D = true, - Format3D = "sbs", - } + new VideoFileInfo( + path: @"/server/Movies/brave (2007)/brave (2006).3d.sbs.mkv", + container: "mkv", + name: "brave", + year: 2006, + is3D: true, + format3D: "sbs") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/300 (2007)/300 (2006).3d1.sbas.mkv", - Container = "mkv", - Name = "300", - Year = 2006 - } + new VideoFileInfo( + path: @"/server/Movies/300 (2007)/300 (2006).3d1.sbas.mkv", + container: "mkv", + name: "300", + year: 2006) }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/300 (2007)/300 (2006).3d.sbs.mkv", - Container = "mkv", - Name = "300", - Year = 2006, - Is3D = true, - Format3D = "sbs", - } + new VideoFileInfo( + path: @"/server/Movies/300 (2007)/300 (2006).3d.sbs.mkv", + container: "mkv", + name: "300", + year: 2006, + is3D: true, + format3D: "sbs") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/brave (2007)/brave (2006)-trailer.bluray.disc", - Container = "disc", - Name = "brave", - Year = 2006, - IsStub = true, - StubType = "bluray", - } + new VideoFileInfo( + path: @"/server/Movies/brave (2007)/brave (2006)-trailer.bluray.disc", + container: "disc", + name: "brave", + year: 2006, + isStub: true, + stubType: "bluray") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/300 (2007)/300 (2006)-trailer.bluray.disc", - Container = "disc", - Name = "300", - Year = 2006, - IsStub = true, - StubType = "bluray", - } + new VideoFileInfo( + path: @"/server/Movies/300 (2007)/300 (2006)-trailer.bluray.disc", + container: "disc", + name: "300", + year: 2006, + isStub: true, + stubType: "bluray") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/Brave (2007)/Brave (2006).bluray.disc", - Container = "disc", - Name = "Brave", - Year = 2006, - IsStub = true, - StubType = "bluray", - } + new VideoFileInfo( + path: @"/server/Movies/Brave (2007)/Brave (2006).bluray.disc", + container: "disc", + name: "Brave", + year: 2006, + isStub: true, + stubType: "bluray") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/300 (2007)/300 (2006).bluray.disc", - Container = "disc", - Name = "300", - Year = 2006, - IsStub = true, - StubType = "bluray", - } + new VideoFileInfo( + path: @"/server/Movies/300 (2007)/300 (2006).bluray.disc", + container: "disc", + name: "300", + year: 2006, + isStub: true, + stubType: "bluray") }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/300 (2007)/300 (2006)-trailer.mkv", - Container = "mkv", - Name = "300", - Year = 2006, - ExtraType = ExtraType.Trailer, - } + new VideoFileInfo( + path: @"/server/Movies/300 (2007)/300 (2006)-trailer.mkv", + container: "mkv", + name: "300", + year: 2006, + extraType: ExtraType.Trailer) }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/Brave (2007)/Brave (2006)-trailer.mkv", - Container = "mkv", - Name = "Brave", - Year = 2006, - ExtraType = ExtraType.Trailer, - } + new VideoFileInfo( + path: @"/server/Movies/Brave (2007)/Brave (2006)-trailer.mkv", + container: "mkv", + name: "Brave", + year: 2006, + extraType: ExtraType.Trailer) }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/300 (2007)/300 (2006).mkv", - Container = "mkv", - Name = "300", - Year = 2006 - } + new VideoFileInfo( + path: @"/server/Movies/300 (2007)/300 (2006).mkv", + container: "mkv", + name: "300", + year: 2006) }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/Bad Boys (1995)/Bad Boys (1995).mkv", - Container = "mkv", - Name = "Bad Boys", - Year = 1995, - } + new VideoFileInfo( + path: @"/server/Movies/Bad Boys (1995)/Bad Boys (1995).mkv", + container: "mkv", + name: "Bad Boys", + year: 1995) }; yield return new object[] { - new VideoFileInfo() - { - Path = @"/server/Movies/Brave (2007)/Brave (2006).mkv", - Container = "mkv", - Name = "Brave", - Year = 2006, - } + new VideoFileInfo( + path: @"/server/Movies/Brave (2007)/Brave (2006).mkv", + container: "mkv", + name: "Brave", + year: 2006) }; } @@ -194,6 +165,34 @@ namespace Jellyfin.Naming.Tests.Video Assert.Equal(result?.StubType, expectedResult.StubType); Assert.Equal(result?.IsDirectory, expectedResult.IsDirectory); Assert.Equal(result?.FileNameWithoutExtension, expectedResult.FileNameWithoutExtension); + Assert.Equal(result?.ToString(), expectedResult.ToString()); + } + + [Fact] + public void ResolveFile_EmptyPath() + { + var result = new VideoResolver(_namingOptions).ResolveFile(string.Empty); + + Assert.Null(result); + } + + [Fact] + public void ResolveDirectoryTest() + { + var paths = new[] + { + @"/Server/Iron Man", + @"Batman", + string.Empty + }; + + var resolver = new VideoResolver(_namingOptions); + var results = paths.Select(path => resolver.ResolveDirectory(path)).ToList(); + + Assert.Equal(3, results.Count); + Assert.NotNull(results[0]); + Assert.NotNull(results[1]); + Assert.Null(results[2]); } } } 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 b960fda72..547f80ed9 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -17,7 +17,7 @@ <PackageReference Include="AutoFixture" Version="4.14.0" /> <PackageReference Include="AutoFixture.AutoMoq" Version="4.14.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.0" /> - <PackageReference Include="Moq" Version="4.14.7" /> + <PackageReference Include="Moq" Version="4.15.1" /> <PackageReference Include="xunit" Version="2.4.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" /> <PackageReference Include="coverlet.collector" Version="1.3.0" /> |
