mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-01-17 10:45:49 +02:00
Moved Episode Not Requested check to new Specification. Updated tests.
This commit is contained in:
parent
198ff059c4
commit
38b0fae29a
@ -239,11 +239,16 @@ public void should_only_include_reports_for_requested_episodes()
|
|||||||
Episodes = episodes.Where(v => v.SceneEpisodeNumber == p.EpisodeNumbers.First()).ToList()
|
Episodes = episodes.Where(v => v.SceneEpisodeNumber == p.EpisodeNumbers.First()).ToList()
|
||||||
});
|
});
|
||||||
|
|
||||||
Mocker.SetConstant<IEnumerable<IDecisionEngineSpecification>>(new List<IDecisionEngineSpecification>());
|
Mocker.SetConstant<IEnumerable<IDecisionEngineSpecification>>(new List<IDecisionEngineSpecification>
|
||||||
|
{
|
||||||
|
Mocker.Resolve<NzbDrone.Core.DecisionEngine.Specifications.Search.EpisodeRequestedSpecification>()
|
||||||
|
});
|
||||||
|
|
||||||
var decisions = Subject.GetSearchDecision(reports, criteria);
|
var decisions = Subject.GetSearchDecision(reports, criteria);
|
||||||
|
|
||||||
Assert.AreEqual(1, decisions.Count);
|
var approvedDecisions = decisions.Where(v => v.Approved).ToList();
|
||||||
|
|
||||||
|
approvedDecisions.Count.Should().Be(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using FluentAssertions;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
@ -26,12 +27,12 @@ public void SetUp()
|
|||||||
|
|
||||||
Mocker.GetMock<IIndexerFactory>()
|
Mocker.GetMock<IIndexerFactory>()
|
||||||
.Setup(s => s.GetAvailableProviders())
|
.Setup(s => s.GetAvailableProviders())
|
||||||
.Returns(new List<IIndexer>{indexer.Object});
|
.Returns(new List<IIndexer> { indexer.Object });
|
||||||
|
|
||||||
Mocker.GetMock<NzbDrone.Core.DecisionEngine.IMakeDownloadDecision>()
|
Mocker.GetMock<NzbDrone.Core.DecisionEngine.IMakeDownloadDecision>()
|
||||||
.Setup(s => s.GetSearchDecision(It.IsAny<List<Parser.Model.ReleaseInfo>>(), It.IsAny<SearchCriteriaBase>()))
|
.Setup(s => s.GetSearchDecision(It.IsAny<List<Parser.Model.ReleaseInfo>>(), It.IsAny<SearchCriteriaBase>()))
|
||||||
.Returns(new List<NzbDrone.Core.DecisionEngine.Specifications.DownloadDecision>());
|
.Returns(new List<NzbDrone.Core.DecisionEngine.Specifications.DownloadDecision>());
|
||||||
|
|
||||||
_xemSeries = Builder<Series>.CreateNew()
|
_xemSeries = Builder<Series>.CreateNew()
|
||||||
.With(v => v.UseSceneNumbering = true)
|
.With(v => v.UseSceneNumbering = true)
|
||||||
.Build();
|
.Build();
|
||||||
@ -81,12 +82,16 @@ private void WithEpisodes()
|
|||||||
WithEpisode(4, 2, 5, 14);
|
WithEpisode(4, 2, 5, 14);
|
||||||
WithEpisode(4, 3, 6, 11);
|
WithEpisode(4, 3, 6, 11);
|
||||||
WithEpisode(5, 1, 6, 12);
|
WithEpisode(5, 1, 6, 12);
|
||||||
|
|
||||||
|
// Season 7+ maps normally, so no mapping specified.
|
||||||
|
WithEpisode(7, 1, 0, 0);
|
||||||
|
WithEpisode(7, 2, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SearchCriteriaBase> WatchForSearchCriteria()
|
private List<SearchCriteriaBase> WatchForSearchCriteria()
|
||||||
{
|
{
|
||||||
List<SearchCriteriaBase> result = new List<SearchCriteriaBase>();
|
List<SearchCriteriaBase> result = new List<SearchCriteriaBase>();
|
||||||
|
|
||||||
Mocker.GetMock<IFetchFeedFromIndexers>()
|
Mocker.GetMock<IFetchFeedFromIndexers>()
|
||||||
.Setup(v => v.Fetch(It.IsAny<IIndexer>(), It.IsAny<SingleEpisodeSearchCriteria>()))
|
.Setup(v => v.Fetch(It.IsAny<IIndexer>(), It.IsAny<SingleEpisodeSearchCriteria>()))
|
||||||
.Callback<IIndexer, SingleEpisodeSearchCriteria>((i, s) => result.Add(s))
|
.Callback<IIndexer, SingleEpisodeSearchCriteria>((i, s) => result.Add(s))
|
||||||
@ -94,7 +99,7 @@ private List<SearchCriteriaBase> WatchForSearchCriteria()
|
|||||||
|
|
||||||
Mocker.GetMock<IFetchFeedFromIndexers>()
|
Mocker.GetMock<IFetchFeedFromIndexers>()
|
||||||
.Setup(v => v.Fetch(It.IsAny<IIndexer>(), It.IsAny<SeasonSearchCriteria>()))
|
.Setup(v => v.Fetch(It.IsAny<IIndexer>(), It.IsAny<SeasonSearchCriteria>()))
|
||||||
.Callback<IIndexer,SeasonSearchCriteria>((i,s) => result.Add(s))
|
.Callback<IIndexer, SeasonSearchCriteria>((i, s) => result.Add(s))
|
||||||
.Returns(new List<Parser.Model.ReleaseInfo>());
|
.Returns(new List<Parser.Model.ReleaseInfo>());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -111,9 +116,9 @@ public void scene_episodesearch()
|
|||||||
|
|
||||||
var criteria = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
||||||
|
|
||||||
Assert.AreEqual(1, criteria.Count);
|
criteria.Count.Should().Be(1);
|
||||||
Assert.AreEqual(2, criteria[0].SeasonNumber);
|
criteria[0].SeasonNumber.Should().Be(2);
|
||||||
Assert.AreEqual(3, criteria[0].EpisodeNumber);
|
criteria[0].EpisodeNumber.Should().Be(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -127,8 +132,8 @@ public void scene_seasonsearch()
|
|||||||
|
|
||||||
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
Assert.AreEqual(1, criteria.Count);
|
criteria.Count.Should().Be(1);
|
||||||
Assert.AreEqual(2, criteria[0].SeasonNumber);
|
criteria[0].SeasonNumber.Should().Be(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -142,9 +147,9 @@ public void scene_seasonsearch_should_search_multiple_seasons()
|
|||||||
|
|
||||||
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
Assert.AreEqual(2, criteria.Count);
|
criteria.Count.Should().Be(2);
|
||||||
Assert.AreEqual(3, criteria[0].SeasonNumber);
|
criteria[0].SeasonNumber.Should().Be(3);
|
||||||
Assert.AreEqual(4, criteria[1].SeasonNumber);
|
criteria[1].SeasonNumber.Should().Be(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -159,12 +164,27 @@ public void scene_seasonsearch_should_search_single_episode_if_possible()
|
|||||||
var criteria1 = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
var criteria1 = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
var criteria2 = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
var criteria2 = allCriteria.OfType<SingleEpisodeSearchCriteria>().ToList();
|
||||||
|
|
||||||
Assert.AreEqual(1, criteria1.Count);
|
criteria1.Count.Should().Be(1);
|
||||||
Assert.AreEqual(5, criteria1[0].SeasonNumber);
|
criteria1[0].SeasonNumber.Should().Be(5);
|
||||||
|
|
||||||
Assert.AreEqual(1, criteria2.Count);
|
criteria2.Count.Should().Be(1);
|
||||||
Assert.AreEqual(6, criteria2[0].SeasonNumber);
|
criteria2[0].SeasonNumber.Should().Be(6);
|
||||||
Assert.AreEqual(11, criteria2[0].EpisodeNumber);
|
criteria2[0].EpisodeNumber.Should().Be(11);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void scene_seasonsearch_should_use_seasonnumber_if_no_scene_number_is_available()
|
||||||
|
{
|
||||||
|
WithEpisodes();
|
||||||
|
|
||||||
|
var allCriteria = WatchForSearchCriteria();
|
||||||
|
|
||||||
|
Subject.SeasonSearch(_xemSeries.Id, 7);
|
||||||
|
|
||||||
|
var criteria = allCriteria.OfType<SeasonSearchCriteria>().ToList();
|
||||||
|
|
||||||
|
criteria.Count.Should().Be(1);
|
||||||
|
criteria[0].SeasonNumber.Should().Be(7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,17 +97,6 @@ private IEnumerable<DownloadDecision> GetDecisions(List<ReleaseInfo> reports, Se
|
|||||||
|
|
||||||
if (decision != null)
|
if (decision != null)
|
||||||
{
|
{
|
||||||
if (searchCriteria != null)
|
|
||||||
{
|
|
||||||
var criteriaEpisodes = searchCriteria.Episodes.Select(v => v.Id).ToList();
|
|
||||||
var remoteEpisodes = decision.RemoteEpisode.Episodes.Select(v => v.Id).ToList();
|
|
||||||
if (!criteriaEpisodes.Intersect(remoteEpisodes).Any())
|
|
||||||
{
|
|
||||||
_logger.Debug("Release rejected since the episode wasn't requested: {0}", decision.RemoteEpisode.ParsedEpisodeInfo);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (decision.Rejections.Any())
|
if (decision.Rejections.Any())
|
||||||
{
|
{
|
||||||
_logger.Debug("Release rejected for the following reasons: {0}", String.Join(", ", decision.Rejections));
|
_logger.Debug("Release rejected for the following reasons: {0}", String.Join(", ", decision.Rejections));
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Core.IndexerSearch.Definitions;
|
||||||
|
using NzbDrone.Core.Parser.Model;
|
||||||
|
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.DecisionEngine.Specifications.Search
|
||||||
|
{
|
||||||
|
public class EpisodeRequestedSpecification : IDecisionEngineSpecification
|
||||||
|
{
|
||||||
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
public EpisodeRequestedSpecification(Logger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string RejectionReason
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "Episode wasn't requested";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSatisfiedBy(RemoteEpisode remoteEpisode, SearchCriteriaBase searchCriteria)
|
||||||
|
{
|
||||||
|
if (searchCriteria == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var criteriaEpisodes = searchCriteria.Episodes.Select(v => v.Id).ToList();
|
||||||
|
var remoteEpisodes = remoteEpisode.Episodes.Select(v => v.Id).ToList();
|
||||||
|
if (!criteriaEpisodes.Intersect(remoteEpisodes).Any())
|
||||||
|
{
|
||||||
|
_logger.Debug("Release rejected since the episode wasn't requested: {0}", remoteEpisode.ParsedEpisodeInfo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -142,15 +142,25 @@ public List<DownloadDecision> SeasonSearch(int seriesId, int seasonNumber)
|
|||||||
|
|
||||||
if (series.UseSceneNumbering)
|
if (series.UseSceneNumbering)
|
||||||
{
|
{
|
||||||
var sceneSeasonGroups = episodes.GroupBy(v => v.SceneSeasonNumber).Distinct();
|
var sceneSeasonGroups = episodes.GroupBy(v =>
|
||||||
|
{
|
||||||
|
if (v.SceneSeasonNumber == 0 && v.SceneEpisodeNumber == 0)
|
||||||
|
return v.SeasonNumber;
|
||||||
|
else
|
||||||
|
return v.SceneSeasonNumber;
|
||||||
|
}).Distinct();
|
||||||
|
|
||||||
foreach (var sceneSeasonEpisodes in sceneSeasonGroups)
|
foreach (var sceneSeasonEpisodes in sceneSeasonGroups)
|
||||||
{
|
{
|
||||||
if (sceneSeasonEpisodes.Count() == 1)
|
if (sceneSeasonEpisodes.Count() == 1)
|
||||||
{
|
{
|
||||||
|
var episode = sceneSeasonEpisodes.First();
|
||||||
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, sceneSeasonEpisodes.ToList());
|
var searchSpec = Get<SingleEpisodeSearchCriteria>(series, sceneSeasonEpisodes.ToList());
|
||||||
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
searchSpec.SeasonNumber = sceneSeasonEpisodes.Key;
|
||||||
searchSpec.EpisodeNumber = sceneSeasonEpisodes.First().SceneEpisodeNumber;
|
if (episode.SceneSeasonNumber == 0 && episode.SceneEpisodeNumber == 0)
|
||||||
|
searchSpec.EpisodeNumber = episode.EpisodeNumber;
|
||||||
|
else
|
||||||
|
searchSpec.EpisodeNumber = episode.SceneEpisodeNumber;
|
||||||
|
|
||||||
var decisions = Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
var decisions = Dispatch(indexer => _feedFetcher.Fetch(indexer, searchSpec), searchSpec);
|
||||||
downloadDecisions.AddRange(decisions);
|
downloadDecisions.AddRange(decisions);
|
||||||
|
@ -217,6 +217,7 @@
|
|||||||
<Compile Include="DecisionEngine\Specifications\NotRestrictedReleaseSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\NotRestrictedReleaseSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\NotSampleSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\NotSampleSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\RssSync\ProperSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\RssSync\ProperSpecification.cs" />
|
||||||
|
<Compile Include="DecisionEngine\Specifications\Search\EpisodeRequestedSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\SeriesSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\SeriesSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\SeasonMatchSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\SeasonMatchSpecification.cs" />
|
||||||
<Compile Include="DecisionEngine\Specifications\Search\DailyEpisodeMatchSpecification.cs" />
|
<Compile Include="DecisionEngine\Specifications\Search\DailyEpisodeMatchSpecification.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user