From 35d43480bf9ba5e27ae0710e636163a6a9989d50 Mon Sep 17 00:00:00 2001 From: Qstick Date: Sun, 23 May 2021 23:14:56 -0400 Subject: [PATCH] Fixed: Errors in queue after Movie deleted Fixes #5899 Fixes RADARR-17A --- .../TrackedDownloadServiceFixture.cs | 120 ++++++++++++++++++ .../TrackedDownloadService.cs | 26 +++- 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs b/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs index 0f48f933e..95cad958e 100644 --- a/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs +++ b/src/NzbDrone.Core.Test/Download/TrackedDownloads/TrackedDownloadServiceFixture.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using FluentAssertions; using Moq; using NUnit.Framework; @@ -7,6 +8,7 @@ using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.History; using NzbDrone.Core.Indexers; using NzbDrone.Core.Movies; +using NzbDrone.Core.Movies.Events; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Test.Framework; @@ -83,5 +85,123 @@ namespace NzbDrone.Core.Test.Download.TrackedDownloads trackedDownload.RemoteMovie.Movie.Should().NotBeNull(); trackedDownload.RemoteMovie.Movie.Id.Should().Be(3); } + + [Test] + public void should_unmap_tracked_download_if_movie_deleted() + { + GivenDownloadHistory(); + + var remoteMovie = new RemoteMovie + { + Movie = new Movie() { Id = 3 }, + + ParsedMovieInfo = new ParsedMovieInfo() + { + MovieTitle = "A Movie", + Year = 1998 + } + }; + + Mocker.GetMock() + .Setup(s => s.Map(It.IsAny(), It.IsAny(), null)) + .Returns(new MappingResult { RemoteMovie = remoteMovie }); + + Mocker.GetMock() + .Setup(s => s.FindByDownloadId(It.IsAny())) + .Returns(new List()); + + ParseMovieTitle(); + + var client = new DownloadClientDefinition() + { + Id = 1, + Protocol = DownloadProtocol.Torrent + }; + + var item = new DownloadClientItem() + { + Title = "A Movie 1998", + DownloadId = "12345", + DownloadClientInfo = new DownloadClientItemClientInfo + { + Id = 1, + Type = "Blackhole", + Name = "Blackhole Client", + Protocol = DownloadProtocol.Torrent + } + }; + + Subject.TrackDownload(client, item); + Subject.GetTrackedDownloads().Should().HaveCount(1); + + Mocker.GetMock() + .Setup(s => s.Map(It.IsAny(), It.IsAny(), null)) + .Returns(new MappingResult { MappingResultType = MappingResultType.Unknown }); + + Subject.Handle(new MoviesDeletedEvent(new List { remoteMovie.Movie }, false, false)); + + var trackedDownloads = Subject.GetTrackedDownloads(); + trackedDownloads.Should().HaveCount(1); + trackedDownloads.First().RemoteMovie.Should().BeNull(); + } + + [Test] + public void should_not_throw_when_processing_deleted_movie() + { + GivenDownloadHistory(); + + var remoteMovie = new RemoteMovie + { + Movie = new Movie() { Id = 3 }, + + ParsedMovieInfo = new ParsedMovieInfo() + { + MovieTitle = "A Movie", + Year = 1998 + } + }; + + Mocker.GetMock() + .Setup(s => s.Map(It.IsAny(), It.IsAny(), null)) + .Returns(new MappingResult { MappingResultType = MappingResultType.Unknown }); + + Mocker.GetMock() + .Setup(s => s.FindByDownloadId(It.IsAny())) + .Returns(new List()); + + ParseMovieTitle(); + + var client = new DownloadClientDefinition() + { + Id = 1, + Protocol = DownloadProtocol.Torrent + }; + + var item = new DownloadClientItem() + { + Title = "A Movie 1998", + DownloadId = "12345", + DownloadClientInfo = new DownloadClientItemClientInfo + { + Id = 1, + Type = "Blackhole", + Name = "Blackhole Client", + Protocol = DownloadProtocol.Torrent + } + }; + + Subject.TrackDownload(client, item); + Subject.GetTrackedDownloads().Should().HaveCount(1); + + Mocker.GetMock() + .Setup(s => s.Map(It.IsAny(), It.IsAny(), null)) + .Returns(new MappingResult { MappingResultType = MappingResultType.Unknown }); + + Subject.Handle(new MoviesDeletedEvent(new List { remoteMovie.Movie }, false, false)); + + var trackedDownloads = Subject.GetTrackedDownloads(); + trackedDownloads.Should().HaveCount(1); + trackedDownloads.First().RemoteMovie.Should().BeNull(); + } } } diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs index 7222079f9..0ca7e2bd3 100644 --- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs +++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs @@ -9,6 +9,7 @@ using NzbDrone.Core.CustomFormats; using NzbDrone.Core.Download.History; using NzbDrone.Core.History; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Movies.Events; using NzbDrone.Core.Parser; namespace NzbDrone.Core.Download.TrackedDownloads @@ -23,7 +24,8 @@ namespace NzbDrone.Core.Download.TrackedDownloads void UpdateTrackable(List trackedDownloads); } - public class TrackedDownloadService : ITrackedDownloadService + public class TrackedDownloadService : ITrackedDownloadService, + IHandle { private readonly IParsingService _parsingService; private readonly IHistoryService _historyService; @@ -185,6 +187,13 @@ namespace NzbDrone.Core.Download.TrackedDownloads } } + private void UpdateCachedItem(TrackedDownload trackedDownload) + { + var parsedMovieInfo = Parser.Parser.ParseMovieTitle(trackedDownload.DownloadItem.Title); + + trackedDownload.RemoteMovie = parsedMovieInfo == null ? null : _parsingService.Map(parsedMovieInfo, "", null).RemoteMovie; + } + private static TrackedDownloadState GetStateFromHistory(DownloadHistoryEventType eventType) { switch (eventType) @@ -217,5 +226,20 @@ namespace NzbDrone.Core.Download.TrackedDownloads downloadItem.OutputPath); } } + + public void Handle(MoviesDeletedEvent message) + { + var cachedItems = _cache.Values.Where(t => + t.RemoteMovie?.Movie != null && + message.Movies.Any(m => m.Id == t.RemoteMovie.Movie.Id)) + .ToList(); + + if (cachedItems.Any()) + { + cachedItems.ForEach(UpdateCachedItem); + + _eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(GetTrackedDownloads())); + } + } } }