using System; using System.Collections.Generic; using System.Linq; using System.Text; using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Core.Download; using NzbDrone.Core.Qualities; using NzbDrone.Core.Tv; using NzbDrone.Core.Model; using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Providers; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Providers.Search; using NzbDrone.Core.Repository; using NzbDrone.Core.Repository.Search; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.ProviderTests.SearchTests { [TestFixture] public class ProcessResultsFixture : TestBase { private Series _matchingSeries; private Series _mismatchedSeries; private Series _nullSeries = null; private SearchHistory _searchHistory; private ProgressNotification _notification; private IList _episodes; [SetUp] public void Setup() { _matchingSeries = Builder.CreateNew() .With(s => s.Id = 79488) .With(s => s.Title = "30 Rock") .Build(); _mismatchedSeries = Builder.CreateNew() .With(s => s.Id = 12345) .With(s => s.Title = "Not 30 Rock") .Build(); _searchHistory = new SearchHistory(); _notification = new ProgressNotification("Test"); _episodes = Builder .CreateListOfSize(1) .Build(); Mocker.GetMock() .Setup(s => s.GetEpisodesByParseResult(It.IsAny())) .Returns(_episodes); } private void WithMatchingSeries() { Mocker.GetMock() .Setup(s => s.GetByTitle(It.IsAny())).Returns(_matchingSeries); } private void WithMisMatchedSeries() { Mocker.GetMock() .Setup(s => s.GetByTitle(It.IsAny())).Returns(_mismatchedSeries); } private void WithNullSeries() { Mocker.GetMock() .Setup(s => s.GetByTitle(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 should_process_higher_quality_results_first() { WithMatchingSeries(); WithSuccessfulDownload(); var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new QualityModel(Quality.DVD, true)) .With(c => c.Age = 10) .Random(1) .With(c => c.Quality = new QualityModel(Quality.Bluray1080p, true)) .With(c => c.Age = 100) .Build() .ToList(); Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.Is(d => d.Quality.Quality == Quality.Bluray1080p))) .Returns(ReportRejectionType.None); var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.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 should_process_newer_reports_first() { WithMatchingSeries(); WithSuccessfulDownload(); var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new QualityModel(Quality.Bluray1080p, true)) .With(c => c.Age = 300) .Build() .ToList(); parseResults[2].Age = 100; Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.IsAny())).Returns(ReportRejectionType.None); var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.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 should_check_other_reports_when_quality_is_not_wanted() { WithMatchingSeries(); WithQualityNotNeeded(); var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new QualityModel(Quality.DVD, true)) .Build() .ToList(); var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.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 should_should_skip_if_series_is_not_watched() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(e => e.Quality = new QualityModel(Quality.HDTV720p, false)) .Build() .ToList(); WithNullSeries(); //Act var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); //Assert result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void should_skip_if_series_does_not_match_searched_series() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(e => e.Quality = new QualityModel(Quality.HDTV720p, false)) .Build() .ToList(); WithMisMatchedSeries(); //Act var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); //Assert result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.Should().NotContain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Never()); } [Test] public void should_skip_if_episode_was_already_downloaded() { var parseResults = Builder.CreateListOfSize(2) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 5 }) .With(c => c.Quality = new QualityModel(Quality.DVD, true)) .TheLast(1) .With(e => e.EpisodeNumbers = new List { 1, 2, 3, 4, 5 }) .Build() .ToList(); WithMatchingSeries(); WithQualityNeeded(); WithSuccessfulDownload(); //Act var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); //Assert result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.Should().Contain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Once()); } [Test] public void should_try_next_report_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 QualityModel(Quality.DVD, true)) .TheLast(1) .With(c => c.Quality = new QualityModel(Quality.SDTV, true)) .Build() .ToList(); WithMatchingSeries(); WithQualityNeeded(); Mocker.GetMock() .Setup(s => s.DownloadReport(It.Is(d => d.Quality.Quality == Quality.DVD))) .Returns(false); Mocker.GetMock() .Setup(s => s.DownloadReport(It.Is(d => d.Quality.Quality == Quality.SDTV))) .Returns(true); //Act var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); //Assert result.SearchHistoryItems.Should().HaveCount(parseResults.Count); result.SearchHistoryItems.Should().Contain(s => s.Success); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Exactly(2)); } [Test] public void should_return_valid_successes_when_one_or_more_downloaded() { var parseResults = Builder.CreateListOfSize(5) .All() .With(e => e.SeasonNumber = 1) .With(e => e.EpisodeNumbers = new List { 1 }) .With(c => c.Quality = new QualityModel(Quality.DVD, true)) .With(c => c.Age = 10) .Random(1) .With(c => c.Quality = new QualityModel(Quality.Bluray1080p, true)) .With(c => c.Age = 100) .Build() .ToList(); WithMatchingSeries(); WithSuccessfulDownload(); Mocker.GetMock() .Setup(s => s.IsSatisfiedBy(It.Is(d => d.Quality.Quality == Quality.Bluray1080p))) .Returns(ReportRejectionType.None); //Act var result = Mocker.Resolve().ProcessReports(_matchingSeries, new { }, parseResults, _searchHistory, _notification); //Assert result.Successes.Should().NotBeNull(); result.Successes.Should().NotBeEmpty(); Mocker.GetMock().Verify(c => c.IsSatisfiedBy(It.IsAny()), Times.Once()); Mocker.GetMock().Verify(c => c.DownloadReport(It.IsAny()), Times.Once()); } } }