using System; using System.Collections.Generic; using System.IO; using System.Linq; using FizzWare.NBuilder; using Moq; using NUnit.Framework; using NzbDrone.Common.Extensions; using NzbDrone.Core.AutoTagging; using NzbDrone.Core.Exceptions; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MetadataSource; using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Tv; using NzbDrone.Core.Tv.Commands; using NzbDrone.Test.Common; namespace NzbDrone.Core.Test.TvTests { [TestFixture] public class RefreshSeriesServiceFixture : CoreTest { private Series _series; [SetUp] public void Setup() { var season1 = Builder.CreateNew() .With(s => s.SeasonNumber = 1) .Build(); _series = Builder.CreateNew() .With(s => s.Status = SeriesStatusType.Continuing) .With(s => s.Seasons = new List { season1 }) .Build(); Mocker.GetMock() .Setup(s => s.GetSeries(_series.Id)) .Returns(_series); Mocker.GetMock() .Setup(s => s.GetSeriesInfo(It.IsAny())) .Callback(p => { throw new SeriesNotFoundException(p); }); Mocker.GetMock() .Setup(s => s.GetTagChanges(_series)) .Returns(new AutoTaggingChanges()); } private void GivenNewSeriesInfo(Series series) { Mocker.GetMock() .Setup(s => s.GetSeriesInfo(_series.TvdbId)) .Returns(new Tuple>(series, new List())); } [Test] public void should_monitor_new_seasons_automatically_if_monitor_new_items_is_all() { _series.MonitorNewItems = NewItemMonitorTypes.All; var newSeriesInfo = _series.JsonClone(); newSeriesInfo.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 2).Monitored == true), It.IsAny(), It.IsAny())); } [Test] public void should_not_monitor_new_seasons_automatically_if_monitor_new_items_is_none() { _series.MonitorNewItems = NewItemMonitorTypes.None; var newSeriesInfo = _series.JsonClone(); newSeriesInfo.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 2).Monitored == false), It.IsAny(), It.IsAny())); } [Test] public void should_not_monitor_new_special_season_automatically() { var series = _series.JsonClone(); series.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 0) .Build()); GivenNewSeriesInfo(series); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 0).Monitored == false), It.IsAny(), It.IsAny())); } [Test] public void should_update_tvrage_id_if_changed() { var newSeriesInfo = _series.JsonClone(); newSeriesInfo.TvRageId = _series.TvRageId + 1; GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.TvRageId == newSeriesInfo.TvRageId), It.IsAny(), It.IsAny())); } [Test] public void should_update_tvmaze_id_if_changed() { var newSeriesInfo = _series.JsonClone(); newSeriesInfo.TvMazeId = _series.TvMazeId + 1; GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.TvMazeId == newSeriesInfo.TvMazeId), It.IsAny(), It.IsAny())); } [Test] public void should_update_tmdb_id_if_changed() { var newSeriesInfo = _series.JsonClone(); newSeriesInfo.TmdbId = _series.TmdbId + 1; GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.TmdbId == newSeriesInfo.TmdbId), It.IsAny(), It.IsAny())); } [Test] public void should_log_error_if_tvdb_id_not_found() { Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Status == SeriesStatusType.Deleted), It.IsAny(), It.IsAny()), Times.Once()); ExceptionVerification.ExpectedErrors(1); } [Test] public void should_mark_as_deleted_if_tvdb_id_not_found() { Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Status == SeriesStatusType.Deleted), It.IsAny(), It.IsAny()), Times.Once()); ExceptionVerification.ExpectedErrors(1); } [Test] public void should_not_remark_as_deleted_if_tvdb_id_not_found() { _series.Status = SeriesStatusType.Deleted; Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.IsAny(), It.IsAny(), It.IsAny()), Times.Never()); ExceptionVerification.ExpectedErrors(1); } [Test] public void should_update_if_tvdb_id_changed() { var newSeriesInfo = _series.JsonClone(); newSeriesInfo.TvdbId = _series.TvdbId + 1; GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.TvdbId == newSeriesInfo.TvdbId), It.IsAny(), It.IsAny())); ExceptionVerification.ExpectedWarns(1); } [Test] public void should_not_throw_if_duplicate_season_is_in_existing_info() { var newSeriesInfo = _series.JsonClone(); newSeriesInfo.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); _series.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); _series.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2), It.IsAny(), It.IsAny())); } [Test] public void should_filter_duplicate_seasons() { var newSeriesInfo = _series.JsonClone(); newSeriesInfo.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); newSeriesInfo.Seasons.Add(Builder.CreateNew() .With(s => s.SeasonNumber = 2) .Build()); GivenNewSeriesInfo(newSeriesInfo); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2), It.IsAny(), It.IsAny())); } [Test] public void should_rescan_series_if_updating_fails() { Mocker.GetMock() .Setup(s => s.GetSeriesInfo(_series.Id)) .Throws(new IOException()); Assert.Throws(() => Subject.Execute(new RefreshSeriesCommand(new List { _series.Id }))); Mocker.GetMock() .Verify(v => v.Scan(_series), Times.Once()); ExceptionVerification.ExpectedErrors(1); } [Test] public void should_not_rescan_series_if_updating_fails_with_series_not_found() { Mocker.GetMock() .Setup(s => s.GetSeriesInfo(_series.Id)) .Throws(new SeriesNotFoundException(_series.Id)); Subject.Execute(new RefreshSeriesCommand(new List { _series.Id })); Mocker.GetMock() .Verify(v => v.Scan(_series), Times.Never()); ExceptionVerification.ExpectedErrors(1); } } }