Honor episode NFO season during metadata merge

Path-derived season numbers could win over explicit provider metadata during episode refresh, causing episodes to appear in the wrong season. Prefer provider-supplied season numbers in the provider merge phases without letting later backfill merges clobber them.
This commit is contained in:
itz4blitz 2026-04-25 18:38:07 -04:00
parent 461662f1ff
commit f9a7cd7457
No known key found for this signature in database
2 changed files with 120 additions and 0 deletions

View file

@ -0,0 +1,110 @@
using System;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Providers.Manager;
using MediaBrowser.Providers.TV;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Xunit;
namespace Jellyfin.Providers.Tests.TV;
public class EpisodeMetadataServiceTests
{
private readonly TestEpisodeMetadataService _service = new();
[Fact]
public void MergeData_ProviderSeasonOverridesPathDerivedSeason()
{
var source = new MetadataResult<Episode>
{
Item = new Episode
{
ParentIndexNumber = 2
}
};
var target = new MetadataResult<Episode>
{
Item = new Episode
{
ParentIndexNumber = 1
}
};
_service.Merge(source, target, replaceData: false, mergeMetadataSettings: true);
Assert.Equal(2, target.Item.ParentIndexNumber);
}
[Fact]
public void MergeData_BackfillExistingMetadata_DoesNotOverrideProviderSeason()
{
var existingMetadata = new MetadataResult<Episode>
{
Item = new Episode
{
ParentIndexNumber = 1
}
};
var temp = new MetadataResult<Episode>
{
Item = new Episode
{
ParentIndexNumber = 2
}
};
_service.Merge(existingMetadata, temp, replaceData: false, mergeMetadataSettings: false);
Assert.Equal(2, temp.Item.ParentIndexNumber);
}
[Fact]
public void MergeData_MissingProviderSeasonKeepsExistingSeason()
{
var source = new MetadataResult<Episode>
{
Item = new Episode()
};
var target = new MetadataResult<Episode>
{
Item = new Episode
{
ParentIndexNumber = 1
}
};
_service.Merge(source, target, replaceData: false, mergeMetadataSettings: true);
Assert.Equal(1, target.Item.ParentIndexNumber);
}
private sealed class TestEpisodeMetadataService : EpisodeMetadataService
{
public TestEpisodeMetadataService()
: base(
Mock.Of<IServerConfigurationManager>(),
NullLogger<EpisodeMetadataService>.Instance,
Mock.Of<IProviderManager>(),
Mock.Of<IFileSystem>(),
Mock.Of<ILibraryManager>(),
Mock.Of<IExternalDataManager>(),
Mock.Of<IItemRepository>())
{
}
public void Merge(MetadataResult<Episode> source, MetadataResult<Episode> target, bool replaceData, bool mergeMetadataSettings)
{
MergeData(source, target, Array.Empty<MetadataField>(), replaceData, mergeMetadataSettings);
}
}
}