Update Music Tests, Added Cases for Should Refresh Artist, Cleanup Skyhook Resources

pull/94/head
Qstick 7 years ago
parent d10fb92a09
commit 6e4638f7b1

@ -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<SeriesNotFoundException>(() => Subject.GetSeriesInfo(int.MaxValue));
Assert.Throws<ArtistNotFoundException>(() => 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<Episode> episodes)
private void ValidateAlbums(List<Album> 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();
}
}
}

@ -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<RefreshArtistService>
{
private Artist _artist;
[SetUp]
public void Setup()
{
var season1 = Builder<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "1")
.Build();
_artist = Builder<Artist>.CreateNew()
.With(s => s.Albums = new List<Album>
{
season1
})
.Build();
Mocker.GetMock<IArtistService>()
.Setup(s => s.GetArtist(_artist.Id))
.Returns(_artist);
Mocker.GetMock<IProvideArtistInfo>()
.Setup(s => s.GetArtistInfo(It.IsAny<string>()))
.Callback<string>(p => { throw new ArtistNotFoundException(p); });
}
private void GivenNewArtistInfo(Artist artist)
{
Mocker.GetMock<IProvideArtistInfo>()
.Setup(s => s.GetArtistInfo(_artist.ForeignArtistId))
.Returns(new Tuple<Artist, List<Album>>(artist, new List<Album>()));
}
[Test]
public void should_monitor_new_albums_automatically()
{
var newArtistInfo = _artist.JsonClone();
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "2")
.Build());
GivenNewArtistInfo(newArtistInfo);
Subject.Execute(new RefreshArtistCommand(_artist.Id));
Mocker.GetMock<IArtistService>()
.Verify(v => v.UpdateArtist(It.Is<Artist>(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<IArtistService>()
.Verify(v => v.UpdateArtist(It.IsAny<Artist>()), 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<IArtistService>()
.Verify(v => v.UpdateArtist(It.Is<Artist>(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<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "2")
.Build());
_artist.Albums.Add(Builder<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "2")
.Build());
_artist.Albums.Add(Builder<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "2")
.Build());
GivenNewArtistInfo(newArtistInfo);
Subject.Execute(new RefreshArtistCommand(_artist.Id));
Mocker.GetMock<IArtistService>()
.Verify(v => v.UpdateArtist(It.Is<Artist>(s => s.Albums.Count == 2)));
}
[Test]
public void should_filter_duplicate_albums()
{
var newArtistInfo = _artist.JsonClone();
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "2")
.Build());
newArtistInfo.Albums.Add(Builder<Album>.CreateNew()
.With(s => s.ForeignAlbumId = "2")
.Build());
GivenNewArtistInfo(newArtistInfo);
Subject.Execute(new RefreshArtistCommand(_artist.Id));
Mocker.GetMock<IArtistService>()
.Verify(v => v.UpdateArtist(It.Is<Artist>(s => s.Albums.Count == 2)));
}
}
}

@ -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<ShouldRefreshArtist>
{
private Artist _artist;
[SetUp]
public void Setup()
{
_artist = Builder<Artist>.CreateNew()
.With(v => v.Status == ArtistStatusType.Continuing)
.Build();
Mocker.GetMock<IAlbumService>()
.Setup(s => s.GetAlbumsByArtist(_artist.Id))
.Returns(Builder<Album>.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<IAlbumService>()
.Setup(s => s.GetAlbumsByArtist(_artist.Id))
.Returns(Builder<Album>.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();
}
}
}

@ -365,13 +365,13 @@
<Compile Include="TvTests\EpisodeRepositoryTests\FindEpisodeFixture.cs" />
<Compile Include="MusicTests\MoveArtistServiceFixture.cs" />
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />
<Compile Include="TvTests\RefreshSeriesServiceFixture.cs" />
<Compile Include="MusicTests\RefreshArtistServiceFixture.cs" />
<Compile Include="TvTests\EpisodeMonitoredServiceTests\SetEpisodeMontitoredFixture.cs" />
<Compile Include="TvTests\SeriesRepositoryTests\SeriesRepositoryFixture.cs" />
<Compile Include="TvTests\SeriesServiceTests\UpdateMultipleSeriesFixture.cs" />
<Compile Include="TvTests\SeriesServiceTests\UpdateSeriesFixture.cs" />
<Compile Include="TvTests\SeriesTitleNormalizerFixture.cs" />
<Compile Include="TvTests\ShouldRefreshSeriesFixture.cs" />
<Compile Include="MusicTests\ShouldRefreshArtistFixture.cs" />
<Compile Include="UpdateTests\UpdatePackageProviderFixture.cs" />
<Compile Include="UpdateTests\UpdateServiceFixture.cs" />
<Compile Include="XbmcVersionTests.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<SkyHookProxy>().GetSeriesInfo(121361);//Game of thrones
// _gameOfThrones = Mocker.Resolve<SkyHookProxy>().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);
}
}
}
}

@ -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<RefreshSeriesService>
{
private Series _series;
[SetUp]
public void Setup()
{
var season1 = Builder<Season>.CreateNew()
.With(s => s.SeasonNumber = 1)
.Build();
_series = Builder<Series>.CreateNew()
.With(s => s.Seasons = new List<Season>
{
season1
})
.Build();
Mocker.GetMock<ISeriesService>()
.Setup(s => s.GetSeries(_series.Id))
.Returns(_series);
Mocker.GetMock<IProvideSeriesInfo>()
.Setup(s => s.GetSeriesInfo(It.IsAny<int>()))
.Callback<int>(p => { throw new SeriesNotFoundException(p); });
}
private void GivenNewSeriesInfo(Series series)
{
Mocker.GetMock<IProvideSeriesInfo>()
.Setup(s => s.GetSeriesInfo(_series.TvdbId))
.Returns(new Tuple<Series, List<Episode>>(series, new List<Episode>()));
}
[Test]
public void should_monitor_new_seasons_automatically()
{
var newSeriesInfo = _series.JsonClone();
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
.With(s => s.SeasonNumber = 2)
.Build());
GivenNewSeriesInfo(newSeriesInfo);
Subject.Execute(new RefreshSeriesCommand(_series.Id));
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(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<Season>.CreateNew()
.With(s => s.SeasonNumber = 0)
.Build());
GivenNewSeriesInfo(series);
Subject.Execute(new RefreshSeriesCommand(_series.Id));
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(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<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(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<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.TvMazeId == newSeriesInfo.TvMazeId)));
}
[Test]
public void should_log_error_if_tvdb_id_not_found()
{
Subject.Execute(new RefreshSeriesCommand(_series.Id));
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.IsAny<Series>()), 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<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(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<Season>.CreateNew()
.With(s => s.SeasonNumber = 2)
.Build());
_series.Seasons.Add(Builder<Season>.CreateNew()
.With(s => s.SeasonNumber = 2)
.Build());
_series.Seasons.Add(Builder<Season>.CreateNew()
.With(s => s.SeasonNumber = 2)
.Build());
GivenNewSeriesInfo(newSeriesInfo);
Subject.Execute(new RefreshSeriesCommand(_series.Id));
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2)));
}
[Test]
public void should_filter_duplicate_seasons()
{
var newSeriesInfo = _series.JsonClone();
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
.With(s => s.SeasonNumber = 2)
.Build());
newSeriesInfo.Seasons.Add(Builder<Season>.CreateNew()
.With(s => s.SeasonNumber = 2)
.Build());
GivenNewSeriesInfo(newSeriesInfo);
Subject.Execute(new RefreshSeriesCommand(_series.Id));
Mocker.GetMock<ISeriesService>()
.Verify(v => v.UpdateSeries(It.Is<Series>(s => s.Seasons.Count == 2)));
}
}
}

@ -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<ShouldRefreshSeries>
{
private Series _series;
[SetUp]
public void Setup()
{
_series = Builder<Series>.CreateNew()
.With(v => v.Status == SeriesStatusType.Continuing)
.Build();
Mocker.GetMock<IEpisodeService>()
.Setup(s => s.GetEpisodeBySeries(_series.Id))
.Returns(Builder<Episode>.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<IEpisodeService>()
.Setup(s => s.GetEpisodeBySeries(_series.Id))
.Returns(Builder<Episode>.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();
}
}
}

@ -1,11 +0,0 @@
using System;
using System.Collections.Generic;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.MetadataSource
{
public interface IProvideSeriesInfo
{
Tuple<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId);
}
}

@ -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<string> Genres { get; set; }
public string AristUrl { get; set; }
public string Overview { get; set; }
public string Id { get; set; }
public List<ImageResource> Images { get; set; }
public string ArtistName { get; set; }
}
}

@ -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; }
}
}

@ -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; }
}
}
}

@ -1,15 +0,0 @@
using System.Collections.Generic;
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
{
public class SeasonResource
{
public SeasonResource()
{
Images = new List<ImageResource>();
}
public int SeasonNumber { get; set; }
public List<ImageResource> Images { get; set; }
}
}

@ -1,43 +0,0 @@
using System.Collections.Generic;
namespace NzbDrone.Core.MetadataSource.SkyHook.Resource
{
public class ShowResource
{
public ShowResource()
{
Actors = new List<ActorResource>();
Genres = new List<string>();
Images = new List<ImageResource>();
Seasons = new List<SeasonResource>();
Episodes = new List<EpisodeResource>();
}
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<ActorResource> Actors { get; set; }
public List<string> Genres { get; set; }
public string ContentRating { get; set; }
public RatingResource Rating { get; set; }
public List<ImageResource> Images { get; set; }
public List<SeasonResource> Seasons { get; set; }
public List<EpisodeResource> Episodes { get; set; }
}
}

@ -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<Series, List<Episode>> GetSeriesInfo(int tvdbSeriesId)
{
throw new NotImplementedException();
}
public Tuple<Artist, List<Album>> 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<MediaCover.MediaCover>
newMember.Images = new List<MediaCover.MediaCover>
{
new MediaCover.MediaCover(MediaCoverTypes.Headshot, arg.Image)
};
}
return newActor;
return newMember;
}
private static ArtistStatusType MapArtistStatus(string status)

@ -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;
}
}

@ -828,18 +828,13 @@
<Compile Include="Messaging\Events\IHandle.cs" />
<Compile Include="Messaging\IProcessMessage.cs" />
<Compile Include="MetadataSource\IProvideArtistInfo.cs" />
<Compile Include="MetadataSource\IProvideSeriesInfo.cs" />
<Compile Include="MetadataSource\ISearchForNewArtist.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\ActorResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\MemberResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\AlbumResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\ArtistInfoResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\ArtistResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\LinkResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\EpisodeResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\ImageResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\RatingResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\SeasonResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\ShowResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\TimeOfDayResource.cs" />
<Compile Include="MetadataSource\SkyHook\Resource\TrackResource.cs" />
<Compile Include="MetadataSource\SkyHook\SkyHookProxy.cs" />
@ -1191,7 +1186,6 @@
<Compile Include="Tv\SeriesTitleNormalizer.cs" />
<Compile Include="Tv\SeriesTitleSlugValidator.cs" />
<Compile Include="Tv\SeriesTypes.cs" />
<Compile Include="Tv\ShouldRefreshSeries.cs" />
<Compile Include="Update\Commands\ApplicationUpdateCommand.cs" />
<Compile Include="Update\InstallUpdateService.cs" />
<Compile Include="Update\RecentUpdateProvider.cs" />

@ -16,25 +16,21 @@ namespace NzbDrone.Core.Tv
public interface IAddSeriesService
{
Series AddSeries(Series newSeries);
List<Series> AddSeries(List<Series> 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<Series> AddSeries(List<Series> newSeries)
{
var added = DateTime.UtcNow;
var seriesToAdd = new List<Series>();
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<Series, List<Episode>> 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<ValidationFailure>
{
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))

@ -18,101 +18,28 @@ namespace NzbDrone.Core.Tv
{
public class RefreshSeriesService : IExecute<RefreshSeriesCommand>
{
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<Series, List<Episode>> 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<Season> 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)
{

@ -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;
}
}
}
Loading…
Cancel
Save