@ -79,7 +79,7 @@ public class MovieFolderScannerTests
@@ -79,7 +79,7 @@ public class MovieFolderScannerTests
_l ocalMetadataProvider . RefreshFallbackMetadata ( Arg . Any < Movie > ( ) )
. Returns ( arg = >
{
( ( Movie ) arg . Arg < MediaItem > ( ) ) . MovieMetadata = new List < MovieMetadata > { new ( ) } ;
( ( Movie ) arg . Arg < MediaItem > ( ) ) . MovieMetadata = [ new MovieMetadata { Artwork = [ ] } ] ;
return Task . FromResult ( true ) ;
} ) ;
@ -457,6 +457,310 @@ public class MovieFolderScannerTests
@@ -457,6 +457,310 @@ public class MovieFolderScannerTests
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( posterPath , ArtworkKind . Poster ) ;
}
[Test]
public async Task NewMovie_Statistics_And_FallbackMetadata_And_FanArt (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
string videoExtension ,
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.ImageFileExtensions))]
string imageExtension )
{
string moviePath = Path . Combine (
FakeRoot ,
Path . Combine ( "Movie (2020)" , $"Movie (2020){videoExtension}" ) ) ;
string fanArtPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"fanart.{imageExtension}" ) ;
MovieFolderScanner service = GetService (
new FakeFileEntry ( moviePath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( fanArtPath ) { LastWriteTime = DateTime . Now }
) ;
var libraryPath = new LibraryPath
{ Id = 1 , Path = FakeRoot , LibraryFolders = new List < LibraryFolder > ( ) } ;
Either < BaseError , Unit > result = await service . ScanFolder (
libraryPath ,
FFmpegPath ,
FFprobePath ,
0 ,
1 ,
CancellationToken . None ) ;
result . IsRight . ShouldBeTrue ( ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
Arg . Any < LibraryPath > ( ) ,
Arg . Any < LibraryFolder > ( ) ,
Arg . Any < string > ( ) ,
Arg . Any < CancellationToken > ( ) ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
libraryPath ,
Arg . Any < LibraryFolder > ( ) ,
moviePath ,
Arg . Any < CancellationToken > ( ) ) ;
await _l ocalStatisticsProvider . Received ( 1 ) . RefreshStatistics (
FFmpegPath ,
FFprobePath ,
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _l ocalMetadataProvider . Received ( 1 ) . RefreshFallbackMetadata (
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( fanArtPath , ArtworkKind . FanArt ) ;
}
[Test]
public async Task NewMovie_Statistics_And_FallbackMetadata_And_FanArt_Backdrop (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
string videoExtension ,
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.ImageFileExtensions))]
string imageExtension )
{
string moviePath = Path . Combine (
FakeRoot ,
Path . Combine ( "Movie (2020)" , $"Movie (2020){videoExtension}" ) ) ;
string fanArtPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"backdrop.{imageExtension}" ) ;
MovieFolderScanner service = GetService (
new FakeFileEntry ( moviePath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( fanArtPath ) { LastWriteTime = DateTime . Now }
) ;
var libraryPath = new LibraryPath
{ Id = 1 , Path = FakeRoot , LibraryFolders = new List < LibraryFolder > ( ) } ;
Either < BaseError , Unit > result = await service . ScanFolder (
libraryPath ,
FFmpegPath ,
FFprobePath ,
0 ,
1 ,
CancellationToken . None ) ;
result . IsRight . ShouldBeTrue ( ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
Arg . Any < LibraryPath > ( ) ,
Arg . Any < LibraryFolder > ( ) ,
Arg . Any < string > ( ) ,
Arg . Any < CancellationToken > ( ) ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
libraryPath ,
Arg . Any < LibraryFolder > ( ) ,
moviePath ,
Arg . Any < CancellationToken > ( ) ) ;
await _l ocalStatisticsProvider . Received ( 1 ) . RefreshStatistics (
FFmpegPath ,
FFprobePath ,
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _l ocalMetadataProvider . Received ( 1 ) . RefreshFallbackMetadata (
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( fanArtPath , ArtworkKind . FanArt ) ;
}
[Test]
public async Task NewMovie_Statistics_And_FallbackMetadata_And_MovieNameFanArt (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
string videoExtension ,
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.ImageFileExtensions))]
string imageExtension )
{
string moviePath = Path . Combine (
FakeRoot ,
Path . Combine ( "Movie (2020)" , $"Movie (2020){videoExtension}" ) ) ;
string fanArtPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"Movie (2020)-fanart.{imageExtension}" ) ;
MovieFolderScanner service = GetService (
new FakeFileEntry ( moviePath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( fanArtPath ) { LastWriteTime = DateTime . Now }
) ;
var libraryPath = new LibraryPath
{ Id = 1 , Path = FakeRoot , LibraryFolders = new List < LibraryFolder > ( ) } ;
Either < BaseError , Unit > result = await service . ScanFolder (
libraryPath ,
FFmpegPath ,
FFprobePath ,
0 ,
1 ,
CancellationToken . None ) ;
result . IsRight . ShouldBeTrue ( ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
Arg . Any < LibraryPath > ( ) ,
Arg . Any < LibraryFolder > ( ) ,
Arg . Any < string > ( ) ,
Arg . Any < CancellationToken > ( ) ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
libraryPath ,
Arg . Any < LibraryFolder > ( ) ,
moviePath ,
Arg . Any < CancellationToken > ( ) ) ;
await _l ocalStatisticsProvider . Received ( 1 ) . RefreshStatistics (
FFmpegPath ,
FFprobePath ,
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _l ocalMetadataProvider . Received ( 1 ) . RefreshFallbackMetadata (
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( fanArtPath , ArtworkKind . FanArt ) ;
}
[Test]
public async Task NewMovie_Statistics_And_FallbackMetadata_FanArt_Ignores_Folder_Image (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
string videoExtension ,
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.ImageFileExtensions))]
string imageExtension )
{
string moviePath = Path . Combine (
FakeRoot ,
Path . Combine ( "Movie (2020)" , $"Movie (2020){videoExtension}" ) ) ;
string folderImagePath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"folder.{imageExtension}" ) ;
MovieFolderScanner service = GetService (
new FakeFileEntry ( moviePath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( folderImagePath ) { LastWriteTime = DateTime . Now }
) ;
var libraryPath = new LibraryPath
{ Id = 1 , Path = FakeRoot , LibraryFolders = new List < LibraryFolder > ( ) } ;
Either < BaseError , Unit > result = await service . ScanFolder (
libraryPath ,
FFmpegPath ,
FFprobePath ,
0 ,
1 ,
CancellationToken . None ) ;
result . IsRight . ShouldBeTrue ( ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
Arg . Any < LibraryPath > ( ) ,
Arg . Any < LibraryFolder > ( ) ,
Arg . Any < string > ( ) ,
Arg . Any < CancellationToken > ( ) ) ;
await _ movieRepository . Received ( 1 ) . GetOrAdd (
libraryPath ,
Arg . Any < LibraryFolder > ( ) ,
moviePath ,
Arg . Any < CancellationToken > ( ) ) ;
await _l ocalStatisticsProvider . Received ( 1 ) . RefreshStatistics (
FFmpegPath ,
FFprobePath ,
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
await _l ocalMetadataProvider . Received ( 1 ) . RefreshFallbackMetadata (
Arg . Is < Movie > ( i = > i . MediaVersions . Head ( ) . MediaFiles . Head ( ) . Path = = moviePath ) ) ;
// Should receive Poster call (as folder.ext is valid for poster)
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( folderImagePath , ArtworkKind . Poster ) ;
// Should NOT receive FanArt call
await _ imageCache . DidNotReceive ( ) . CopyArtworkToCache ( Arg . Any < string > ( ) , ArtworkKind . FanArt ) ;
}
[Test]
public async Task NewMovie_Statistics_And_FallbackMetadata_Poster_Priority (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
string videoExtension ,
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.ImageFileExtensions))]
string imageExtension )
{
string moviePath = Path . Combine (
FakeRoot ,
Path . Combine ( "Movie (2020)" , $"Movie (2020){videoExtension}" ) ) ;
string posterPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"poster.{imageExtension}" ) ;
string moviePosterPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"Movie (2020)-poster.{imageExtension}" ) ;
MovieFolderScanner service = GetService (
new FakeFileEntry ( moviePath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( posterPath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( moviePosterPath ) { LastWriteTime = DateTime . Now }
) ;
var libraryPath = new LibraryPath
{ Id = 1 , Path = FakeRoot , LibraryFolders = new List < LibraryFolder > ( ) } ;
Either < BaseError , Unit > result = await service . ScanFolder (
libraryPath ,
FFmpegPath ,
FFprobePath ,
0 ,
1 ,
CancellationToken . None ) ;
result . IsRight . ShouldBeTrue ( ) ;
// Should prefer "poster.ext" over "MovieName-poster.ext"
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( posterPath , ArtworkKind . Poster ) ;
await _ imageCache . DidNotReceive ( ) . CopyArtworkToCache ( moviePosterPath , ArtworkKind . Poster ) ;
}
[Test]
public async Task NewMovie_Statistics_And_FallbackMetadata_FanArt_Priority (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]
string videoExtension ,
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.ImageFileExtensions))]
string imageExtension )
{
string moviePath = Path . Combine (
FakeRoot ,
Path . Combine ( "Movie (2020)" , $"Movie (2020){videoExtension}" ) ) ;
string fanArtPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"fanart.{imageExtension}" ) ;
string movieFanArtPath = Path . Combine (
Path . GetDirectoryName ( moviePath ) ? ? string . Empty ,
$"Movie (2020)-fanart.{imageExtension}" ) ;
MovieFolderScanner service = GetService (
new FakeFileEntry ( moviePath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( fanArtPath ) { LastWriteTime = DateTime . Now } ,
new FakeFileEntry ( movieFanArtPath ) { LastWriteTime = DateTime . Now }
) ;
var libraryPath = new LibraryPath
{ Id = 1 , Path = FakeRoot , LibraryFolders = new List < LibraryFolder > ( ) } ;
Either < BaseError , Unit > result = await service . ScanFolder (
libraryPath ,
FFmpegPath ,
FFprobePath ,
0 ,
1 ,
CancellationToken . None ) ;
result . IsRight . ShouldBeTrue ( ) ;
// Should prefer "fanart.ext" over "MovieName-fanart.ext"
await _ imageCache . Received ( 1 ) . CopyArtworkToCache ( fanArtPath , ArtworkKind . FanArt ) ;
await _ imageCache . DidNotReceive ( ) . CopyArtworkToCache ( movieFanArtPath , ArtworkKind . FanArt ) ;
}
[Test]
public async Task Should_Ignore_Extra_Files (
[ValueSource(typeof(LocalFolderScanner), nameof(LocalFolderScanner.VideoFileExtensions))]