diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/FullSeasonSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/FullSeasonSpecificationFixture.cs new file mode 100644 index 000000000..6a66d957d --- /dev/null +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/FullSeasonSpecificationFixture.cs @@ -0,0 +1,75 @@ + +using System; +using NUnit.Framework; +using NzbDrone.Core.DecisionEngine.Specifications; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; +using FizzWare.NBuilder; +using System.Linq; +using FluentAssertions; +using NzbDrone.Core.Tv; +using Moq; +using System.Collections.Generic; + +namespace NzbDrone.Core.Test.DecisionEngineTests +{ + [TestFixture] + public class FullSeasonSpecificationFixture : CoreTest + { + private RemoteEpisode _remoteEpisode; + + [SetUp] + public void Setup() + { + var show = Builder.CreateNew().With(s => s.Id = 1234).Build(); + _remoteEpisode = new RemoteEpisode + { + ParsedEpisodeInfo = new ParsedEpisodeInfo + { + FullSeason = true + }, + Episodes = Builder.CreateListOfSize(3) + .All() + .With(e => e.AirDateUtc = DateTime.UtcNow.AddDays(-8)) + .With(s => s.SeriesId = show.Id) + .BuildList(), + Series = show, + Release = new ReleaseInfo + { + Title = "Series.Title.S01.720p.BluRay.X264-RlsGrp" + } + }; + + Mocker.GetMock().Setup(s => s.EpisodesBetweenDates(It.IsAny(), It.IsAny(), false)) + .Returns(new List()); + } + + [Test] + public void should_return_true_if_is_not_a_full_season() + { + _remoteEpisode.ParsedEpisodeInfo.FullSeason = false; + _remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2); + Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_return_true_if_all_episodes_have_aired() + { + Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_return_false_if_one_episode_has_not_aired() + { + _remoteEpisode.Episodes.Last().AirDateUtc = DateTime.UtcNow.AddDays(+2); + Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); + } + + [Test] + public void should_return_false_if_an_episode_does_not_have_an_air_date() + { + _remoteEpisode.Episodes.Last().AirDateUtc = null; + Mocker.Resolve().IsSatisfiedBy(_remoteEpisode, null).Accepted.Should().BeFalse(); + } + } +} diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index a81548baa..42a3afe78 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -138,6 +138,7 @@ + diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/FullSeasonSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/FullSeasonSpecification.cs new file mode 100644 index 000000000..301e28077 --- /dev/null +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/FullSeasonSpecification.cs @@ -0,0 +1,40 @@ +using System; +using NLog; +using NzbDrone.Core.IndexerSearch.Definitions; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Common.Extensions; +using System.Linq; +using NzbDrone.Core.Tv; + +namespace NzbDrone.Core.DecisionEngine.Specifications +{ + public class FullSeasonSpecification : IDecisionEngineSpecification + { + private readonly Logger _logger; + private readonly IEpisodeService _episodeService; + + public FullSeasonSpecification(Logger logger, IEpisodeService episodeService) + { + _logger = logger; + _episodeService = episodeService; + } + + public RejectionType Type { get { return RejectionType.Permanent; } } + + public virtual Decision IsSatisfiedBy(RemoteEpisode subject, SearchCriteriaBase searchCriteria) + { + if (subject.ParsedEpisodeInfo.FullSeason) + { + _logger.Debug("Checking if all episodes in full season release have aired. {0}", subject.Release.Title); + + if (subject.Episodes.Any(e => !e.AirDateUtc.HasValue || e.AirDateUtc.Value.After(DateTime.UtcNow))) + { + _logger.Debug("Full season release {0} rejected. All episodes haven't aired yet.", subject.Release.Title); + return Decision.Reject("Full season release rejected. All episodes haven't aired yet."); + } + } + + return Decision.Accept(); + } + } +} diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index e564c5212..dc77e71a2 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -309,6 +309,7 @@ +