From 6e4638f7b1c7e553746352b7a3f6ecab313ccfde Mon Sep 17 00:00:00 2001 From: Qstick Date: Thu, 28 Sep 2017 22:02:08 -0400 Subject: [PATCH] Update Music Tests, Added Cases for Should Refresh Artist, Cleanup Skyhook Resources --- .../SkyHook/SkyHookProxyFixture.cs | 91 ++++----- .../MusicTests/RefreshArtistServiceFixture.cs | 140 +++++++++++++ .../MusicTests/ShouldRefreshArtistFixture.cs | 135 +++++++++++++ .../NzbDrone.Core.Test.csproj | 4 +- .../TvTests/RefreshEpisodeServiceFixture.cs | 6 +- .../TvTests/RefreshSeriesServiceFixture.cs | 184 ------------------ .../TvTests/ShouldRefreshSeriesFixture.cs | 135 ------------- .../MetadataSource/IProvideSeriesInfo.cs | 11 -- .../SkyHook/Resource/ArtistInfoResource.cs | 19 -- .../SkyHook/Resource/EpisodeResource.cs | 17 -- .../{ActorResource.cs => MemberResource.cs} | 6 +- .../SkyHook/Resource/SeasonResource.cs | 15 -- .../SkyHook/Resource/ShowResource.cs | 43 ---- .../MetadataSource/SkyHook/SkyHookProxy.cs | 18 +- .../Music/ShouldRefreshArtist.cs | 26 ++- src/NzbDrone.Core/NzbDrone.Core.csproj | 8 +- src/NzbDrone.Core/Tv/AddSeriesService.cs | 49 ----- src/NzbDrone.Core/Tv/RefreshSeriesService.cs | 80 +------- src/NzbDrone.Core/Tv/ShouldRefreshSeries.cs | 55 ------ 19 files changed, 352 insertions(+), 690 deletions(-) create mode 100644 src/NzbDrone.Core.Test/MusicTests/RefreshArtistServiceFixture.cs create mode 100644 src/NzbDrone.Core.Test/MusicTests/ShouldRefreshArtistFixture.cs delete mode 100644 src/NzbDrone.Core.Test/TvTests/RefreshSeriesServiceFixture.cs delete mode 100644 src/NzbDrone.Core.Test/TvTests/ShouldRefreshSeriesFixture.cs delete mode 100644 src/NzbDrone.Core/MetadataSource/IProvideSeriesInfo.cs delete mode 100644 src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ArtistInfoResource.cs delete mode 100644 src/NzbDrone.Core/MetadataSource/SkyHook/Resource/EpisodeResource.cs rename src/NzbDrone.Core/MetadataSource/SkyHook/Resource/{ActorResource.cs => MemberResource.cs} (65%) delete mode 100644 src/NzbDrone.Core/MetadataSource/SkyHook/Resource/SeasonResource.cs delete mode 100644 src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ShowResource.cs delete mode 100644 src/NzbDrone.Core/Tv/ShouldRefreshSeries.cs diff --git a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs index e6178c0d2..67cd315b2 100644 --- a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs +++ b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxyFixture.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; @@ -7,7 +7,7 @@ using NzbDrone.Core.Exceptions; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MetadataSource.SkyHook; using NzbDrone.Core.Test.Framework; -using NzbDrone.Core.Tv; +using NzbDrone.Core.Music; using NzbDrone.Test.Common.Categories; namespace NzbDrone.Core.Test.MetadataSource.SkyHook @@ -22,88 +22,75 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook UseRealHttp(); } - [TestCase(75978, "Family Guy")] - [TestCase(83462, "Castle (2009)")] - [TestCase(266189, "The Blacklist")] - public void should_be_able_to_get_series_detail(int tvdbId, string title) + [TestCase("f59c5520-5f46-4d2c-b2c4-822eabf53419", "Linkin Park")] + [TestCase("66c662b6-6e2f-4930-8610-912e24c63ed1", "AC/DC")] + public void should_be_able_to_get_artist_detail(string mbId, string name) { - var details = Subject.GetSeriesInfo(tvdbId); + var details = Subject.GetArtistInfo(mbId); - ValidateSeries(details.Item1); - ValidateEpisodes(details.Item2); + ValidateArtist(details.Item1); + ValidateAlbums(details.Item2); - details.Item1.Title.Should().Be(title); + details.Item1.Name.Should().Be(name); } [Test] - public void getting_details_of_invalid_series() + public void getting_details_of_invalid_artist() { - Assert.Throws(() => Subject.GetSeriesInfo(int.MaxValue)); + Assert.Throws(() => Subject.GetArtistInfo("aaaaaa-aaa-aaaa-aaaa")); } [Test] - public void should_not_have_period_at_start_of_title_slug() + public void should_not_have_period_at_start_of_name_slug() { - var details = Subject.GetSeriesInfo(79099); + var details = Subject.GetArtistInfo("f59c5520-5f46-4d2c-b2c4-822eabf53419"); - details.Item1.TitleSlug.Should().Be("dothack"); + details.Item1.NameSlug.Should().Be("dothack"); } - private void ValidateSeries(Series series) + private void ValidateArtist(Artist artist) { - series.Should().NotBeNull(); - series.Title.Should().NotBeNullOrWhiteSpace(); - series.CleanTitle.Should().Be(Parser.Parser.CleanSeriesTitle(series.Title)); - series.SortTitle.Should().Be(SeriesTitleNormalizer.Normalize(series.Title, series.TvdbId)); - series.Overview.Should().NotBeNullOrWhiteSpace(); - series.AirTime.Should().NotBeNullOrWhiteSpace(); - series.FirstAired.Should().HaveValue(); - series.FirstAired.Value.Kind.Should().Be(DateTimeKind.Utc); - series.Images.Should().NotBeEmpty(); - series.ImdbId.Should().NotBeNullOrWhiteSpace(); - series.Network.Should().NotBeNullOrWhiteSpace(); - series.Runtime.Should().BeGreaterThan(0); - series.TitleSlug.Should().NotBeNullOrWhiteSpace(); + artist.Should().NotBeNull(); + artist.Name.Should().NotBeNullOrWhiteSpace(); + artist.CleanName.Should().Be(Parser.Parser.CleanSeriesTitle(artist.Name)); + artist.SortName.Should().Be(Parser.Parser.NormalizeTitle(artist.Name)); + artist.Overview.Should().NotBeNullOrWhiteSpace(); + artist.Images.Should().NotBeEmpty(); + artist.NameSlug.Should().NotBeNullOrWhiteSpace(); //series.TvRageId.Should().BeGreaterThan(0); - series.TvdbId.Should().BeGreaterThan(0); + artist.ForeignArtistId.Should().NotBeNullOrWhiteSpace(); } - private void ValidateEpisodes(List episodes) + private void ValidateAlbums(List albums) { - episodes.Should().NotBeEmpty(); + albums.Should().NotBeEmpty(); - var episodeGroup = episodes.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000")); + var episodeGroup = albums.GroupBy(e => e.AlbumType + e.Title); episodeGroup.Should().OnlyContain(c => c.Count() == 1); + - episodes.Should().Contain(c => c.SeasonNumber > 0); - episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Overview)); - - foreach (var episode in episodes) + foreach (var episode in albums) { - ValidateEpisode(episode); + ValidateAlbum(episode); - //if atleast one episdoe has title it means parse it working. - episodes.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Title)); + //if atleast one album has title it means parse it working. + albums.Should().Contain(c => !string.IsNullOrWhiteSpace(c.Title)); } } - private void ValidateEpisode(Episode episode) + private void ValidateAlbum(Album album) { - episode.Should().NotBeNull(); - - //TODO: Is there a better way to validate that episode number or season number is greater than zero? - (episode.EpisodeNumber + episode.SeasonNumber).Should().NotBe(0); + album.Should().NotBeNull(); + + album.Title.Should().NotBeNullOrWhiteSpace(); + album.AlbumType.Should().NotBeNullOrWhiteSpace(); - episode.Should().NotBeNull(); + album.Should().NotBeNull(); - if (episode.AirDateUtc.HasValue) + if (album.ReleaseDate.HasValue) { - episode.AirDateUtc.Value.Kind.Should().Be(DateTimeKind.Utc); + album.ReleaseDate.Value.Kind.Should().Be(DateTimeKind.Utc); } - - episode.Images.Any(i => i.CoverType == MediaCoverTypes.Screenshot && i.Url.Contains("-940.")) - .Should() - .BeFalse(); } } } diff --git a/src/NzbDrone.Core.Test/MusicTests/RefreshArtistServiceFixture.cs b/src/NzbDrone.Core.Test/MusicTests/RefreshArtistServiceFixture.cs new file mode 100644 index 000000000..20dc7d223 --- /dev/null +++ b/src/NzbDrone.Core.Test/MusicTests/RefreshArtistServiceFixture.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using FizzWare.NBuilder; +using Moq; +using NUnit.Framework; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Exceptions; +using NzbDrone.Core.MetadataSource; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Core.Music; +using NzbDrone.Core.Music.Commands; +using NzbDrone.Test.Common; + +namespace NzbDrone.Core.Test.MusicTests +{ + [TestFixture] + public class RefreshArtistServiceFixture : CoreTest + { + private Artist _artist; + + [SetUp] + public void Setup() + { + var season1 = Builder.CreateNew() + .With(s => s.ForeignAlbumId = "1") + .Build(); + + _artist = Builder.CreateNew() + .With(s => s.Albums = new List + { + season1 + }) + .Build(); + + Mocker.GetMock() + .Setup(s => s.GetArtist(_artist.Id)) + .Returns(_artist); + + Mocker.GetMock() + .Setup(s => s.GetArtistInfo(It.IsAny())) + .Callback(p => { throw new ArtistNotFoundException(p); }); + } + + private void GivenNewArtistInfo(Artist artist) + { + Mocker.GetMock() + .Setup(s => s.GetArtistInfo(_artist.ForeignArtistId)) + .Returns(new Tuple>(artist, new List())); + } + + [Test] + public void should_monitor_new_albums_automatically() + { + var newArtistInfo = _artist.JsonClone(); + newArtistInfo.Albums.Add(Builder.CreateNew() + .With(s => s.ForeignAlbumId = "2") + .Build()); + + GivenNewArtistInfo(newArtistInfo); + + Subject.Execute(new RefreshArtistCommand(_artist.Id)); + + Mocker.GetMock() + .Verify(v => v.UpdateArtist(It.Is(s => s.Albums.Count == 2 && s.Albums.Single(season => season.ForeignAlbumId == "2").Monitored == true))); + } + + [Test] + public void should_log_error_if_musicbrainz_id_not_found() + { + Subject.Execute(new RefreshArtistCommand(_artist.Id)); + + Mocker.GetMock() + .Verify(v => v.UpdateArtist(It.IsAny()), Times.Never()); + + ExceptionVerification.ExpectedErrors(1); + } + + [Test] + public void should_update_if_musicbrainz_id_changed() + { + var newArtistInfo = _artist.JsonClone(); + newArtistInfo.ForeignArtistId = _artist.ForeignArtistId + 1; + + GivenNewArtistInfo(newArtistInfo); + + Subject.Execute(new RefreshArtistCommand(_artist.Id)); + + Mocker.GetMock() + .Verify(v => v.UpdateArtist(It.Is(s => s.ForeignArtistId == newArtistInfo.ForeignArtistId))); + + ExceptionVerification.ExpectedWarns(1); + } + + [Test] + public void should_not_throw_if_duplicate_album_is_in_existing_info() + { + var newArtistInfo = _artist.JsonClone(); + newArtistInfo.Albums.Add(Builder.CreateNew() + .With(s => s.ForeignAlbumId = "2") + .Build()); + + _artist.Albums.Add(Builder.CreateNew() + .With(s => s.ForeignAlbumId = "2") + .Build()); + + _artist.Albums.Add(Builder.CreateNew() + .With(s => s.ForeignAlbumId = "2") + .Build()); + + GivenNewArtistInfo(newArtistInfo); + + Subject.Execute(new RefreshArtistCommand(_artist.Id)); + + Mocker.GetMock() + .Verify(v => v.UpdateArtist(It.Is(s => s.Albums.Count == 2))); + } + + [Test] + public void should_filter_duplicate_albums() + { + var newArtistInfo = _artist.JsonClone(); + newArtistInfo.Albums.Add(Builder.CreateNew() + .With(s => s.ForeignAlbumId = "2") + .Build()); + + newArtistInfo.Albums.Add(Builder.CreateNew() + .With(s => s.ForeignAlbumId = "2") + .Build()); + + GivenNewArtistInfo(newArtistInfo); + + Subject.Execute(new RefreshArtistCommand(_artist.Id)); + + Mocker.GetMock() + .Verify(v => v.UpdateArtist(It.Is(s => s.Albums.Count == 2))); + + } + } +} diff --git a/src/NzbDrone.Core.Test/MusicTests/ShouldRefreshArtistFixture.cs b/src/NzbDrone.Core.Test/MusicTests/ShouldRefreshArtistFixture.cs new file mode 100644 index 000000000..61d528402 --- /dev/null +++ b/src/NzbDrone.Core.Test/MusicTests/ShouldRefreshArtistFixture.cs @@ -0,0 +1,135 @@ +using System; +using System.Linq; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Music; +using NzbDrone.Test.Common; + +namespace NzbDrone.Core.Test.MusicTests +{ + [TestFixture] + public class ShouldRefreshArtistFixture : TestBase + { + private Artist _artist; + + [SetUp] + public void Setup() + { + _artist = Builder.CreateNew() + .With(v => v.Status == ArtistStatusType.Continuing) + .Build(); + + Mocker.GetMock() + .Setup(s => s.GetAlbumsByArtist(_artist.Id)) + .Returns(Builder.CreateListOfSize(2) + .All() + .With(e => e.ReleaseDate = DateTime.Today.AddDays(-100)) + .Build() + .ToList()); + } + + private void GivenArtistIsEnded() + { + _artist.Status = ArtistStatusType.Ended; + } + + private void GivenArtistLastRefreshedMonthsAgo() + { + _artist.LastInfoSync = DateTime.UtcNow.AddDays(-90); + } + + private void GivenArtistLastRefreshedYesterday() + { + _artist.LastInfoSync = DateTime.UtcNow.AddDays(-1); + } + + private void GivenArtistLastRefreshedHalfADayAgo() + { + _artist.LastInfoSync = DateTime.UtcNow.AddHours(-12); + } + + private void GivenArtistLastRefreshedRecently() + { + _artist.LastInfoSync = DateTime.UtcNow.AddHours(-1); + } + + private void GivenRecentlyAired() + { + Mocker.GetMock() + .Setup(s => s.GetAlbumsByArtist(_artist.Id)) + .Returns(Builder.CreateListOfSize(2) + .TheFirst(1) + .With(e => e.ReleaseDate = DateTime.Today.AddDays(-7)) + .TheLast(1) + .With(e => e.ReleaseDate = DateTime.Today.AddDays(-100)) + .Build() + .ToList()); + } + + [Test] + public void should_return_true_if_running_artist_last_refreshed_more_than_6_hours_ago() + { + GivenArtistLastRefreshedHalfADayAgo(); + + Subject.ShouldRefresh(_artist).Should().BeTrue(); + } + + [Test] + public void should_return_false_if_running_artist_last_refreshed_less_than_6_hours_ago() + { + GivenArtistLastRefreshedRecently(); + + Subject.ShouldRefresh(_artist).Should().BeFalse(); + } + + [Test] + public void should_return_false_if_ended_artist_last_refreshed_yesterday() + { + GivenArtistIsEnded(); + GivenArtistLastRefreshedYesterday(); + + Subject.ShouldRefresh(_artist).Should().BeFalse(); + } + + [Test] + public void should_return_true_if_artist_last_refreshed_more_than_30_days_ago() + { + GivenArtistIsEnded(); + GivenArtistLastRefreshedMonthsAgo(); + + Subject.ShouldRefresh(_artist).Should().BeTrue(); + } + + [Test] + public void should_return_true_if_album_released_in_last_30_days() + { + GivenArtistIsEnded(); + GivenArtistLastRefreshedYesterday(); + + GivenRecentlyAired(); + + Subject.ShouldRefresh(_artist).Should().BeTrue(); + } + + [Test] + public void should_return_false_when_recently_refreshed_ended_show_has_not_aired_for_30_days() + { + GivenArtistIsEnded(); + GivenArtistLastRefreshedYesterday(); + + Subject.ShouldRefresh(_artist).Should().BeFalse(); + } + + [Test] + public void should_return_false_when_recently_refreshed_ended_show_aired_in_last_30_days() + { + GivenArtistIsEnded(); + GivenArtistLastRefreshedRecently(); + + GivenRecentlyAired(); + + Subject.ShouldRefresh(_artist).Should().BeFalse(); + } + } +} diff --git a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj index c37b48540..0e85a29f1 100644 --- a/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj +++ b/src/NzbDrone.Core.Test/NzbDrone.Core.Test.csproj @@ -365,13 +365,13 @@ - + - + diff --git a/src/NzbDrone.Core.Test/TvTests/RefreshEpisodeServiceFixture.cs b/src/NzbDrone.Core.Test/TvTests/RefreshEpisodeServiceFixture.cs index 592b56dc3..53aa18cdc 100644 --- a/src/NzbDrone.Core.Test/TvTests/RefreshEpisodeServiceFixture.cs +++ b/src/NzbDrone.Core.Test/TvTests/RefreshEpisodeServiceFixture.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using FizzWare.NBuilder; @@ -25,7 +25,7 @@ namespace NzbDrone.Core.Test.TvTests { UseRealHttp(); - _gameOfThrones = Mocker.Resolve().GetSeriesInfo(121361);//Game of thrones + // _gameOfThrones = Mocker.Resolve().GetSeriesInfo(121361);//Game of thrones // Remove specials. _gameOfThrones.Item2.RemoveAll(v => v.SeasonNumber == 0); @@ -394,4 +394,4 @@ namespace NzbDrone.Core.Test.TvTests _updatedEpisodes.First().AbsoluteEpisodeNumber.Should().Be(episodes[1].AbsoluteEpisodeNumber); } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core.Test/TvTests/RefreshSeriesServiceFixture.cs b/src/NzbDrone.Core.Test/TvTests/RefreshSeriesServiceFixture.cs deleted file mode 100644 index f441496cd..000000000 --- a/src/NzbDrone.Core.Test/TvTests/RefreshSeriesServiceFixture.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using FizzWare.NBuilder; -using Moq; -using NUnit.Framework; -using NzbDrone.Common.Extensions; -using NzbDrone.Core.Exceptions; -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.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); }); - } - - 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() - { - var newSeriesInfo = _series.JsonClone(); - newSeriesInfo.Seasons.Add(Builder.CreateNew() - .With(s => s.SeasonNumber = 2) - .Build()); - - GivenNewSeriesInfo(newSeriesInfo); - - Subject.Execute(new RefreshSeriesCommand(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 2).Monitored == true))); - } - - [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(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2 && s.Seasons.Single(season => season.SeasonNumber == 0).Monitored == false))); - } - - [Test] - public void should_update_tvrage_id_if_changed() - { - var newSeriesInfo = _series.JsonClone(); - newSeriesInfo.TvRageId = _series.TvRageId + 1; - - GivenNewSeriesInfo(newSeriesInfo); - - Subject.Execute(new RefreshSeriesCommand(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.TvRageId == newSeriesInfo.TvRageId))); - } - - [Test] - public void should_update_tvmaze_id_if_changed() - { - var newSeriesInfo = _series.JsonClone(); - newSeriesInfo.TvMazeId = _series.TvMazeId + 1; - - GivenNewSeriesInfo(newSeriesInfo); - - Subject.Execute(new RefreshSeriesCommand(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.TvMazeId == newSeriesInfo.TvMazeId))); - } - - [Test] - public void should_log_error_if_tvdb_id_not_found() - { - Subject.Execute(new RefreshSeriesCommand(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(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(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.TvdbId == newSeriesInfo.TvdbId))); - - 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(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2))); - } - - [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(_series.Id)); - - Mocker.GetMock() - .Verify(v => v.UpdateSeries(It.Is(s => s.Seasons.Count == 2))); - - } - } -} diff --git a/src/NzbDrone.Core.Test/TvTests/ShouldRefreshSeriesFixture.cs b/src/NzbDrone.Core.Test/TvTests/ShouldRefreshSeriesFixture.cs deleted file mode 100644 index 6fb44c09a..000000000 --- a/src/NzbDrone.Core.Test/TvTests/ShouldRefreshSeriesFixture.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.Linq; -using FizzWare.NBuilder; -using FluentAssertions; -using NUnit.Framework; -using NzbDrone.Core.Tv; -using NzbDrone.Test.Common; - -namespace NzbDrone.Core.Test.TvTests -{ - [TestFixture] - public class ShouldRefreshSeriesFixture : TestBase - { - private Series _series; - - [SetUp] - public void Setup() - { - _series = Builder.CreateNew() - .With(v => v.Status == SeriesStatusType.Continuing) - .Build(); - - Mocker.GetMock() - .Setup(s => s.GetEpisodeBySeries(_series.Id)) - .Returns(Builder.CreateListOfSize(2) - .All() - .With(e => e.AirDateUtc = DateTime.Today.AddDays(-100)) - .Build() - .ToList()); - } - - private void GivenSeriesIsEnded() - { - _series.Status = SeriesStatusType.Ended; - } - - private void GivenSeriesLastRefreshedMonthsAgo() - { - _series.LastInfoSync = DateTime.UtcNow.AddDays(-90); - } - - private void GivenSeriesLastRefreshedYesterday() - { - _series.LastInfoSync = DateTime.UtcNow.AddDays(-1); - } - - private void GivenSeriesLastRefreshedHalfADayAgo() - { - _series.LastInfoSync = DateTime.UtcNow.AddHours(-12); - } - - private void GivenSeriesLastRefreshedRecently() - { - _series.LastInfoSync = DateTime.UtcNow.AddHours(-1); - } - - private void GivenRecentlyAired() - { - Mocker.GetMock() - .Setup(s => s.GetEpisodeBySeries(_series.Id)) - .Returns(Builder.CreateListOfSize(2) - .TheFirst(1) - .With(e => e.AirDateUtc = DateTime.Today.AddDays(-7)) - .TheLast(1) - .With(e => e.AirDateUtc = DateTime.Today.AddDays(-100)) - .Build() - .ToList()); - } - - [Test] - public void should_return_true_if_running_series_last_refreshed_more_than_6_hours_ago() - { - GivenSeriesLastRefreshedHalfADayAgo(); - - Subject.ShouldRefresh(_series).Should().BeTrue(); - } - - [Test] - public void should_return_false_if_running_series_last_refreshed_less_than_6_hours_ago() - { - GivenSeriesLastRefreshedRecently(); - - Subject.ShouldRefresh(_series).Should().BeFalse(); - } - - [Test] - public void should_return_false_if_ended_series_last_refreshed_yesterday() - { - GivenSeriesIsEnded(); - GivenSeriesLastRefreshedYesterday(); - - Subject.ShouldRefresh(_series).Should().BeFalse(); - } - - [Test] - public void should_return_true_if_series_last_refreshed_more_than_30_days_ago() - { - GivenSeriesIsEnded(); - GivenSeriesLastRefreshedMonthsAgo(); - - Subject.ShouldRefresh(_series).Should().BeTrue(); - } - - [Test] - public void should_return_true_if_episode_aired_in_last_30_days() - { - GivenSeriesIsEnded(); - GivenSeriesLastRefreshedYesterday(); - - GivenRecentlyAired(); - - Subject.ShouldRefresh(_series).Should().BeTrue(); - } - - [Test] - public void should_return_false_when_recently_refreshed_ended_show_has_not_aired_for_30_days() - { - GivenSeriesIsEnded(); - GivenSeriesLastRefreshedYesterday(); - - Subject.ShouldRefresh(_series).Should().BeFalse(); - } - - [Test] - public void should_return_false_when_recently_refreshed_ended_show_aired_in_last_30_days() - { - GivenSeriesIsEnded(); - GivenSeriesLastRefreshedRecently(); - - GivenRecentlyAired(); - - Subject.ShouldRefresh(_series).Should().BeFalse(); - } - } -} diff --git a/src/NzbDrone.Core/MetadataSource/IProvideSeriesInfo.cs b/src/NzbDrone.Core/MetadataSource/IProvideSeriesInfo.cs deleted file mode 100644 index f2ab03336..000000000 --- a/src/NzbDrone.Core/MetadataSource/IProvideSeriesInfo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using NzbDrone.Core.Tv; - -namespace NzbDrone.Core.MetadataSource -{ - public interface IProvideSeriesInfo - { - Tuple> GetSeriesInfo(int tvdbSeriesId); - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ArtistInfoResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ArtistInfoResource.cs deleted file mode 100644 index 8a81d873f..000000000 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ArtistInfoResource.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; - -namespace NzbDrone.Core.MetadataSource.SkyHook.Resource -{ - public class ArtistInfoResource - { - public ArtistInfoResource() { } - - public List Genres { get; set; } - public string AristUrl { get; set; } - public string Overview { get; set; } - public string Id { get; set; } - public List Images { get; set; } - public string ArtistName { get; set; } - } -} diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/EpisodeResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/EpisodeResource.cs deleted file mode 100644 index acaffe418..000000000 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/EpisodeResource.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace NzbDrone.Core.MetadataSource.SkyHook.Resource -{ - public class EpisodeResource - { - public int SeasonNumber { get; set; } - public int EpisodeNumber { get; set; } - public int? AbsoluteEpisodeNumber { get; set; } - public string Title { get; set; } - public string AirDate { get; set; } - public DateTime? AirDateUtc { get; set; } - public RatingResource Rating { get; set; } - public string Overview { get; set; } - public string Image { get; set; } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ActorResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/MemberResource.cs similarity index 65% rename from src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ActorResource.cs rename to src/NzbDrone.Core/MetadataSource/SkyHook/Resource/MemberResource.cs index 180933387..1f79b6221 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ActorResource.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/MemberResource.cs @@ -1,9 +1,9 @@ namespace NzbDrone.Core.MetadataSource.SkyHook.Resource { - public class ActorResource + public class MemberResource { public string Name { get; set; } - public string Character { get; set; } + public string Instrument { get; set; } public string Image { get; set; } } -} \ No newline at end of file +} diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/SeasonResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/SeasonResource.cs deleted file mode 100644 index 55ce6ccf9..000000000 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/SeasonResource.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; - -namespace NzbDrone.Core.MetadataSource.SkyHook.Resource -{ - public class SeasonResource - { - public SeasonResource() - { - Images = new List(); - } - - public int SeasonNumber { get; set; } - public List Images { get; set; } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ShowResource.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ShowResource.cs deleted file mode 100644 index fd442100d..000000000 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/ShowResource.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Collections.Generic; - -namespace NzbDrone.Core.MetadataSource.SkyHook.Resource -{ - public class ShowResource - { - public ShowResource() - { - Actors = new List(); - Genres = new List(); - Images = new List(); - Seasons = new List(); - Episodes = new List(); - } - - public int TvdbId { get; set; } - public string Title { get; set; } - public string Overview { get; set; } - //public string Language { get; set; } - public string Slug { get; set; } - public string FirstAired { get; set; } - public int? TvRageId { get; set; } - public int? TvMazeId { get; set; } - - public string Status { get; set; } - public int? Runtime { get; set; } - public TimeOfDayResource TimeOfDay { get; set; } - - public string Network { get; set; } - public string ImdbId { get; set; } - - public List Actors { get; set; } - public List Genres { get; set; } - - public string ContentRating { get; set; } - - public RatingResource Rating { get; set; } - - public List Images { get; set; } - public List Seasons { get; set; } - public List Episodes { get; set; } - } -} \ No newline at end of file diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 6203d4ce9..8c3d770b7 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -17,7 +17,7 @@ using NzbDrone.Core.Configuration; namespace NzbDrone.Core.MetadataSource.SkyHook { - public class SkyHookProxy : IProvideSeriesInfo, IProvideArtistInfo, ISearchForNewArtist + public class SkyHookProxy : IProvideArtistInfo, ISearchForNewArtist { private readonly IHttpClient _httpClient; private readonly Logger _logger; @@ -37,12 +37,6 @@ namespace NzbDrone.Core.MetadataSource.SkyHook _logger = logger; } - [Obsolete("Used for Sonarr, not Lidarr")] - public Tuple> GetSeriesInfo(int tvdbSeriesId) - { - throw new NotImplementedException(); - } - public Tuple> GetArtistInfo(string foreignArtistId) { @@ -191,23 +185,23 @@ namespace NzbDrone.Core.MetadataSource.SkyHook return artist; } - private static Actor MapActors(ActorResource arg) + private static Member MapMembers(MemberResource arg) { - var newActor = new Actor + var newMember = new Member { Name = arg.Name, - Character = arg.Character + Instrument = arg.Instrument }; if (arg.Image != null) { - newActor.Images = new List + newMember.Images = new List { new MediaCover.MediaCover(MediaCoverTypes.Headshot, arg.Image) }; } - return newActor; + return newMember; } private static ArtistStatusType MapArtistStatus(string status) diff --git a/src/NzbDrone.Core/Music/ShouldRefreshArtist.cs b/src/NzbDrone.Core/Music/ShouldRefreshArtist.cs index f38ccaaf5..de252678c 100644 --- a/src/NzbDrone.Core/Music/ShouldRefreshArtist.cs +++ b/src/NzbDrone.Core/Music/ShouldRefreshArtist.cs @@ -1,4 +1,4 @@ -using NLog; +using NLog; using System; using System.Collections.Generic; using System.Linq; @@ -11,14 +11,14 @@ namespace NzbDrone.Core.Music bool ShouldRefresh(Artist artist); } - public class CheckIfArtistShouldBeRefreshed : ICheckIfArtistShouldBeRefreshed + public class ShouldRefreshArtist : ICheckIfArtistShouldBeRefreshed { - private readonly ITrackService _trackService; + private readonly IAlbumService _albumService; private readonly Logger _logger; - public CheckIfArtistShouldBeRefreshed(ITrackService trackService, Logger logger) + public ShouldRefreshArtist(IAlbumService albumService, Logger logger) { - _trackService = trackService; + _albumService = albumService; _logger = logger; } @@ -36,7 +36,21 @@ namespace NzbDrone.Core.Music return false; } - //_logger.Trace("Artist {0} ended long ago, should not be refreshed.", artist.Title); + if (artist.Status == ArtistStatusType.Continuing) + { + _logger.Trace("Artist {0} is continuing, should refresh.", artist.Name); + return true; + } + + var lastAlbum = _albumService.GetAlbumsByArtist(artist.Id).OrderByDescending(e => e.ReleaseDate).FirstOrDefault(); + + if (lastAlbum != null && lastAlbum.ReleaseDate > DateTime.UtcNow.AddDays(-30)) + { + _logger.Trace("Last album in {0} aired less than 30 days ago, should refresh.", artist.Name); + return true; + } + + _logger.Trace("Artist {0} ended long ago, should not be refreshed.", artist.Name); return false; } } diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj index 3affe55b8..d4d7e6b8a 100644 --- a/src/NzbDrone.Core/NzbDrone.Core.csproj +++ b/src/NzbDrone.Core/NzbDrone.Core.csproj @@ -828,18 +828,13 @@ - - + - - - - @@ -1191,7 +1186,6 @@ - diff --git a/src/NzbDrone.Core/Tv/AddSeriesService.cs b/src/NzbDrone.Core/Tv/AddSeriesService.cs index 0a4a593d2..1c8e0a294 100644 --- a/src/NzbDrone.Core/Tv/AddSeriesService.cs +++ b/src/NzbDrone.Core/Tv/AddSeriesService.cs @@ -16,25 +16,21 @@ namespace NzbDrone.Core.Tv public interface IAddSeriesService { Series AddSeries(Series newSeries); - List AddSeries(List newSeries); } public class AddSeriesService : IAddSeriesService { private readonly ISeriesService _seriesService; - private readonly IProvideSeriesInfo _seriesInfo; private readonly IBuildFileNames _fileNameBuilder; private readonly IAddSeriesValidator _addSeriesValidator; private readonly Logger _logger; public AddSeriesService(ISeriesService seriesService, - IProvideSeriesInfo seriesInfo, IBuildFileNames fileNameBuilder, IAddSeriesValidator addSeriesValidator, Logger logger) { _seriesService = seriesService; - _seriesInfo = seriesInfo; _fileNameBuilder = fileNameBuilder; _addSeriesValidator = addSeriesValidator; _logger = logger; @@ -44,7 +40,6 @@ namespace NzbDrone.Core.Tv { Ensure.That(newSeries, () => newSeries).IsNotNull(); - newSeries = AddSkyhookData(newSeries); newSeries = SetPropertiesAndValidate(newSeries); _logger.Info("Adding Series {0} Path: [{1}]", newSeries, newSeries.Path); @@ -53,50 +48,6 @@ namespace NzbDrone.Core.Tv return newSeries; } - public List AddSeries(List newSeries) - { - var added = DateTime.UtcNow; - var seriesToAdd = new List(); - foreach (var s in newSeries) - { - // TODO: Verify if adding skyhook data will be slow - var series = AddSkyhookData(s); - series = SetPropertiesAndValidate(series); - series.Added = added; - seriesToAdd.Add(series); - } - return _seriesService.AddSeries(seriesToAdd); - - } - - private Series AddSkyhookData(Series newSeries) - { - Tuple> tuple; - - try - { - tuple = _seriesInfo.GetSeriesInfo(newSeries.TvdbId); - } - catch (SeriesNotFoundException) - { - _logger.Error("tvdbid {1} was not found, it may have been removed from TheTVDB.", newSeries.TvdbId); - - throw new ValidationException(new List - { - new ValidationFailure("TvdbId", "A series with this ID was not found", newSeries.TvdbId) - }); - } - - var series = tuple.Item1; - - // If seasons were passed in on the new series use them, otherwise use the seasons from Skyhook - newSeries.Seasons = newSeries.Seasons != null && newSeries.Seasons.Any() ? newSeries.Seasons : series.Seasons; - - series.ApplyChanges(newSeries); - - return series; - } - private Series SetPropertiesAndValidate(Series newSeries) { if (string.IsNullOrWhiteSpace(newSeries.Path)) diff --git a/src/NzbDrone.Core/Tv/RefreshSeriesService.cs b/src/NzbDrone.Core/Tv/RefreshSeriesService.cs index 1706cb2ca..13f4c0fe9 100644 --- a/src/NzbDrone.Core/Tv/RefreshSeriesService.cs +++ b/src/NzbDrone.Core/Tv/RefreshSeriesService.cs @@ -18,101 +18,28 @@ namespace NzbDrone.Core.Tv { public class RefreshSeriesService : IExecute { - private readonly IProvideSeriesInfo _seriesInfo; private readonly ISeriesService _seriesService; private readonly IRefreshEpisodeService _refreshEpisodeService; private readonly IEventAggregator _eventAggregator; private readonly IDailySeriesService _dailySeriesService; private readonly IDiskScanService _diskScanService; - private readonly ICheckIfSeriesShouldBeRefreshed _checkIfSeriesShouldBeRefreshed; private readonly Logger _logger; - public RefreshSeriesService(IProvideSeriesInfo seriesInfo, - ISeriesService seriesService, + public RefreshSeriesService(ISeriesService seriesService, IRefreshEpisodeService refreshEpisodeService, IEventAggregator eventAggregator, IDailySeriesService dailySeriesService, IDiskScanService diskScanService, - ICheckIfSeriesShouldBeRefreshed checkIfSeriesShouldBeRefreshed, Logger logger) { - _seriesInfo = seriesInfo; _seriesService = seriesService; _refreshEpisodeService = refreshEpisodeService; _eventAggregator = eventAggregator; _dailySeriesService = dailySeriesService; _diskScanService = diskScanService; - _checkIfSeriesShouldBeRefreshed = checkIfSeriesShouldBeRefreshed; _logger = logger; } - private void RefreshSeriesInfo(Series series) - { - _logger.ProgressInfo("Updating {0}", series.Title); - - Tuple> tuple; - - try - { - tuple = _seriesInfo.GetSeriesInfo(series.TvdbId); - } - catch (SeriesNotFoundException) - { - _logger.Error("Series '{0}' (tvdbid {1}) was not found, it may have been removed from TheTVDB.", series.Title, series.TvdbId); - return; - } - - var seriesInfo = tuple.Item1; - - if (series.TvdbId != seriesInfo.TvdbId) - { - _logger.Warn("Series '{0}' (tvdbid {1}) was replaced with '{2}' (tvdbid {3}), because the original was a duplicate.", series.Title, series.TvdbId, seriesInfo.Title, seriesInfo.TvdbId); - series.TvdbId = seriesInfo.TvdbId; - } - - series.Title = seriesInfo.Title; - series.TitleSlug = seriesInfo.TitleSlug; - series.TvRageId = seriesInfo.TvRageId; - series.TvMazeId = seriesInfo.TvMazeId; - series.ImdbId = seriesInfo.ImdbId; - series.AirTime = seriesInfo.AirTime; - series.Overview = seriesInfo.Overview; - series.Status = seriesInfo.Status; - series.CleanTitle = seriesInfo.CleanTitle; - series.SortTitle = seriesInfo.SortTitle; - series.LastInfoSync = DateTime.UtcNow; - series.Runtime = seriesInfo.Runtime; - series.Images = seriesInfo.Images; - series.Network = seriesInfo.Network; - series.FirstAired = seriesInfo.FirstAired; - series.Ratings = seriesInfo.Ratings; - series.Actors = seriesInfo.Actors; - series.Genres = seriesInfo.Genres; - series.Certification = seriesInfo.Certification; - - if (_dailySeriesService.IsDailySeries(series.TvdbId)) - { - series.SeriesType = SeriesTypes.Daily; - } - - try - { - series.Path = new DirectoryInfo(series.Path).FullName; - series.Path = series.Path.GetActualCasing(); - } - catch (Exception e) - { - _logger.Warn(e, "Couldn't update series path for " + series.Path); - } - - series.Seasons = UpdateSeasons(series, seriesInfo); - - _seriesService.UpdateSeries(series); - _refreshEpisodeService.RefreshEpisodeInfo(series, tuple.Item2); - - _logger.Debug("Finished series refresh for {0}", series.Title); - _eventAggregator.PublishEvent(new SeriesUpdatedEvent(series)); - } private List UpdateSeasons(Series series, Series seriesInfo) { @@ -151,7 +78,6 @@ namespace NzbDrone.Core.Tv if (message.SeriesId.HasValue) { var series = _seriesService.GetSeries(message.SeriesId.Value); - RefreshSeriesInfo(series); } else { @@ -159,11 +85,11 @@ namespace NzbDrone.Core.Tv foreach (var series in allSeries) { - if (message.Trigger == CommandTrigger.Manual || _checkIfSeriesShouldBeRefreshed.ShouldRefresh(series)) + if (message.Trigger == CommandTrigger.Manual) { try { - RefreshSeriesInfo(series); + //RefreshSeriesInfo(series); } catch (Exception e) { diff --git a/src/NzbDrone.Core/Tv/ShouldRefreshSeries.cs b/src/NzbDrone.Core/Tv/ShouldRefreshSeries.cs deleted file mode 100644 index bbf48cbb8..000000000 --- a/src/NzbDrone.Core/Tv/ShouldRefreshSeries.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Linq; -using NLog; - -namespace NzbDrone.Core.Tv -{ - public interface ICheckIfSeriesShouldBeRefreshed - { - bool ShouldRefresh(Series series); - } - - public class ShouldRefreshSeries : ICheckIfSeriesShouldBeRefreshed - { - private readonly IEpisodeService _episodeService; - private readonly Logger _logger; - - public ShouldRefreshSeries(IEpisodeService episodeService, Logger logger) - { - _episodeService = episodeService; - _logger = logger; - } - - public bool ShouldRefresh(Series series) - { - if (series.LastInfoSync < DateTime.UtcNow.AddDays(-30)) - { - _logger.Trace("Series {0} last updated more than 30 days ago, should refresh.", series.Title); - return true; - } - - if (series.LastInfoSync >= DateTime.UtcNow.AddHours(-6)) - { - _logger.Trace("Series {0} last updated less than 6 hours ago, should not be refreshed.", series.Title); - return false; - } - - if (series.Status == SeriesStatusType.Continuing) - { - _logger.Trace("Series {0} is continuing, should refresh.", series.Title); - return true; - } - - var lastEpisode = _episodeService.GetEpisodeBySeries(series.Id).OrderByDescending(e => e.AirDateUtc).FirstOrDefault(); - - if (lastEpisode != null && lastEpisode.AirDateUtc > DateTime.UtcNow.AddDays(-30)) - { - _logger.Trace("Last episode in {0} aired less than 30 days ago, should refresh.", series.Title); - return true; - } - - _logger.Trace("Series {0} ended long ago, should not be refreshed.", series.Title); - return false; - } - } -}