Compare commits

...

9 Commits

Author SHA1 Message Date
SenorSmartyPants ba753d9962
Merge 8f3a4ca3a6 into 5612cb8178 2024-04-25 09:15:44 -04:00
renovate[bot] 5612cb8178
chore(deps): update ci dependencies (#11427)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-25 07:15:31 -06:00
renovate[bot] ccd06bc547
chore(deps): update dependency diacritics to v3.3.29 (#11429)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-25 07:02:45 -06:00
Bond-009 d29b85a134
Fix multiple intro providers and remove unneeded ToLists (#11431) 2024-04-25 07:02:01 -06:00
SenorSmartyPants 8f3a4ca3a6 Convert Equals 1 to Single tests 2023-09-24 15:46:21 -05:00
SenorSmartyPants 48176f5d80 version[ABCD] test 2023-09-24 15:18:33 -05:00
SenorSmartyPants 09e5c3ba69 Code review: Count() -> Count and comments capitalization 2023-09-24 15:18:33 -05:00
SenorSmartyPants 9016fec892 Make sure episodes in series folder don't group as multiversion
Test for episodes in series folder


Turn on multiple versions for episodes


Support for multiversion episodes in mixed folders

Update 2 failing test cases. These were for passing for unofficially supported filenames. Dashes with no spaces, which is not how JF docs say multiversion files are supposed to be named.
Fix possible null


fix null take 2


Don't ParseName when calling ResolveVideos<Episode> 

ParseName drops everything after year in a filename. This results in episode information being dropped if year is present.

Update tests to set ParseName=false

Additional test with Mixed folder with Year in filename

Added case when calculating displayname for versions for mixed folders.
Add StringComparison.Ordinal to LastIndexOf

Was generating an error in recent build attempts.
Clean the episode filename to set the grouper value

This allows files like 
Name (2020) - S01E01 [BluRay-480p x264][AC3 2.0] - [ORIGINAL].mkv
Name (2020) - S01E01 [BluRay-1080p x264][AC3 5.1]- [Remaster].mkv

to be grouped on 'Name (2020) - S01E01'
Fix false positive merging

Only do cleanstring or " -" index cleaning, not both.
Compatiblity fix when stacking episodes and multiple versions are present


Fix linting problems
2023-09-24 15:17:41 -05:00
SenorSmartyPants 8677a17c3e Non greedy regex, parse the first year, not the last 2023-09-24 15:07:45 -05:00
16 changed files with 501 additions and 85 deletions

View File

@ -20,7 +20,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- name: Setup .NET
uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
with:

View File

@ -14,7 +14,7 @@ jobs:
permissions: read-all
steps:
- name: Checkout repository
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
@ -39,7 +39,7 @@ jobs:
permissions: read-all
steps:
- name: Checkout repository
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
ref: ${{ github.event.pull_request.head.sha }}
repository: ${{ github.event.pull_request.head.repo.full_name }}
@ -78,12 +78,12 @@ jobs:
- openapi-base
steps:
- name: Download openapi-head
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: openapi-head
path: openapi-head
- name: Download openapi-base
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: openapi-base
path: openapi-base
@ -152,7 +152,7 @@ jobs:
run: |-
echo "JELLYFIN_VERSION=$(date +'%Y%m%d%H%M%S')" >> $GITHUB_ENV
- name: Download openapi-head
uses: actions/download-artifact@9c19ed7fe5d278cd354c7dfd5d3b88589c7e2395 # v4.1.6
uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
with:
name: openapi-head
path: openapi-head

View File

@ -19,7 +19,7 @@ jobs:
runs-on: "${{ matrix.os }}"
steps:
- uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
- uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
- uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
with:

View File

@ -24,7 +24,7 @@ jobs:
reactions: '+1'
- name: Checkout the latest code
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0
@ -51,7 +51,7 @@ jobs:
reactions: eyes
- name: Checkout the latest code
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0
@ -128,7 +128,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: pull in script
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
repository: jellyfin/jellyfin-triage-script
- name: install python

View File

@ -10,7 +10,7 @@ jobs:
issues: write
steps:
- name: pull in script
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
repository: jellyfin/jellyfin-triage-script
- name: install python

View File

@ -33,7 +33,7 @@ jobs:
yq-version: v4.9.8
- name: Checkout Repository
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
ref: ${{ env.TAG_BRANCH }}
@ -66,7 +66,7 @@ jobs:
NEXT_VERSION: ${{ github.event.inputs.NEXT_VERSION }}
steps:
- name: Checkout Repository
uses: actions/checkout@1d96c772d19495a3b5c517cd2bc0cb401ea0529f # v4.1.3
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
with:
ref: ${{ env.TAG_BRANCH }}

View File

@ -13,7 +13,7 @@
<PackageVersion Include="BlurHashSharp" Version="1.3.2" />
<PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="coverlet.collector" Version="6.0.2" />
<PackageVersion Include="Diacritics" Version="3.3.27" />
<PackageVersion Include="Diacritics" Version="3.3.29" />
<PackageVersion Include="DiscUtils.Udf" Version="0.16.13" />
<PackageVersion Include="DotNet.Glob" Version="3.1.3" />
<PackageVersion Include="EFCoreSecondLevelCacheInterceptor" Version="4.4.3" />

View File

@ -146,8 +146,8 @@ namespace Emby.Naming.Common
CleanDateTimes = new[]
{
@"(.+[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19[0-9]{2}|20[0-9]{2})(?![0-9]+|\W[0-9]{2}\W[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*",
@"(.+[^_\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9]{2}|20[0-9]{2})(?![0-9]+|\W[0-9]{2}\W[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*"
@"(.+?[^_\,\.\(\)\[\]\-])[_\.\(\)\[\]\-](19[0-9]{2}|20[0-9]{2})(?![0-9]+|\W[0-9]{2}\W[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*",
@"(.+?[^_\,\.\(\)\[\]\-])[ _\.\(\)\[\]\-]+(19[0-9]{2}|20[0-9]{2})(?![0-9]+|\W[0-9]{2}\W[0-9]{2})([ _\,\.\(\)\[\]\-][^0-9]|).*(19[0-9]{2}|20[0-9]{2})*"
};
CleanStrings = new[]
@ -739,6 +739,12 @@ namespace Emby.Naming.Common
@"^\s*(?<name>[^ ].*?)\s*$"
};
VideoVersionExpressions = new[]
{
// Get filename before final space-dash-space
@"^(?<filename>.*?)(?:\s-\s(?!.*\s-\s)(.*))?$"
};
MultipleEpisodeExpressions = new[]
{
@".*(\\|\/)[sS]?(?<seasonnumber>[0-9]{1,4})[xX](?<epnumber>[0-9]{1,3})((-| - )[0-9]{1,4}[eExX](?<endingepnumber>[0-9]{1,3}))+[^\\\/]*$",
@ -864,6 +870,11 @@ namespace Emby.Naming.Common
/// </summary>
public string[] CleanStrings { get; set; }
/// <summary>
/// Gets or sets list of raw clean strings regular expressions strings.
/// </summary>
public string[] VideoVersionExpressions { get; set; }
/// <summary>
/// Gets or sets list of multi-episode regular expressions.
/// </summary>
@ -884,6 +895,11 @@ namespace Emby.Naming.Common
/// </summary>
public Regex[] CleanStringRegexes { get; private set; } = Array.Empty<Regex>();
/// <summary>
/// Gets list of video version regular expressions.
/// </summary>
public Regex[] VideoVersionRegexes { get; private set; } = Array.Empty<Regex>();
/// <summary>
/// Compiles raw regex strings into regexes.
/// </summary>
@ -891,6 +907,7 @@ namespace Emby.Naming.Common
{
CleanDateTimeRegexes = CleanDateTimes.Select(Compile).ToArray();
CleanStringRegexes = CleanStrings.Select(Compile).ToArray();
VideoVersionRegexes = VideoVersionExpressions.Select(Compile).ToArray();
}
private Regex Compile(string exp)

View File

@ -4,7 +4,9 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Emby.Naming.Common;
using Emby.Naming.TV;
using Jellyfin.Extensions;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
namespace Emby.Naming.Video
@ -25,10 +27,16 @@ namespace Emby.Naming.Video
/// </summary>
/// <param name="videoInfos">List of related video files.</param>
/// <param name="namingOptions">The naming options.</param>
/// <param name="collectionType">Collection type of videos being resolved.</param>
/// <param name="supportMultiVersion">Indication we should consider multi-versions of content.</param>
/// <param name="parseName">Whether to parse the name or use the filename.</param>
/// <returns>Returns enumerable of <see cref="VideoInfo"/> which groups files together when related.</returns>
public static IReadOnlyList<VideoInfo> Resolve(IReadOnlyList<VideoFileInfo> videoInfos, NamingOptions namingOptions, bool supportMultiVersion = true, bool parseName = true)
public static IReadOnlyList<VideoInfo> Resolve(
IReadOnlyList<VideoFileInfo> videoInfos,
NamingOptions namingOptions,
string collectionType,
bool supportMultiVersion = true,
bool parseName = true)
{
// Filter out all extras, otherwise they could cause stacks to not be resolved
// See the unit test TestStackedWithTrailer
@ -79,12 +87,19 @@ namespace Emby.Naming.Video
var info = new VideoInfo(media.Name) { Files = new[] { media } };
info.Year = info.Files[0].Year;
if (info.Year is null)
{
// Parse name for year info. Episodes don't get parsed up to this point for year info.
var info2 = VideoResolver.Resolve(media.Path, media.IsDirectory, namingOptions, parseName);
info.Year = info2?.Year;
}
list.Add(info);
}
if (supportMultiVersion)
{
list = GetVideosGroupedByVersion(list, namingOptions);
list = GetVideosGroupedByVersion(list, namingOptions, collectionType);
}
// Whatever files are left, just add them
@ -98,7 +113,7 @@ namespace Emby.Naming.Video
return list;
}
private static List<VideoInfo> GetVideosGroupedByVersion(List<VideoInfo> videos, NamingOptions namingOptions)
private static List<VideoInfo> GetVideosGroupedByVersion(List<VideoInfo> videos, NamingOptions namingOptions, string collectionType)
{
if (videos.Count == 0)
{
@ -112,6 +127,8 @@ namespace Emby.Naming.Video
return videos;
}
var mergeable = new List<VideoInfo>();
var notMergeable = new List<VideoInfo>();
// Cannot use Span inside local functions and delegates thus we cannot use LINQ here nor merge with the above [if]
VideoInfo? primary = null;
for (var i = 0; i < videos.Count; i++)
@ -122,9 +139,14 @@ namespace Emby.Naming.Video
continue;
}
if (!IsEligibleForMultiVersion(folderName, video.Files[0].FileNameWithoutExtension, namingOptions))
// Don't merge stacked episodes
if (video.Files.Count == 1 && IsEligibleForMultiVersion(folderName, video.Files[0].Path, namingOptions, collectionType))
{
return videos;
mergeable.Add(video);
}
else
{
notMergeable.Add(video);
}
if (folderName.Equals(video.Files[0].FileNameWithoutExtension, StringComparison.Ordinal))
@ -133,35 +155,59 @@ namespace Emby.Naming.Video
}
}
if (videos.Count > 1)
var list = new List<VideoInfo>();
if (collectionType.Equals(CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{
var groups = videos.GroupBy(x => ResolutionRegex().IsMatch(x.Files[0].FileNameWithoutExtension)).ToList();
videos.Clear();
var groupedList = mergeable.GroupBy(x => EpisodeGrouper(x.Files[0].Path, namingOptions, collectionType));
foreach (var grouping in groupedList)
{
list.Add(OrganizeAlternateVersions(grouping.ToList(), grouping.Key.AsSpan(), primary));
}
}
else if (mergeable.Count > 0)
{
list.Add(OrganizeAlternateVersions(mergeable, folderName, primary));
}
// Add non mergeables back in
list.AddRange(notMergeable);
list.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.Ordinal));
return list;
}
private static VideoInfo OrganizeAlternateVersions(List<VideoInfo> grouping, ReadOnlySpan<char> name, VideoInfo? primary)
{
VideoInfo? groupPrimary = null;
if (primary is not null && grouping.Contains(primary))
{
groupPrimary = primary;
}
var alternateVersions = new List<VideoInfo>();
if (grouping.Count > 1)
{
// groups resolution based into one, and all other names
var groups = grouping.GroupBy(x => ResolutionRegex().IsMatch(x.Files[0].FileNameWithoutExtension));
foreach (var group in groups)
{
if (group.Key)
{
videos.InsertRange(0, group.OrderByDescending(x => x.Files[0].FileNameWithoutExtension.ToString(), new AlphanumericComparator()));
alternateVersions.InsertRange(0, group.OrderByDescending(x => x.Files[0].FileNameWithoutExtension.ToString(), new AlphanumericComparator()));
}
else
{
videos.AddRange(group.OrderBy(x => x.Files[0].FileNameWithoutExtension.ToString(), new AlphanumericComparator()));
alternateVersions.AddRange(group.OrderBy(x => x.Files[0].FileNameWithoutExtension.ToString(), new AlphanumericComparator()));
}
}
}
primary ??= videos[0];
videos.Remove(primary);
groupPrimary ??= alternateVersions.FirstOrDefault() ?? grouping.First();
alternateVersions.Remove(groupPrimary);
groupPrimary.AlternateVersions = alternateVersions.Select(x => x.Files[0]).ToArray();
var list = new List<VideoInfo>
{
primary
};
list[0].AlternateVersions = videos.Select(x => x.Files[0]).ToArray();
list[0].Name = folderName.ToString();
return list;
groupPrimary.Name = name.ToString();
return groupPrimary;
}
private static bool HaveSameYear(IReadOnlyList<VideoInfo> videos)
@ -183,8 +229,16 @@ namespace Emby.Naming.Video
return true;
}
private static bool IsEligibleForMultiVersion(ReadOnlySpan<char> folderName, ReadOnlySpan<char> testFilename, NamingOptions namingOptions)
private static bool IsEligibleForMultiVersion(ReadOnlySpan<char> folderName, ReadOnlySpan<char> testFilePath, NamingOptions namingOptions, ReadOnlySpan<char> collectionType)
{
var testFilename = Path.GetFileNameWithoutExtension(testFilePath);
if (collectionType.Equals(CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{
// Episodes are always eligible to be grouped
return true;
}
if (!testFilename.StartsWith(folderName, StringComparison.OrdinalIgnoreCase))
{
return false;
@ -207,5 +261,41 @@ namespace Emby.Naming.Video
|| testFilename[0] == '-'
|| CheckMultiVersionRegex().IsMatch(testFilename);
}
private static string EpisodeGrouper(string testFilePath, NamingOptions namingOptions, ReadOnlySpan<char> collectionType)
{
// Grouper for tv shows/episodes should be everything before space-dash-space
var resolver = new EpisodeResolver(namingOptions);
EpisodeInfo? episodeInfo = resolver.Resolve(testFilePath, false);
ReadOnlySpan<char> seriesName = episodeInfo!.SeriesName;
var filename = Path.GetFileNameWithoutExtension(testFilePath);
// Start with grouping by filename
string g = filename;
for (var i = 0; i < namingOptions.VideoVersionRegexes.Length; i++)
{
var rule = namingOptions.VideoVersionRegexes[i];
var match = rule.Match(filename);
if (!match.Success)
{
continue;
}
g = match.Groups["filename"].Value;
// Clean the filename
if (VideoResolver.TryCleanString(g, namingOptions, out string newName))
{
g = newName;
}
// Never group episodes under series name
if (MemoryExtensions.Equals(g.AsSpan(), seriesName, StringComparison.OrdinalIgnoreCase))
{
g = filename;
}
}
return g;
}
}
}

View File

@ -44,7 +44,6 @@ using MediaBrowser.Model.Library;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Tasks;
using Microsoft.Extensions.Logging;
using TMDbLib.Objects.Authentication;
using Episode = MediaBrowser.Controller.Entities.TV.Episode;
using EpisodeInfo = Emby.Naming.TV.EpisodeInfo;
using Genre = MediaBrowser.Controller.Entities.Genre;
@ -1612,14 +1611,18 @@ namespace Emby.Server.Implementations.Library
/// <returns>IEnumerable{System.String}.</returns>
public async Task<IEnumerable<Video>> GetIntros(BaseItem item, User user)
{
if (IntroProviders.Length == 0)
{
return [];
}
var tasks = IntroProviders
.Take(1)
.Select(i => GetIntros(i, item, user));
var items = await Task.WhenAll(tasks).ConfigureAwait(false);
return items
.SelectMany(i => i.ToArray())
.SelectMany(i => i)
.Select(ResolveIntro)
.Where(i => i is not null)!; // null values got filtered out
}

View File

@ -274,7 +274,7 @@ namespace Emby.Server.Implementations.Library
var tasks = _providers.Select(i => GetDynamicMediaSources(item, i, cancellationToken));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
return results.SelectMany(i => i.ToList());
return results.SelectMany(i => i);
}
private async Task<IEnumerable<MediaSourceInfo>> GetDynamicMediaSources(BaseItem item, IMediaSourceProvider provider, CancellationToken cancellationToken)

View File

@ -228,7 +228,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
if (collectionType == CollectionType.tvshows)
{
return ResolveVideos<Episode>(parent, files, false, collectionType, true);
return ResolveVideos<Episode>(parent, files, true, collectionType, false);
}
return null;
@ -274,7 +274,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
.Where(f => f is not null)
.ToList();
var resolverResult = VideoListResolver.Resolve(videoInfos, NamingOptions, supportMultiEditions, parseName);
var resolverResult = VideoListResolver.Resolve(videoInfos, NamingOptions, collectionType, supportMultiEditions, parseName);
var result = new MultiItemResolverResult
{

View File

@ -1185,10 +1185,18 @@ namespace MediaBrowser.Controller.Entities
{
if (HasLocalAlternateVersions)
{
var displayName = System.IO.Path.GetFileNameWithoutExtension(path)
var fileName = System.IO.Path.GetFileNameWithoutExtension(path);
var displayName = fileName
.Replace(System.IO.Path.GetFileName(ContainingFolderPath), string.Empty, StringComparison.OrdinalIgnoreCase)
.TrimStart(new char[] { ' ', '-' });
if (fileName == displayName)
{
// File does not start with parent folder name. This must be an episode in a mixed directory
// Get string after last dash - this is the version name
displayName = fileName.Substring(fileName.LastIndexOf('-') + 1).TrimStart(new char[] { ' ', '-' });
}
if (!string.IsNullOrEmpty(displayName))
{
terms.Add(displayName);

View File

@ -286,7 +286,7 @@ namespace MediaBrowser.Providers.Manager
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
return results.SelectMany(i => i.ToList());
return results.SelectMany(i => i);
}
/// <summary>

View File

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Emby.Naming.Common;
using Emby.Naming.Video;
using MediaBrowser.Model.Entities;
using Xunit;
namespace Jellyfin.Naming.Tests.Video
@ -23,7 +25,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result.Where(v => v.ExtraType is null));
Assert.Single(result.Where(v => v.ExtraType is not null));
@ -42,7 +45,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result.Where(v => v.ExtraType is null));
Assert.Single(result.Where(v => v.ExtraType is not null));
@ -60,7 +64,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
Assert.Single(result[0].AlternateVersions);
@ -82,7 +87,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(7, result.Count);
Assert.Empty(result[0].AlternateVersions);
@ -105,7 +111,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
Assert.Equal(7, result[0].AlternateVersions.Count);
@ -129,7 +136,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(9, result.Count);
Assert.Empty(result[0].AlternateVersions);
@ -149,7 +157,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(5, result.Count);
Assert.Empty(result[0].AlternateVersions);
@ -171,7 +180,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(5, result.Count);
Assert.Empty(result[0].AlternateVersions);
@ -193,7 +203,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
Assert.Equal("/movies/Iron Man/Iron Man.mkv", result[0].Files[0].Path);
@ -222,7 +233,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
Assert.Equal("/movies/Iron Man/Iron Man.mkv", result[0].Files[0].Path);
@ -246,7 +258,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
}
@ -267,7 +280,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(7, result.Count);
Assert.Empty(result[0].AlternateVersions);
@ -289,7 +303,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(5, result.Count);
Assert.Empty(result[0].AlternateVersions);
@ -306,7 +321,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies);
Assert.Single(result);
Assert.Single(result[0].AlternateVersions);
@ -323,7 +339,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies);
Assert.Single(result);
Assert.Single(result[0].AlternateVersions);
@ -344,7 +361,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies);
Assert.Single(result);
Assert.Equal("/movies/X-Men Apocalypse (2016)/X-Men Apocalypse (2016).mkv", result[0].Files[0].Path);
@ -367,7 +385,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies);
Assert.Single(result);
Assert.Single(result[0].AlternateVersions);
@ -384,7 +403,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies);
Assert.Equal(2, result.Count);
}
@ -392,9 +412,186 @@ namespace Jellyfin.Naming.Tests.Video
[Fact]
public void TestEmptyList()
{
var result = VideoListResolver.Resolve(new List<VideoFileInfo>(), _namingOptions).ToList();
var result = VideoListResolver.Resolve(new List<VideoFileInfo>(), _namingOptions, string.Empty).ToList();
Assert.Empty(result);
}
[Fact]
public void TestMultiVersionEpisodeDontCollapse()
{
// Test for false positive
var files = new[]
{
@"/TV/Dexter/Dexter - S01E01 - One.mkv",
@"/TV/Dexter/Dexter - S01E02 - Two.mkv",
@"/TV/Dexter/Dexter - S01E03 - Three.mkv",
@"/TV/Dexter/Dexter - S01E04 - Four.mkv",
@"/TV/Dexter/Dexter - S01E05 - Five.mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Equal(5, result.Count);
Assert.Empty(result[0].AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisodeDontCollapse2()
{
// Test for false positive
var files = new[]
{
@"/TV/Dexter/Dexter - S01E01 One.mkv",
@"/TV/Dexter/Dexter - S01E02 Two.mkv",
@"/TV/Dexter/Dexter - S01E03 Three.mkv",
@"/TV/Dexter/Dexter - S01E04 Four.mkv",
@"/TV/Dexter/Dexter - S01E05 Five.mkv",
@"/TV/Star Trek- Picard/Season 3/Star Trek - Picard 3x01 [WEBDL-720p Proper x264][EAC3 5.1] - Part One - The Next Generation.mkv",
@"/TV/Star Trek- Picard/Season 3/Star Trek - Picard 3x02 [WEBDL-720p Proper x264][EAC3 5.1] - Part Two - Disengage.mkv",
@"/TV/Star Trek- Picard/Season 3/Star Trek - Picard 3x03 [WEBDL-720p x264][EAC3 5.1] - Part Three - Seventeen Seconds.mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Equal(8, result.Count);
Assert.Empty(result[0].AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisode()
{
var files = new[]
{
@"/TV/Dexter/Dexter - S01E01/Dexter - S01E01 - One.mkv",
@"/TV/Dexter/Dexter - S01E01/Dexter - S01E01 - Two.mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Single(result);
Assert.Single(result[0].AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisodeMixedSeriesFolder()
{
var files = new[]
{
@"/TV/Dexter/Dexter - S01E01.mkv",
@"/TV/Dexter/Dexter - S01E01 - Unaired.mkv",
@"/TV/Dexter/Dexter - S01E02 - Two.mkv",
@"/TV/Dexter/Dexter - S01E03 - Three.mkv",
@"/TV/Dexter/Dexter S02E01 - Ia.mkv",
@"/TV/Dexter/Dexter S02E01 - I.mkv",
@"/TV/Dexter/Dexter - S02E02.mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Equal(5, result.Count);
Assert.Single(result[0].AlternateVersions);
Assert.Empty(result[1].AlternateVersions);
Assert.Empty(result[2].AlternateVersions);
Assert.Empty(result[3].AlternateVersions);
var s02e01 = result.FirstOrDefault(x => string.Equals(x.Name, "Dexter S02E01", StringComparison.Ordinal));
Assert.NotNull(s02e01);
Assert.Single(s02e01!.AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisodeMixedSeasonFolder()
{
var files = new[]
{
@"/TV/Dexter/Season 2/Dexter - S02E01 - Ia.mkv",
@"/TV/Dexter/Season 2/Dexter - S02E01 - I.mkv",
@"/TV/Dexter/Season 2/Dexter - S02E02.mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Equal(2, result.Count);
Assert.Single(result[0].AlternateVersions);
Assert.Empty(result[1].AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisodeMixedSeasonFolderWithYear()
{
var files = new[]
{
@"/TV/Name (2020)/Season 1/Name (2020) - S01E01 - [ORIGINAL].mkv",
@"/TV/Name (2020)/Season 1/Name (2020) - S01E01 - [VERSION].mkv",
@"/TV/Name (2020)/Season 1/Name (2020) - S01E02 - [ORIGINAL].mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Equal(2, result.Count);
Assert.Single(result[0].AlternateVersions);
Assert.Empty(result[1].AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisodeMixedSeasonFolderWithYearAndDirtyNames()
{
var files = new[]
{
@"/TV/Name (2020)/Season 1/Name (2020) - S01E01 [BluRay-480p x264][AC3 2.0] - [ORIGINAL].mkv",
@"/TV/Name (2020)/Season 1/Name (2020) - S01E01 [BluRay-1080p x264][AC3 5.1] - [Remaster].mkv",
@"/TV/Name (2020)/Season 1/Name (2020) - S01E02 - [ORIGINAL].mkv",
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Equal(2, result.Count);
Assert.Single(result[0].AlternateVersions);
Assert.Empty(result[1].AlternateVersions);
}
[Fact]
public void TestMultiVersionEpisodeABCD()
{
var files = new[]
{
@"/TV/SeriesName/SeriesName- S01E01 - EpisodeTitle - [VersionA].mkv",
@"/TV/SeriesName/SeriesName- S01E01 - EpisodeTitle - [VersionB].mkv",
@"/TV/SeriesName/SeriesName- S01E01 - EpisodeTitle - VersionC.mkv",
@"/TV/SeriesName/SeriesName- S01E01 - EpisodeTitle - VersionD.mkv"
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows);
Assert.Single(result);
Assert.Equal(3, result[0].AlternateVersions.Count);
}
}
}

View File

@ -42,7 +42,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(11, result.Count);
var batman = result.FirstOrDefault(x => string.Equals(x.Name, "Batman", StringComparison.Ordinal));
@ -65,6 +66,87 @@ namespace Jellyfin.Naming.Tests.Video
Assert.Equal(ExtraType.Trailer, result[10].ExtraType);
}
[Fact]
public void TestTVStackAndVersions()
{
var files = new[]
{
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) - s01e01 CD1.avi",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) - s01e01 CD2.avi",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) - s01e02 - The First Cut is the Deepest.avi",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) - s01e03.mp4",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) - s01e04 - Aired Version.mp4",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) - s01e04 - Uncensored Version.mp4"
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows).ToList();
Assert.Equal(4, result.Count);
var s01e01 = result.FirstOrDefault(x => string.Equals(x.Name, "Grey's Anatomy (2005) - s01e01", StringComparison.Ordinal));
Assert.NotNull(s01e01);
Assert.Equal(2, s01e01!.Files.Count);
var s01e04 = result.FirstOrDefault(x => string.Equals(x.Name, "Grey's Anatomy (2005) - s01e04", StringComparison.Ordinal));
Assert.NotNull(s01e04);
Assert.Single(s01e04!.AlternateVersions);
}
[Fact]
public void TestTVStackAndVersionsNoFirstDash()
{
var files = new[]
{
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) s01e01 - pt1.avi",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) s01e01 - pt2.avi",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) s01e02 - The First Cut is the Deepest.avi",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) s01e03.mp4",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) s01e04 - Aired Version.mp4",
@"/TV/Grey's Anatomy (2005)/Grey's Anatomy (2005) s01e04 - Uncensored Version.mp4"
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows).ToList();
Assert.Equal(4, result.Count);
var s01e01 = result.FirstOrDefault(x => string.Equals(x.Name, "Grey's Anatomy (2005) s01e01", StringComparison.Ordinal));
Assert.NotNull(s01e01);
Assert.Equal(2, s01e01!.Files.Count);
var s01e04 = result.FirstOrDefault(x => string.Equals(x.Name, "Grey's Anatomy (2005) s01e04", StringComparison.Ordinal));
Assert.NotNull(s01e04);
Assert.Single(s01e04!.AlternateVersions);
}
[Fact]
public void TestTVStack()
{
var files = new[]
{
@"/TV/Doctor Who/Season 21/Doctor Who 21x11 - Resurrection of the Daleks - Part 1.mkv",
@"/TV/Doctor Who/Season 21/Doctor Who 21x11 - Resurrection of the Daleks - Part 2.mkv",
@"/TV/Doctor Who/Season 21/Doctor Who 21x12 - Resurrection of the Daleks - Part 3.mkv",
@"/TV/Doctor Who/Season 21/Doctor Who 21x12 - Resurrection of the Daleks - Part 4.mkv"
};
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions, false)).OfType<VideoFileInfo>().ToList(),
_namingOptions,
CollectionType.TvShows).ToList();
Assert.Equal(2, result.Count);
var s21e12 = result.FirstOrDefault(x => string.Equals(x.Name, "Doctor Who 21x12 - Resurrection of the Daleks", StringComparison.Ordinal));
Assert.NotNull(s21e12);
Assert.Equal(2, s21e12!.Files.Count);
}
[Fact]
public void TestWithMetadata()
{
@ -76,7 +158,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
}
@ -92,7 +175,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -110,7 +194,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -129,7 +214,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(3, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -149,7 +235,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(3, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -168,7 +255,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -190,7 +278,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
string.Empty).ToList();
Assert.Equal(5, result.Count);
}
@ -206,7 +295,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, true, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
}
@ -223,7 +313,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, true, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
}
@ -241,7 +332,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(3, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -262,7 +354,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(4, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -284,7 +377,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
string.Empty).ToList();
Assert.Equal(2, result.Count);
}
@ -299,7 +393,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
}
@ -314,7 +409,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Single(result);
}
@ -330,7 +426,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
// The result should contain two individual movies
// Version grouping should not work here, because the files are not in a directory with the name 'Four Sisters and a Wedding'
@ -348,7 +445,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
}
@ -364,7 +462,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -382,7 +481,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
Assert.False(result[0].ExtraType.HasValue);
@ -400,7 +500,8 @@ namespace Jellyfin.Naming.Tests.Video
var result = VideoListResolver.Resolve(
files.Select(i => VideoResolver.Resolve(i, false, _namingOptions)).OfType<VideoFileInfo>().ToList(),
_namingOptions).ToList();
_namingOptions,
CollectionType.Movies).ToList();
Assert.Equal(2, result.Count);
Assert.False(result[0].ExtraType.HasValue);