using System.Collections.Generic; using System.Linq; using FizzWare.NBuilder; using FluentAssertions; using Moq; using NUnit.Framework; using NzbDrone.Core.Configuration; using NzbDrone.Core.Jobs.Implementations; using NzbDrone.Core.Tv; using NzbDrone.Core.Jobs; using NzbDrone.Core.Model; using NzbDrone.Core.Model.Notification; using NzbDrone.Core.Providers; using NzbDrone.Core.Test.Framework; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.JobTests { [TestFixture] public class BacklogSearchJobTest : CoreTest { private void WithEnableBacklogSearching() { Mocker.GetMock().SetupGet(s => s.EnableBacklogSearching).Returns(true); } [Test] public void no_missing_epsiodes_should_not_trigger_any_search() { var notification = new ProgressNotification("Backlog Search Job Test"); var episodes = new List(); WithStrictMocker(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); Subject.Start(notification, null); Mocker.GetMock().Verify(c => c.Start(notification, new { SeriesId = It.IsAny(), SeasonNumber = It.IsAny() }), Times.Never()); Mocker.GetMock().Verify(c => c.Start(notification, new { SeriesId = It.IsAny(), SeasonNumber = 0 }), Times.Never()); } [Test] public void individual_missing_episode() { var notification = new ProgressNotification("Backlog Search Job Test"); var series = Builder.CreateNew() .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var episodes = Builder.CreateListOfSize(1) .All() .With(e => e.Series = series) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); Mocker.GetMock() .Setup(s => s.Start(notification, It.Is(d => d.GetPropertyValue("EpisodeId") == 1))); Subject.Start(notification, null); Mocker.GetMock().Verify(c => c.Start(notification, It.Is(d => d.GetPropertyValue("EpisodeId") >= 0)), Times.Once()); } [Test] public void individual_missing_episodes_only() { var notification = new ProgressNotification("Backlog Search Job Test"); var series = Builder.CreateNew() .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var episodes = Builder.CreateListOfSize(5) .All() .With(e => e.Series = series) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); Subject.Start(notification, null); Mocker.GetMock().Verify(c => c.Start(notification, It.Is(d => d.GetPropertyValue("EpisodeId") >= 0)), Times.Exactly(episodes.Count)); } [Test] public void series_season_missing_episodes_only_mismatch_count() { var notification = new ProgressNotification("Backlog Search Job Test"); var series = Builder.CreateNew() .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var episodes = Builder.CreateListOfSize(5) .All() .With(e => e.Series = series) .With(e => e.SeasonNumber = 1) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); Mocker.GetMock() .Setup(s => s.GetEpisodeNumbersBySeason(1, 1)).Returns(new List { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); Subject.Start(notification, null); Mocker.GetMock().Verify(c => c.Start(notification, It.Is(d => d.GetPropertyValue("EpisodeId") >= 0)), Times.Exactly(episodes.Count)); } [Test] public void series_season_missing_episodes_only() { var notification = new ProgressNotification("Backlog Search Job Test"); var series = Builder.CreateNew() .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var episodes = Builder.CreateListOfSize(5) .All() .With(e => e.Series = series) .With(e => e.SeriesId = series.Id) .With(e => e.SeasonNumber = 1) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); Mocker.GetMock() .Setup(s => s.GetEpisodeNumbersBySeason(1, 1)).Returns(episodes.Select(e => e.EpisodeNumber).ToList()); Subject.Start(notification, null); Mocker.GetMock().Verify(c => c.Start(notification, It.Is(d => d.GetPropertyValue("SeriesId") >= 0 && d.GetPropertyValue("SeasonNumber") >= 0)), Times.Once()); } [Test] public void multiple_missing_episodes() { var notification = new ProgressNotification("Backlog Search Job Test"); var series = Builder.CreateNew() .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var series2 = Builder.CreateNew() .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var episodes = Builder.CreateListOfSize(10) .TheFirst(5) .With(e => e.Series = series) .With(e => e.SeriesId = series.Id) .With(e => e.SeasonNumber = 1) .TheNext(5) .With(e => e.Series = series2) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); Mocker.GetMock() .Setup(s => s.GetEpisodeNumbersBySeason(1, 1)).Returns(new List { 1, 2, 3, 4, 5 }); Subject.Start(notification, null); Mocker.GetMock().Verify(c => c.Start(notification, It.Is(d => d.GetPropertyValue("SeriesId") >= 0 && d.GetPropertyValue("SeasonNumber") >= 0)), Times.Once()); Mocker.GetMock().Verify(c => c.Start(notification, It.Is(d => d.GetPropertyValue("EpisodeId") >= 0)), Times.Exactly(5)); } [Test] public void GetMissingForEnabledSeries_should_only_return_episodes_for_monitored_series() { var series = Builder.CreateListOfSize(2) .TheFirst(1) .With(s => s.Monitored = false) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .TheNext(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .Build(); var episodes = Builder.CreateListOfSize(11) .TheFirst(5) .With(e => e.Series = series[0]) .With(e => e.SeasonNumber = 1) .TheLast(6) .With(e => e.Series = series[1]) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); var result = Subject.GetMissingForEnabledSeries(); result.Should().NotBeEmpty(); result.Should().Contain(s => s.Series.Monitored); result.Should().NotContain(s => !s.Series.Monitored); } [Test] public void GetMissingForEnabledSeries_should_only_return_explicity_enabled_series_when_backlog_searching_is_ignored() { var series = Builder.CreateListOfSize(3) .TheFirst(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Disable) .TheNext(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .TheNext(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Inherit) .Build(); var episodes = Builder.CreateListOfSize(12) .TheFirst(3) .With(e => e.Series = series[0]) .TheNext(4) .With(e => e.Series = series[1]) .TheNext(5) .With(e => e.Series = series[2]) .Build().ToList(); //WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); var result = Subject.GetMissingForEnabledSeries(); result.Should().NotBeEmpty(); result.Should().Contain(s => s.Series.BacklogSetting == BacklogSettingType.Enable); result.Should().NotContain(s => s.Series.BacklogSetting == BacklogSettingType.Disable); result.Should().NotContain(s => s.Series.BacklogSetting == BacklogSettingType.Inherit); } [Test] public void GetMissingForEnabledSeries_should_return_explicity_enabled_and_inherit_series_when_backlog_searching_is_enabled() { var series = Builder.CreateListOfSize(3) .TheFirst(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Disable) .TheNext(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Enable) .TheNext(1) .With(s => s.Monitored = true) .With(s => s.BacklogSetting = BacklogSettingType.Inherit) .Build(); var episodes = Builder.CreateListOfSize(12) .TheFirst(3) .With(e => e.Series = series[0]) .TheNext(4) .With(e => e.Series = series[1]) .TheNext(5) .With(e => e.Series = series[2]) .Build().ToList(); WithEnableBacklogSearching(); Mocker.GetMock() .Setup(s => s.EpisodesWithoutFiles(true)).Returns(episodes); var result = Subject.GetMissingForEnabledSeries(); result.Should().NotBeEmpty(); result.Should().Contain(s => s.Series.BacklogSetting == BacklogSettingType.Enable); result.Should().NotContain(s => s.Series.BacklogSetting == BacklogSettingType.Disable); result.Should().Contain(s => s.Series.BacklogSetting == BacklogSettingType.Inherit); } } }