Fix: When removing pending items from the queue remove all releases for that episode

This commit is contained in:
Keivan Beigi 2015-05-11 23:32:58 -07:00
parent 80403a4021
commit 724a3eee45
4 changed files with 140 additions and 14 deletions

View File

@ -55,7 +55,7 @@ namespace NzbDrone.Api.Queue
if (pendingRelease != null) if (pendingRelease != null)
{ {
_pendingReleaseService.RemovePendingQueueItem(id); _pendingReleaseService.RemovePendingQueueItems(pendingRelease.Id);
return new object().AsResponse(); return new object().AsResponse();
} }

View File

@ -0,0 +1,119 @@
using System.Collections.Generic;
using System.Linq;
using Moq;
using NUnit.Framework;
using NzbDrone.Core.Download.Pending;
using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test.Download.Pending.PendingReleaseServiceTests
{
[TestFixture]
public class RemovePendingFixture : CoreTest<PendingReleaseService>
{
private List<PendingRelease> _pending;
[SetUp]
public void Setup()
{
_pending = new List<PendingRelease>();
Mocker.GetMock<IPendingReleaseRepository>()
.Setup(s => s.AllBySeriesId(It.IsAny<int>()))
.Returns(_pending);
Mocker.GetMock<IPendingReleaseRepository>()
.Setup(s => s.Get(It.IsAny<int>()))
.Returns<int>(r => _pending.Single(c => c.Id == r));
}
private void AddPending(int id, int seasonNumber, int[] episodes)
{
_pending.Add(new PendingRelease
{
Id = id,
ParsedEpisodeInfo = new ParsedEpisodeInfo { SeasonNumber = seasonNumber, EpisodeNumbers = episodes }
});
}
[Test]
public void should_remove_same_release()
{
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 3 });
Subject.RemovePendingQueueItems(1);
AssertRemoved(1);
}
[Test]
public void should_remove_multiple_releases_release()
{
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 2 });
AddPending(id: 3, seasonNumber: 2, episodes: new[] { 3 });
AddPending(id: 4, seasonNumber: 2, episodes: new[] { 3 });
Subject.RemovePendingQueueItems(3);
AssertRemoved(3, 4);
}
[Test]
public void should_not_remove_diffrent_season()
{
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 3, seasonNumber: 3, episodes: new[] { 1 });
AddPending(id: 4, seasonNumber: 3, episodes: new[] { 1 });
Subject.RemovePendingQueueItems(1);
AssertRemoved(1, 2);
}
[Test]
public void should_not_remove_diffrent_episodes()
{
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 3, seasonNumber: 2, episodes: new[] { 2 });
AddPending(id: 4, seasonNumber: 2, episodes: new[] { 3 });
Subject.RemovePendingQueueItems(1);
AssertRemoved(1, 2);
}
[Test]
public void should_not_remove_multiepisodes()
{
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1, 2 });
Subject.RemovePendingQueueItems(1);
AssertRemoved(1);
}
[Test]
public void should_not_remove_singleepisodes()
{
AddPending(id: 1, seasonNumber: 2, episodes: new[] { 1 });
AddPending(id: 2, seasonNumber: 2, episodes: new[] { 1, 2 });
Subject.RemovePendingQueueItems(2);
AssertRemoved(2);
}
private void AssertRemoved(params int[] ids)
{
Mocker.GetMock<IPendingReleaseRepository>().Verify(c => c.DeleteMany(It.Is<IEnumerable<int>>(s => s.SequenceEqual(ids))));
}
}
}

View File

@ -166,6 +166,7 @@
<Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" /> <Compile Include="Download\DownloadClientTests\UTorrentTests\UTorrentFixture.cs" />
<Compile Include="Download\DownloadServiceFixture.cs" /> <Compile Include="Download\DownloadServiceFixture.cs" />
<Compile Include="Download\FailedDownloadServiceFixture.cs" /> <Compile Include="Download\FailedDownloadServiceFixture.cs" />
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemovePendingFixture.cs" />
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveRejectedFixture.cs" /> <Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveRejectedFixture.cs" />
<Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveGrabbedFixture.cs" /> <Compile Include="Download\Pending\PendingReleaseServiceTests\RemoveGrabbedFixture.cs" />
<Compile Include="Download\Pending\PendingReleaseServiceTests\AddFixture.cs" /> <Compile Include="Download\Pending\PendingReleaseServiceTests\AddFixture.cs" />

View File

@ -21,12 +21,12 @@ namespace NzbDrone.Core.Download.Pending
public interface IPendingReleaseService public interface IPendingReleaseService
{ {
void Add(DownloadDecision decision); void Add(DownloadDecision decision);
List<ReleaseInfo> GetPending(); List<ReleaseInfo> GetPending();
List<RemoteEpisode> GetPendingRemoteEpisodes(int seriesId); List<RemoteEpisode> GetPendingRemoteEpisodes(int seriesId);
List<Queue.Queue> GetPendingQueue(); List<Queue.Queue> GetPendingQueue();
Queue.Queue FindPendingQueueItem(int queueId); Queue.Queue FindPendingQueueItem(int queueId);
void RemovePendingQueueItem(int queueId); void RemovePendingQueueItems(int episodeId);
RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds); RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds);
} }
@ -63,7 +63,7 @@ namespace NzbDrone.Core.Download.Pending
_logger = logger; _logger = logger;
} }
public void Add(DownloadDecision decision) public void Add(DownloadDecision decision)
{ {
var alreadyPending = GetPendingReleases(); var alreadyPending = GetPendingReleases();
@ -74,7 +74,7 @@ namespace NzbDrone.Core.Download.Pending
.Intersect(episodeIds) .Intersect(episodeIds)
.Any()); .Any());
if (existingReports.Any(MatchingReleasePredicate(decision))) if (existingReports.Any(MatchingReleasePredicate(decision.RemoteEpisode.Release)))
{ {
_logger.Debug("This release is already pending, not adding again"); _logger.Debug("This release is already pending, not adding again");
return; return;
@ -152,11 +152,17 @@ namespace NzbDrone.Core.Download.Pending
return GetPendingQueue().SingleOrDefault(p => p.Id == queueId); return GetPendingQueue().SingleOrDefault(p => p.Id == queueId);
} }
public void RemovePendingQueueItem(int queueId) public void RemovePendingQueueItems(int queueId)
{ {
var id = FindPendingReleaseId(queueId); var targetItem = _repository.Get(queueId);
var seriesReleases = _repository.AllBySeriesId(targetItem.SeriesId);
_repository.Delete(id);
var releasesToRemove = seriesReleases.Where(
c => c.ParsedEpisodeInfo.SeasonNumber == targetItem.ParsedEpisodeInfo.SeasonNumber &&
c.ParsedEpisodeInfo.EpisodeNumbers.SequenceEqual(targetItem.ParsedEpisodeInfo.EpisodeNumbers));
_repository.DeleteMany(releasesToRemove.Select(c => c.Id));
} }
public RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds) public RemoteEpisode OldestPendingRelease(int seriesId, IEnumerable<int> episodeIds)
@ -223,11 +229,11 @@ namespace NzbDrone.Core.Download.Pending
_eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent()); _eventAggregator.PublishEvent(new PendingReleasesUpdatedEvent());
} }
private Func<PendingRelease, bool> MatchingReleasePredicate(DownloadDecision decision) private static Func<PendingRelease, bool> MatchingReleasePredicate(ReleaseInfo release)
{ {
return p => p.Title == decision.RemoteEpisode.Release.Title && return p => p.Title == release.Title &&
p.Release.PublishDate == decision.RemoteEpisode.Release.PublishDate && p.Release.PublishDate == release.PublishDate &&
p.Release.Indexer == decision.RemoteEpisode.Release.Indexer; p.Release.Indexer == release.Indexer;
} }
private int GetDelay(RemoteEpisode remoteEpisode) private int GetDelay(RemoteEpisode remoteEpisode)
@ -236,7 +242,7 @@ namespace NzbDrone.Core.Download.Pending
var delay = delayProfile.GetProtocolDelay(remoteEpisode.Release.DownloadProtocol); var delay = delayProfile.GetProtocolDelay(remoteEpisode.Release.DownloadProtocol);
var minimumAge = _configService.MinimumAge; var minimumAge = _configService.MinimumAge;
return new [] { delay, minimumAge }.Max(); return new[] { delay, minimumAge }.Max();
} }
private void RemoveGrabbed(RemoteEpisode remoteEpisode) private void RemoveGrabbed(RemoteEpisode remoteEpisode)
@ -278,7 +284,7 @@ namespace NzbDrone.Core.Download.Pending
foreach (var rejectedRelease in rejected) foreach (var rejectedRelease in rejected)
{ {
var matching = pending.SingleOrDefault(MatchingReleasePredicate(rejectedRelease)); var matching = pending.SingleOrDefault(MatchingReleasePredicate(rejectedRelease.RemoteEpisode.Release));
if (matching != null) if (matching != null)
{ {