1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-25 22:46:31 -04:00

New: Check whether an existing episode file was deleted before grabbing an upgrade, to avoid timing issues in combination with Ignore Deleted Episodes.

This commit is contained in:
Taloth Saldono
2017-03-11 19:49:32 +01:00
parent 413ce1d9a7
commit fa006d85fd
34 changed files with 302 additions and 17 deletions
@@ -28,6 +28,8 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
private Mock<IDecisionEngineSpecification> _fail2;
private Mock<IDecisionEngineSpecification> _fail3;
private Mock<IDecisionEngineSpecification> _failDelayed1;
[SetUp]
public void Setup()
{
@@ -39,14 +41,19 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_fail2 = new Mock<IDecisionEngineSpecification>();
_fail3 = new Mock<IDecisionEngineSpecification>();
_failDelayed1 = new Mock<IDecisionEngineSpecification>();
_pass1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Accept);
_pass2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Accept);
_pass3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Accept);
_fail1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("fail1"));
_fail2.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("fail2"));
_fail3.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("fail3"));
_failDelayed1.Setup(c => c.IsSatisfiedBy(It.IsAny<RemoteEpisode>(), null)).Returns(Decision.Reject("failDelayed1"));
_failDelayed1.SetupGet(c => c.Priority).Returns(SpecificationPriority.Disk);
_reports = new List<ReleaseInfo> { new ReleaseInfo { Title = "The.Office.S03E115.DVDRip.XviD-OSiTV" } };
_remoteEpisode = new RemoteEpisode {
Series = new Series(),
@@ -78,6 +85,25 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
_pass3.Verify(c => c.IsSatisfiedBy(_remoteEpisode, null), Times.Once());
}
[Test]
public void should_call_delayed_specifications_if_non_delayed_passed()
{
GivenSpecifications(_pass1, _failDelayed1);
Subject.GetRssDecision(_reports).ToList();
_failDelayed1.Verify(c => c.IsSatisfiedBy(_remoteEpisode, null), Times.Once());
}
[Test]
public void should_not_call_delayed_specifications_if_non_delayed_failed()
{
GivenSpecifications(_fail1, _failDelayed1);
Subject.GetRssDecision(_reports).ToList();
_failDelayed1.Verify(c => c.IsSatisfiedBy(_remoteEpisode, null), Times.Never());
}
[Test]
public void should_return_rejected_if_single_specs_fail()
{
@@ -214,10 +240,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
var criteria = new SeasonSearchCriteria { Episodes = episodes.Take(1).ToList(), SeasonNumber = 1 };
var reports = episodes.Select(v =>
new ReleaseInfo()
{
Title = string.Format("{0}.S{1:00}E{2:00}.720p.WEB-DL-DRONE", series.Title, v.SceneSeasonNumber, v.SceneEpisodeNumber)
var reports = episodes.Select(v =>
new ReleaseInfo()
{
Title = string.Format("{0}.S{1:00}E{2:00}.720p.WEB-DL-DRONE", series.Title, v.SceneSeasonNumber, v.SceneEpisodeNumber)
}).ToList();
Mocker.GetMock<IParsingService>()
@@ -289,4 +315,4 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
ExceptionVerification.ExpectedErrors(1);
}
}
}
}
@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.DecisionEngine.Specifications.RssSync;
using NzbDrone.Core.IndexerSearch.Definitions;
using NzbDrone.Core.MediaFiles;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Profiles;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv;
using NzbDrone.Core.DecisionEngine;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Common.Disk;
using Moq;
using NzbDrone.Test.Common;
using System.IO;
namespace NzbDrone.Core.Test.DecisionEngineTests.RssSync
{
[TestFixture]
public class DeletedEpisodeFileSpecificationFixture : CoreTest<DeletedEpisodeFileSpecification>
{
private RemoteEpisode _parseResultMulti;
private RemoteEpisode _parseResultSingle;
private EpisodeFile _firstFile;
private EpisodeFile _secondFile;
[SetUp]
public void Setup()
{
_firstFile = new EpisodeFile
{
Id = 1,
RelativePath = "My.Series.S01E01.mkv",
Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 1)),
DateAdded = DateTime.Now
};
_secondFile = new EpisodeFile
{
Id = 2,
RelativePath = "My.Series.S01E02.mkv",
Quality = new QualityModel(Quality.Bluray1080p, new Revision(version: 1)),
DateAdded = DateTime.Now
};
var singleEpisodeList = new List<Episode> { new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 } };
var doubleEpisodeList = new List<Episode> {
new Episode { EpisodeFile = _firstFile, EpisodeFileId = 1 },
new Episode { EpisodeFile = _secondFile, EpisodeFileId = 2 }
};
var fakeSeries = Builder<Series>.CreateNew()
.With(c => c.Profile = new Profile { Cutoff = Quality.Bluray1080p })
.With(c => c.Path = @"C:\Series\My.Series".AsOsAgnostic())
.Build();
_parseResultMulti = new RemoteEpisode
{
Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.DVD, new Revision(version: 2)) },
Episodes = doubleEpisodeList
};
_parseResultSingle = new RemoteEpisode
{
Series = fakeSeries,
ParsedEpisodeInfo = new ParsedEpisodeInfo { Quality = new QualityModel(Quality.DVD, new Revision(version: 2)) },
Episodes = singleEpisodeList
};
GivenUnmonitorDeletedEpisodes(true);
}
private void GivenUnmonitorDeletedEpisodes(bool enabled)
{
Mocker.GetMock<IConfigService>()
.SetupGet(v => v.AutoUnmonitorPreviouslyDownloadedEpisodes)
.Returns(enabled);
}
private void WithExistingFile(EpisodeFile episodeFile)
{
var path = Path.Combine(@"C:\Series\My.Series".AsOsAgnostic(), episodeFile.RelativePath);
Mocker.GetMock<IDiskProvider>()
.Setup(v => v.FileExists(path))
.Returns(true);
}
[Test]
public void should_return_true_when_unmonitor_deleted_episdes_is_off()
{
GivenUnmonitorDeletedEpisodes(false);
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_when_searching()
{
Subject.IsSatisfiedBy(_parseResultSingle, new SeasonSearchCriteria()).Accepted.Should().BeTrue();
}
[Test]
public void should_return_true_if_file_exists()
{
WithExistingFile(_firstFile);
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_if_file_is_missing()
{
Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse();
}
[Test]
public void should_return_true_if_both_of_multiple_episode_exist()
{
WithExistingFile(_firstFile);
WithExistingFile(_secondFile);
Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeTrue();
}
[Test]
public void should_return_false_if_one_of_multiple_episode_is_missing()
{
WithExistingFile(_firstFile);
Subject.IsSatisfiedBy(_parseResultMulti, null).Accepted.Should().BeFalse();
}
}
}