using System.Collections.Generic; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Core.Model; using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Providers; using NzbDrone.Core.Providers.DecisionEngine; using NzbDrone.Core.Repository; using NzbDrone.Core.Repository.Quality; using NzbDrone.Core.Repository.Search; using NzbDrone.Core.Test.Framework; namespace NzbDrone.Core.Test.ProviderTests.SearchProviderTests { [TestFixture] // ReSharper disable InconsistentNaming public class ProcessSearchResultsFixture : CoreTest { private Series _matchingSeries = null; private Series _mismatchedSeries = null; private Series _nullSeries = null; [SetUp] public void setup() { _matchingSeries = Builder.CreateNew() .With(s => s.SeriesId = 79488) .With(s => s.Title = "30 Rock") .Build(); _mismatchedSeries = Builder.CreateNew() .With(s => s.SeriesId = 12345) .With(s => s.Title = "Not 30 Rock") .Build(); } private void WithMatchingSeries() { Mocker.GetMock() .Setup(s => s.FindSeries(It.IsAny())).Returns(_matchingSeries); } private void WithMisMatchedSeries() { Mocker.GetMock() .Setup(s => s.FindSeries(It.IsAny())).Returns(_mismatchedSeries); } private void WithNullSeries() { Mocker.GetMock() .Setup(s => s.FindSeries(It.IsAny())).Returns(_nullSeries); } private void WithSuccessfulDownload() { Mocker.GetMock() .Setup(s => s.DownloadReport(It.IsAny())) .Returns(true); } private void WithFailingDownload() { Mocker.GetMock() .Setup(s => s.DownloadReport(It.IsAny())) .Returns(false); } private void WithQualityNeeded() { Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.IsAny())) .Returns(ReportRejectionType.None); } private void WithQualityNotNeeded() { Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.IsAny())) .Returns(ReportRejectionType.ExistingQualityIsEqualOrBetter); } [Test] public void processSearchResults_higher_quality_should_be_called_first() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new Quality(QualityTypes.DVD, true)) .With(c => c.Age = 10) .Random(1) .With(c => c.Quality = new Quality(QualityTypes.Bluray1080p, true)) .With(c => c.Age = 100) .Build(); WithMatchingSeries(); WithSuccessfulDownload(); Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.Is(d => d.Quality.QualityType == QualityTypes.Bluray1080p))) .Returns(ReportRejectionType.None); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().Contain(s => s.Success); Mocker.GetMock().Verify(c => c.IsSatisfiedBy(It.IsAny()), Times.Once()); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Once()); } [Test] public void processSearchResults_newer_report_should_be_called_first() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new Quality(QualityTypes.Bluray1080p, true)) .With(c => c.Age = 300) .Build(); parseResults[2].Age = 100; WithMatchingSeries(); WithSuccessfulDownload(); Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.IsAny())).Returns(ReportRejectionType.None); //Act var result = Mocker.Resolve().ProcessSearchResults(MockNotification, parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().Contain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.Is(d => d.Age != 100)), Times.Never()); Mocker.GetMock().Verify(c => c.DownloadReport(It.Is(d => d.Age == 100)), Times.Once()); } [Test] public void processSearchResults_when_quality_is_not_needed_should_check_the_rest() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new Quality(QualityTypes.DVD, true)) .Build(); WithMatchingSeries(); WithQualityNotNeeded(); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.IsSatisfiedBy(It.IsAny()), Times.Exactly(5)); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void processSearchResults_should_skip_if_series_is_null() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .Build(); WithNullSeries(); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void processSearchResults_should_skip_if_series_is_mismatched() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .Build(); WithMisMatchedSeries(); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void processSearchResults_should_skip_if_season_doesnt_match() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 2) .With(e => e.EpisodeNumbers = new List { 1 }) .Build(); WithMatchingSeries(); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void processSearchResults_should_skip_if_episodeNumber_doesnt_match() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 2 }) .Build(); WithMatchingSeries(); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void processSearchResults_should_skip_if_any_episodeNumber_was_already_added_to_download_queue() { var parseResults = Builder.CreateListOfSize(2) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 5 }) .With(c => c.Quality = new Quality(QualityTypes.DVD, true)) .TheLast(1) .With(e => e.EpisodeNumbers = new List { 1, 2, 3, 4, 5 }) .Build(); WithMatchingSeries(); WithQualityNeeded(); WithSuccessfulDownload(); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().Contain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Once()); } [Test] public void processSearchResults_should_try_next_if_download_fails() { var parseResults = Builder.CreateListOfSize(2) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new Quality(QualityTypes.DVD, true)) .TheLast(1) .With(c => c.Quality = new Quality(QualityTypes.SDTV, true)) .Build(); WithMatchingSeries(); WithQualityNeeded(); Mocker.GetMock() .Setup(s => s.DownloadReport(It.Is(d => d.Quality.QualityType == QualityTypes.DVD))) .Returns(false); Mocker.GetMock() .Setup(s => s.DownloadReport(It.Is(d => d.Quality.QualityType == QualityTypes.SDTV))) .Returns(true); //Act var result = Mocker.Resolve().ProcessSearchResults(new ProgressNotification("Test"), parseResults, new SearchHistory(), _matchingSeries, 1); //Assert result.Should().HaveCount(parseResults.Count); result.Should().Contain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Exactly(2)); } } }