fix: Regression caused reset_unmatched_scores: false to not be respected

pull/201/head
Robert Dailey 11 months ago
parent fd8a2f570b
commit d799da385e

@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Recyclarr will now continue if `git fetch` fails for any repos, so long as there is an existing,
valid clone to use.
### Fixed
- Address regression causing `reset_unmatched_scores: false` to not be respected.
## [5.0.0] - 2023-06-22
This release contains **BREAKING CHANGES**. See the [v5.0 Upgrade Guide][breaking5] for required

@ -32,7 +32,12 @@ public class QualityProfileApiPersistencePhase
private void LogQualityProfileUpdates(QualityProfileTransactionData transactions)
{
var updatedScores = transactions.UpdatedProfiles
.Select(x => (x.UpdatedProfile.Name, x.UpdatedScores))
.Select(x => (
ProfileName: x.UpdatedProfile.Name,
Scores: x.UpdatedScores
.Where(y => y.Reason != FormatScoreUpdateReason.New && y.Dto.Score != y.NewScore)
.ToList()))
.Where(x => x.Scores.Any())
.ToList();
if (updatedScores.Count > 0)
@ -50,7 +55,7 @@ public class QualityProfileApiPersistencePhase
_log.Information("Updated {ProfileCount} profiles and a total of {ScoreCount} scores",
transactions.UpdatedProfiles.Count,
updatedScores.Sum(s => s.UpdatedScores.Count));
updatedScores.Sum(s => s.Scores.Count));
}
else
{

@ -26,7 +26,7 @@ public class QualityProfilePreviewPhase
.AddColumn("[bold]New[/]")
.AddColumn("[bold]Reason[/]");
foreach (var updatedScore in updatedScores.Where(x => x.Reason != FormatScoreUpdateReason.NoChange))
foreach (var updatedScore in updatedScores.Where(x => x.Dto.Score != x.NewScore))
{
table.AddRow(
updatedScore.Dto.Name,

@ -71,28 +71,31 @@ public class QualityProfileTransactionPhase
.FullJoin(profileDto.FormatItems,
x => x.FormatId,
x => x.Format,
// Exists in config, but not in service (these are unusual and should be errors)
// See `FormatScoreUpdateReason` for reason why we need this (it's preview mode)
l => new UpdatedFormatScore
{
Dto = new ProfileFormatItemDto {Format = l.FormatId, Name = l.CfName},
NewScore = l.Score,
Reason = FormatScoreUpdateReason.New
},
// Exists in service, but not in config
r => new UpdatedFormatScore
{
Dto = r,
NewScore = 0,
NewScore = profileData.Profile.ResetUnmatchedScores ? 0 : r.Score,
Reason = FormatScoreUpdateReason.Reset
},
// Exists in both service and config
(l, r) => new UpdatedFormatScore
{
Dto = r,
NewScore = l.Score,
Reason = FormatScoreUpdateReason.Updated
})
.Select(x => x.Dto.Score == x.NewScore ? x with {Reason = FormatScoreUpdateReason.NoChange} : x)
.ToList();
return scoreMap.Any(x => x.Reason != FormatScoreUpdateReason.NoChange)
return scoreMap.Any(x => x.Dto.Score != x.NewScore)
? new UpdatedQualityProfile(profileDto) {UpdatedScores = scoreMap}
: null;
}

@ -4,11 +4,6 @@ namespace Recyclarr.Cli.Pipelines.QualityProfile;
public enum FormatScoreUpdateReason
{
/// <summary>
/// A score who's value did not change.
/// </summary>
NoChange,
/// <summary>
/// A score that is changed.
/// </summary>

@ -47,6 +47,6 @@ public record QualityDefinitionConfig
public record QualityProfileConfig
{
public bool? ResetUnmatchedScores { get; init; }
public bool ResetUnmatchedScores { get; init; }
public string Name { get; init; } = "";
}

@ -11,12 +11,12 @@ public static class NewQp
string profileName,
params (string TrashId, int FormatId, int Score)[] scores)
{
return Processed(profileName, null, scores);
return Processed(profileName, false, scores);
}
public static ProcessedQualityProfileData Processed(
string profileName,
bool? resetUnmatchedScores,
bool resetUnmatchedScores,
params (string TrashId, int FormatId, int Score)[] scores)
{
return Processed(profileName, resetUnmatchedScores,
@ -25,7 +25,7 @@ public static class NewQp
public static ProcessedQualityProfileData Processed(
string profileName,
bool? resetUnmatchedScores,
bool resetUnmatchedScores,
params (string CfName, string TrashId, int FormatId, int Score)[] scores)
{
return new ProcessedQualityProfileData(new QualityProfileConfig

@ -151,7 +151,7 @@ public class QualityProfileTransactionPhaseTest
}
[Test, AutoMockData]
public void Reset_scores(
public void Reset_scores_with_reset_unmatched_true(
QualityProfileTransactionPhase sut)
{
var guideData = new[]
@ -194,4 +194,48 @@ public class QualityProfileTransactionPhaseTest
NewQp.UpdatedScore("quality4", 0, 500, FormatScoreUpdateReason.New)
}, o => o.Excluding(x => x.Dto.Format));
}
[Test, AutoMockData]
public void Reset_scores_with_reset_unmatched_false(QualityProfileTransactionPhase sut)
{
var guideData = new[]
{
NewQp.Processed("profile1", false, ("quality3", "id3", 3, 100), ("quality4", "id4", 4, 500))
};
var serviceData = new[]
{
new QualityProfileDto
{
Name = "profile1",
FormatItems = new[]
{
new ProfileFormatItemDto
{
Name = "quality1",
Format = 1,
Score = 200
},
new ProfileFormatItemDto
{
Name = "quality2",
Format = 2,
Score = 300
}
}
}
};
var result = sut.Execute(guideData, serviceData);
result.UpdatedProfiles.Should()
.ContainSingle().Which.UpdatedScores.Should()
.BeEquivalentTo(new[]
{
NewQp.UpdatedScore("quality1", 200, 200, FormatScoreUpdateReason.Reset),
NewQp.UpdatedScore("quality2", 300, 300, FormatScoreUpdateReason.Reset),
NewQp.UpdatedScore("quality3", 0, 100, FormatScoreUpdateReason.New),
NewQp.UpdatedScore("quality4", 0, 500, FormatScoreUpdateReason.New)
}, o => o.Excluding(x => x.Dto.Format));
}
}

Loading…
Cancel
Save