mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-10-30 23:42:33 +01:00
Merge branch 'master' of git://github.com/kayone/NzbDrone
This commit is contained in:
commit
7b5556199f
@ -166,7 +166,7 @@ namespace Migrator.Providers
|
|||||||
|
|
||||||
public virtual string Default(object defaultValue)
|
public virtual string Default(object defaultValue)
|
||||||
{
|
{
|
||||||
if (defaultValue is String && defaultValue == String.Empty)
|
if (defaultValue is String && defaultValue.ToString() == String.Empty)
|
||||||
{
|
{
|
||||||
defaultValue = "''";
|
defaultValue = "''";
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,123 @@ namespace NzbDrone.Core.Test
|
|||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
public class EpisodeProviderTest : TestBase
|
public class EpisodeProviderTest : TestBase
|
||||||
{
|
{
|
||||||
|
[Test]
|
||||||
|
public void GetEpisodes_exists()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
var db = MockLib.GetEmptyDatabase();
|
||||||
|
mocker.SetConstant(db);
|
||||||
|
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew().Build();
|
||||||
|
var fakeEpisodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
.WhereAll().Have(e => e.SeriesId = 1).Build();
|
||||||
|
|
||||||
|
|
||||||
|
db.InsertMany(fakeEpisodes);
|
||||||
|
|
||||||
|
mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(p => p.GetSeries(1))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var episode = mocker.Resolve<EpisodeProvider>().GetEpisode(1);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
episode.ShouldHave().AllPropertiesBut(e => e.Series).EqualTo(fakeEpisodes.First());
|
||||||
|
episode.Series.ShouldHave().AllProperties().EqualTo(fakeSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Sequence contains no elements")]
|
||||||
|
public void GetEpisodes_invalid_series()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
var db = MockLib.GetEmptyDatabase();
|
||||||
|
mocker.SetConstant(db);
|
||||||
|
|
||||||
|
mocker.Resolve<SeriesProvider>();
|
||||||
|
|
||||||
|
var fakeEpisodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
.WhereAll().Have(e => e.SeriesId = 1).Build();
|
||||||
|
|
||||||
|
|
||||||
|
db.InsertMany(fakeEpisodes);
|
||||||
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
mocker.Resolve<EpisodeProvider>().GetEpisode(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AttachSeries_empty_list()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var result = mocker.Resolve<EpisodeProvider>().AttachSeries(new List<Episode>());
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
result.Should().HaveCount(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AttachSeries_list_success()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew().With(s => s.SeriesId = 12).Build();
|
||||||
|
var fakeEpisodes = Builder<Episode>.CreateListOfSize(5)
|
||||||
|
.WhereAll().Have(e => e.SeriesId = 12).Build();
|
||||||
|
|
||||||
|
mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(c => c.GetSeries(12))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
|
||||||
|
fakeEpisodes.Should().OnlyContain(e => e.Series == null);
|
||||||
|
var returnedSeries = mocker.Resolve<EpisodeProvider>().AttachSeries(fakeEpisodes);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
fakeEpisodes.Should().OnlyContain(e => e.Series == fakeSeries);
|
||||||
|
returnedSeries.Should().BeEquivalentTo(fakeEpisodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AttachSeries_single_success()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew().With(s => s.SeriesId = 12).Build();
|
||||||
|
var fakeEpisodes = Builder<Episode>.CreateNew().With(e => e.SeriesId = 12).Build();
|
||||||
|
|
||||||
|
mocker.GetMock<SeriesProvider>()
|
||||||
|
.Setup(c => c.GetSeries(12))
|
||||||
|
.Returns(fakeSeries);
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var returnedEpisode = mocker.Resolve<EpisodeProvider>().AttachSeries(fakeEpisodes);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
fakeEpisodes.Series.Should().Be(fakeSeries);
|
||||||
|
returnedEpisode.Should().Be(fakeEpisodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
[ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Sequence contains no elements")]
|
||||||
|
public void AttachSeries_single_invalid_series()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.SetConstant(MockLib.GetEmptyDatabase());
|
||||||
|
mocker.Resolve<SeriesProvider>();
|
||||||
|
var fakeEpisodes = Builder<Episode>.CreateNew().With(e => e.SeriesId = 12).Build();
|
||||||
|
|
||||||
|
//Act
|
||||||
|
var returnedEpisode = mocker.Resolve<EpisodeProvider>().AttachSeries(fakeEpisodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void GetEpisodesBySeason_success()
|
public void GetEpisodesBySeason_success()
|
||||||
@ -311,7 +428,7 @@ namespace NzbDrone.Core.Test
|
|||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
episodes.ToList().ForEach(c => db.Insert(c));
|
episodes.ToList().ForEach(c => db.Insert(c));
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
var result = mocker.Resolve<EpisodeProvider>().IsIgnored(10, 2);
|
var result = mocker.Resolve<EpisodeProvider>().IsIgnored(10, 2);
|
||||||
|
|
||||||
|
@ -26,8 +26,6 @@ namespace NzbDrone.Core.Test
|
|||||||
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var episodes = Builder<Episode>.CreateListOfSize(10).Build();
|
|
||||||
|
|
||||||
var notification = new ProgressNotification("Test");
|
var notification = new ProgressNotification("Test");
|
||||||
|
|
||||||
var mocker = new AutoMoqer(MockBehavior.Strict);
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
@ -39,23 +37,21 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
mocker.GetMock<DiskScanJob>()
|
mocker.GetMock<DiskScanJob>()
|
||||||
.Setup(j => j.Start(notification, series[0].SeriesId))
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
.Callback(() => series[0].LastDiskSync = DateTime.Now)
|
.Callback(() => series[0].LastDiskSync = DateTime.Now);
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
mocker.GetMock<DiskScanJob>()
|
mocker.GetMock<DiskScanJob>()
|
||||||
.Setup(j => j.Start(notification, series[1].SeriesId))
|
.Setup(j => j.Start(notification, series[1].SeriesId))
|
||||||
.Callback(() => series[1].LastDiskSync = DateTime.Now)
|
.Callback(() => series[1].LastDiskSync = DateTime.Now);
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
mocker.GetMock<UpdateInfoJob>()
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
.Setup(j => j.Start(notification, series[0].SeriesId))
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
.Callback(() => series[0].LastInfoSync = DateTime.Now)
|
.Callback(() => series[0].LastInfoSync = DateTime.Now);
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
mocker.GetMock<UpdateInfoJob>()
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
.Setup(j => j.Start(notification, series[1].SeriesId))
|
.Setup(j => j.Start(notification, series[1].SeriesId))
|
||||||
.Callback(() => series[1].LastInfoSync = DateTime.Now)
|
.Callback(() => series[1].LastInfoSync = DateTime.Now);
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
mocker.GetMock<SeriesProvider>()
|
||||||
.Setup(s => s.GetSeries(series[0].SeriesId)).Returns(series[0]);
|
.Setup(s => s.GetSeries(series[0].SeriesId)).Returns(series[0]);
|
||||||
@ -63,13 +59,6 @@ namespace NzbDrone.Core.Test
|
|||||||
mocker.GetMock<SeriesProvider>()
|
mocker.GetMock<SeriesProvider>()
|
||||||
.Setup(s => s.GetSeries(series[1].SeriesId)).Returns(series[1]);
|
.Setup(s => s.GetSeries(series[1].SeriesId)).Returns(series[1]);
|
||||||
|
|
||||||
|
|
||||||
mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(s => s.GetEpisodeBySeries(series[0].SeriesId)).Returns(episodes);
|
|
||||||
|
|
||||||
mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(s => s.GetEpisodeBySeries(series[1].SeriesId)).Returns(episodes);
|
|
||||||
|
|
||||||
mocker.GetMock<MediaFileProvider>()
|
mocker.GetMock<MediaFileProvider>()
|
||||||
.Setup(s => s.GetSeriesFiles(It.IsAny<int>())).Returns(new List<EpisodeFile>());
|
.Setup(s => s.GetSeriesFiles(It.IsAny<int>())).Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
@ -78,6 +67,13 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
mocker.VerifyAllMocks();
|
mocker.VerifyAllMocks();
|
||||||
|
|
||||||
|
mocker.GetMock<DiskScanJob>().Verify(j => j.Start(notification, series[0].SeriesId), Times.Once());
|
||||||
|
mocker.GetMock<DiskScanJob>().Verify(j => j.Start(notification, series[1].SeriesId), Times.Once());
|
||||||
|
|
||||||
|
mocker.GetMock<UpdateInfoJob>().Verify(j => j.Start(notification, series[0].SeriesId), Times.Once());
|
||||||
|
mocker.GetMock<UpdateInfoJob>().Verify(j => j.Start(notification, series[1].SeriesId), Times.Once());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -93,8 +89,6 @@ namespace NzbDrone.Core.Test
|
|||||||
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
.AndTheNext(1).Has(s => s.SeriesId = 15)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var episodes = Builder<Episode>.CreateListOfSize(10).Build();
|
|
||||||
|
|
||||||
var notification = new ProgressNotification("Test");
|
var notification = new ProgressNotification("Test");
|
||||||
|
|
||||||
var mocker = new AutoMoqer(MockBehavior.Strict);
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
@ -105,18 +99,15 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
mocker.GetMock<UpdateInfoJob>()
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
.Setup(j => j.Start(notification, series[0].SeriesId))
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
.Callback(() => series[0].LastInfoSync = DateTime.Now)
|
.Callback(() => series[0].LastInfoSync = DateTime.Now);
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
mocker.GetMock<UpdateInfoJob>()
|
mocker.GetMock<UpdateInfoJob>()
|
||||||
.Setup(j => j.Start(notification, series[1].SeriesId))
|
.Setup(j => j.Start(notification, series[1].SeriesId))
|
||||||
.Throws(new InvalidOperationException())
|
.Throws(new InvalidOperationException());
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
mocker.GetMock<DiskScanJob>()
|
mocker.GetMock<DiskScanJob>()
|
||||||
.Setup(j => j.Start(notification, series[0].SeriesId))
|
.Setup(j => j.Start(notification, series[0].SeriesId))
|
||||||
.Callback(() => series[0].LastDiskSync = DateTime.Now)
|
.Callback(() => series[0].LastDiskSync = DateTime.Now);
|
||||||
.AtMostOnce();
|
|
||||||
|
|
||||||
|
|
||||||
mocker.GetMock<SeriesProvider>()
|
mocker.GetMock<SeriesProvider>()
|
||||||
@ -125,17 +116,98 @@ namespace NzbDrone.Core.Test
|
|||||||
mocker.GetMock<MediaFileProvider>()
|
mocker.GetMock<MediaFileProvider>()
|
||||||
.Setup(s => s.GetSeriesFiles(It.IsAny<int>())).Returns(new List<EpisodeFile>());
|
.Setup(s => s.GetSeriesFiles(It.IsAny<int>())).Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
mocker.GetMock<EpisodeProvider>()
|
|
||||||
.Setup(s => s.GetEpisodeBySeries(It.IsAny<long>())).Returns(episodes);
|
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
mocker.Resolve<ImportNewSeriesJob>().Start(notification, 0);
|
mocker.Resolve<ImportNewSeriesJob>().Start(notification, 0);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
mocker.VerifyAllMocks();
|
mocker.VerifyAllMocks();
|
||||||
|
|
||||||
|
mocker.GetMock<UpdateInfoJob>().Verify(j => j.Start(notification, series[0].SeriesId), Times.Once());
|
||||||
|
mocker.GetMock<UpdateInfoJob>().Verify(j => j.Start(notification, series[1].SeriesId), Times.Once());
|
||||||
|
|
||||||
|
mocker.GetMock<DiskScanJob>().Verify(j => j.Start(notification, series[0].SeriesId), Times.Once());
|
||||||
|
|
||||||
ExceptionVerification.ExcpectedErrors(1);
|
ExceptionVerification.ExcpectedErrors(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AutoIgnoreSeason_new_series_should_not_ignore_any()
|
||||||
|
{
|
||||||
|
int seriesId = 12;
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(p => p.GetSeriesFiles(seriesId))
|
||||||
|
.Returns(new List<EpisodeFile>());
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(p => p.GetSeasons(seriesId))
|
||||||
|
.Returns(new List<int> { 0, 1, 2, 3, 4 });
|
||||||
|
|
||||||
|
mocker.Resolve<ImportNewSeriesJob>().AutoIgnoreSeasons(seriesId);
|
||||||
|
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>().Verify(p => p.SetSeasonIgnore(seriesId, It.IsAny<int>(), It.IsAny<Boolean>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AutoIgnoreSeason_existing_should_not_ignore_currentseason()
|
||||||
|
{
|
||||||
|
int seriesId = 12;
|
||||||
|
|
||||||
|
var episodesFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
|
.WhereAll().Have(e => e.SeriesId = seriesId)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
episodesFiles[0].SeasonNumber = 0;
|
||||||
|
episodesFiles[1].SeasonNumber = 1;
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer(MockBehavior.Strict);
|
||||||
|
|
||||||
|
mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(p => p.GetSeriesFiles(seriesId))
|
||||||
|
.Returns(episodesFiles);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(p => p.GetSeasons(seriesId))
|
||||||
|
.Returns(new List<int> { 0, 1, 2 });
|
||||||
|
|
||||||
|
mocker.Resolve<ImportNewSeriesJob>().AutoIgnoreSeasons(seriesId);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>().Verify(p => p.SetSeasonIgnore(seriesId, 2, It.IsAny<Boolean>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void AutoIgnoreSeason_existing_should_ignore_seasons_with_no_file()
|
||||||
|
{
|
||||||
|
int seriesId = 12;
|
||||||
|
|
||||||
|
var episodesFiles = Builder<EpisodeFile>.CreateListOfSize(2)
|
||||||
|
.WhereAll().Have(e => e.SeriesId = seriesId)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
episodesFiles[0].SeasonNumber = 1;
|
||||||
|
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
|
||||||
|
mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(p => p.GetSeriesFiles(seriesId))
|
||||||
|
.Returns(episodesFiles);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(p => p.GetSeasons(seriesId))
|
||||||
|
.Returns(new List<int> { 0, 1, 2 });
|
||||||
|
|
||||||
|
mocker.Resolve<ImportNewSeriesJob>().AutoIgnoreSeasons(seriesId);
|
||||||
|
|
||||||
|
mocker.GetMock<EpisodeProvider>().Verify(p => p.SetSeasonIgnore(seriesId, 0, true), Times.Once());
|
||||||
|
mocker.GetMock<EpisodeProvider>().Verify(p => p.SetSeasonIgnore(seriesId, 1, true), Times.Never());
|
||||||
|
mocker.GetMock<EpisodeProvider>().Verify(p => p.SetSeasonIgnore(seriesId, 2, It.IsAny<Boolean>()), Times.Never());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -106,6 +106,7 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
[ExpectedException(typeof(InvalidOperationException), ExpectedMessage = "Sequence contains no elements")]
|
||||||
public void Get_series_invalid_series_id_should_return_null()
|
public void Get_series_invalid_series_id_should_return_null()
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
|
@ -84,6 +84,21 @@ namespace NzbDrone.Core.Test
|
|||||||
Assert.IsNull(result);
|
Assert.IsNull(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void none_unique_season_episode_number()
|
||||||
|
{
|
||||||
|
//setup
|
||||||
|
var tvdbProvider = new TvDbProvider();
|
||||||
|
|
||||||
|
//act
|
||||||
|
var result = tvdbProvider.GetSeries(75978, true);//Family guy
|
||||||
|
|
||||||
|
//Asserts that when episodes are grouped by Season/Episode each group contains maximum of
|
||||||
|
//one item.
|
||||||
|
result.Episodes.GroupBy(e => e.SeasonNumber.ToString("000") + e.EpisodeNumber.ToString("000"))
|
||||||
|
.Max(e => e.Count()).Should().Be(1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void American_dad_fix()
|
public void American_dad_fix()
|
||||||
@ -97,11 +112,11 @@ namespace NzbDrone.Core.Test
|
|||||||
var seasonsNumbers = result.Episodes.Select(e => e.SeasonNumber)
|
var seasonsNumbers = result.Episodes.Select(e => e.SeasonNumber)
|
||||||
.Distinct().ToList();
|
.Distinct().ToList();
|
||||||
|
|
||||||
var seasons = new List<List<TvdbEpisode>>(seasonsNumbers.Count);
|
var seasons = new Dictionary<int, List<TvdbEpisode>>(seasonsNumbers.Count);
|
||||||
|
|
||||||
foreach (var season in seasonsNumbers)
|
foreach (var season in seasonsNumbers)
|
||||||
{
|
{
|
||||||
seasons.Insert(season, result.Episodes.Where(e => e.SeasonNumber == season).ToList());
|
seasons.Add(season, result.Episodes.Where(e => e.SeasonNumber == season).ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var episode in result.Episodes)
|
foreach (var episode in result.Episodes)
|
||||||
@ -119,16 +134,16 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
foreach (var season in seasons)
|
foreach (var season in seasons)
|
||||||
{
|
{
|
||||||
season.Should().OnlyHaveUniqueItems();
|
season.Value.Should().OnlyHaveUniqueItems();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Make sure no episode number is skipped
|
//Make sure no episode number is skipped
|
||||||
foreach (var season in seasons)
|
foreach (var season in seasons)
|
||||||
{
|
{
|
||||||
for (int i = 1; i < season.Count; i++)
|
for (int i = 1; i < season.Value.Count; i++)
|
||||||
{
|
{
|
||||||
season.Should().Contain(c => c.EpisodeNumber == i, "Can't find Episode S{0:00}E{1:00}",
|
season.Value.Should().Contain(c => c.EpisodeNumber == i, "Can't find Episode S{0:00}E{1:00}",
|
||||||
season[0].SeasonNumber, i);
|
season.Value[0].SeasonNumber, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ namespace NzbDrone.Core.Test
|
|||||||
private Episode tomorrow;
|
private Episode tomorrow;
|
||||||
private Episode twoDays;
|
private Episode twoDays;
|
||||||
private Episode sevenDays;
|
private Episode sevenDays;
|
||||||
private Episode eightDays;
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public new void Setup()
|
public new void Setup()
|
||||||
|
@ -8,13 +8,14 @@ using FluentAssertions;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Core.Providers;
|
using NzbDrone.Core.Providers;
|
||||||
using NzbDrone.Core.Repository;
|
using NzbDrone.Core.Repository;
|
||||||
|
using NzbDrone.Core.Repository.Quality;
|
||||||
using NzbDrone.Core.Test.Framework;
|
using NzbDrone.Core.Test.Framework;
|
||||||
|
using PetaPoco;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Test
|
namespace NzbDrone.Core.Test
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
// ReSharper disable InconsistentNaming
|
// ReSharper disable InconsistentNaming
|
||||||
[Ignore]
|
|
||||||
public class DbBenchmark : TestBase
|
public class DbBenchmark : TestBase
|
||||||
{
|
{
|
||||||
const int Episodes_Per_Season = 20;
|
const int Episodes_Per_Season = 20;
|
||||||
@ -22,6 +23,7 @@ namespace NzbDrone.Core.Test
|
|||||||
private readonly List<int> seriesIds = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
|
private readonly List<int> seriesIds = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
|
||||||
private readonly List<Episode> episodes = new List<Episode>();
|
private readonly List<Episode> episodes = new List<Episode>();
|
||||||
private readonly List<EpisodeFile> files = new List<EpisodeFile>();
|
private readonly List<EpisodeFile> files = new List<EpisodeFile>();
|
||||||
|
private IDatabase db;
|
||||||
|
|
||||||
|
|
||||||
[TestFixtureSetUp]
|
[TestFixtureSetUp]
|
||||||
@ -30,8 +32,18 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
|
|
||||||
base.Setup();
|
base.Setup();
|
||||||
|
db = MockLib.GetEmptyDatabase();
|
||||||
int currentFileId = 0;
|
int currentFileId = 0;
|
||||||
|
|
||||||
|
|
||||||
|
var qulityProfile = new QualityProfile
|
||||||
|
{
|
||||||
|
Name = "TestProfile",
|
||||||
|
Allowed = new List<QualityTypes> { QualityTypes.DVD, QualityTypes.Bluray1080p },
|
||||||
|
Cutoff = QualityTypes.DVD
|
||||||
|
};
|
||||||
|
db.Insert(qulityProfile);
|
||||||
|
|
||||||
foreach (var _seriesId in seriesIds)
|
foreach (var _seriesId in seriesIds)
|
||||||
{
|
{
|
||||||
int seriesId = _seriesId;
|
int seriesId = _seriesId;
|
||||||
@ -40,7 +52,7 @@ namespace NzbDrone.Core.Test
|
|||||||
.With(s => s.Monitored = true)
|
.With(s => s.Monitored = true)
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
//repo.Add(series);
|
db.Insert(series);
|
||||||
|
|
||||||
foreach (var _seasonNumber in seasonsNumbers)
|
foreach (var _seasonNumber in seasonsNumbers)
|
||||||
{
|
{
|
||||||
@ -52,8 +64,7 @@ namespace NzbDrone.Core.Test
|
|||||||
{
|
{
|
||||||
var epFile = Builder<EpisodeFile>.CreateNew()
|
var epFile = Builder<EpisodeFile>.CreateNew()
|
||||||
.With(e => e.SeriesId = seriesId)
|
.With(e => e.SeriesId = seriesId)
|
||||||
.With(e => e.SeriesId = seriesId)
|
.And(e => e.SeasonNumber = _seasonNumber)
|
||||||
.And(e => e.SeasonNumber = _seasonNumber)
|
|
||||||
.And(e => e.Path = Guid.NewGuid().ToString())
|
.And(e => e.Path = Guid.NewGuid().ToString())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
@ -83,30 +94,32 @@ namespace NzbDrone.Core.Test
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//repo.AddMany(episodes);
|
db.InsertMany(episodes);
|
||||||
//repo.AddMany(files);
|
db.InsertMany(files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void get_episode_by_series_seasons_episode_x5000()
|
public void get_episode_by_series_seasons_episode_x5000()
|
||||||
{
|
{
|
||||||
var epProvider = new EpisodeProvider(null, null);
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.SetConstant(db);
|
||||||
|
mocker.Resolve<SeriesProvider>();
|
||||||
|
|
||||||
|
var epProvider = mocker.Resolve<EpisodeProvider>();
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
|
|
||||||
var random = new Random();
|
var random = new Random();
|
||||||
Console.WriteLine("Starting Test");
|
Console.WriteLine("Starting Test");
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
for (int i = 0; i < 5000; i++)
|
for (int i = 0; i < 5000; i++)
|
||||||
{
|
{
|
||||||
epProvider.GetEpisode(6, random.Next(2, 5), random.Next(2, Episodes_Per_Season - 10)).Should().NotBeNull();
|
var ep = epProvider.GetEpisode(6, random.Next(2, 5), random.Next(2, Episodes_Per_Season - 10));
|
||||||
|
ep.Series.Should().NotBeNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
Console.WriteLine("Took " + sw.Elapsed);
|
Console.WriteLine("Took " + sw.Elapsed);
|
||||||
@ -115,7 +128,11 @@ namespace NzbDrone.Core.Test
|
|||||||
[Test]
|
[Test]
|
||||||
public void get_episode_by_series_seasons_x1000()
|
public void get_episode_by_series_seasons_x1000()
|
||||||
{
|
{
|
||||||
var epProvider = new EpisodeProvider( null, null);
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.SetConstant(db);
|
||||||
|
mocker.Resolve<SeriesProvider>();
|
||||||
|
|
||||||
|
var epProvider = mocker.Resolve<EpisodeProvider>();
|
||||||
|
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
@ -140,8 +157,9 @@ namespace NzbDrone.Core.Test
|
|||||||
public void get_episode_file_count_x100()
|
public void get_episode_file_count_x100()
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
//mocker.SetConstant(repo);
|
mocker.SetConstant(db);
|
||||||
mocker.SetConstant(mocker.Resolve<EpisodeProvider>());
|
mocker.Resolve<SeriesProvider>();
|
||||||
|
mocker.Resolve<EpisodeProvider>();
|
||||||
var mediaProvider = mocker.Resolve<MediaFileProvider>();
|
var mediaProvider = mocker.Resolve<MediaFileProvider>();
|
||||||
|
|
||||||
|
|
||||||
@ -163,12 +181,40 @@ namespace NzbDrone.Core.Test
|
|||||||
Console.WriteLine("Took " + sw.Elapsed);
|
Console.WriteLine("Took " + sw.Elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void get_season_count_x5000()
|
public void get_episode_file_count_x1000()
|
||||||
{
|
{
|
||||||
var mocker = new AutoMoqer();
|
var mocker = new AutoMoqer();
|
||||||
//mocker.SetConstant(repo);
|
mocker.SetConstant(db);
|
||||||
|
mocker.Resolve<SeriesProvider>();
|
||||||
|
mocker.Resolve<EpisodeProvider>();
|
||||||
|
var mediaProvider = mocker.Resolve<MediaFileProvider>();
|
||||||
|
|
||||||
|
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
|
||||||
|
|
||||||
|
var random = new Random();
|
||||||
|
Console.WriteLine("Starting Test");
|
||||||
|
|
||||||
|
var sw = Stopwatch.StartNew();
|
||||||
|
for (int i = 0; i < 1000; i++)
|
||||||
|
{
|
||||||
|
mediaProvider.GetEpisodeFilesCount(random.Next(1, 5)).Should().NotBeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sw.Stop();
|
||||||
|
|
||||||
|
Console.WriteLine("Took " + sw.Elapsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void get_season_count_x500()
|
||||||
|
{
|
||||||
|
var mocker = new AutoMoqer();
|
||||||
|
mocker.SetConstant(db);
|
||||||
var provider = mocker.Resolve<EpisodeProvider>();
|
var provider = mocker.Resolve<EpisodeProvider>();
|
||||||
|
|
||||||
|
|
||||||
@ -179,7 +225,7 @@ namespace NzbDrone.Core.Test
|
|||||||
Console.WriteLine("Starting Test");
|
Console.WriteLine("Starting Test");
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
var sw = Stopwatch.StartNew();
|
||||||
for (int i = 0; i < 5000; i++)
|
for (int i = 0; i < 500; i++)
|
||||||
{
|
{
|
||||||
provider.GetSeasons(random.Next(1, 10)).Should().HaveSameCount(seasonsNumbers);
|
provider.GetSeasons(random.Next(1, 10)).Should().HaveSameCount(seasonsNumbers);
|
||||||
}
|
}
|
||||||
@ -191,34 +237,6 @@ namespace NzbDrone.Core.Test
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void get_episode_file_count_x10()
|
|
||||||
{
|
|
||||||
var mocker = new AutoMoqer();
|
|
||||||
//mocker.SetConstant(repo);
|
|
||||||
mocker.SetConstant(mocker.Resolve<EpisodeProvider>());
|
|
||||||
var provider = mocker.Resolve<MediaFileProvider>();
|
|
||||||
|
|
||||||
|
|
||||||
Thread.Sleep(1000);
|
|
||||||
|
|
||||||
|
|
||||||
var random = new Random();
|
|
||||||
Console.WriteLine("Starting Test");
|
|
||||||
|
|
||||||
var sw = Stopwatch.StartNew();
|
|
||||||
for (int i = 0; i < 100; i++)
|
|
||||||
{
|
|
||||||
var result = provider.GetEpisodeFilesCount(random.Next(1, 10));
|
|
||||||
result.Item1.Should().NotBe(0);
|
|
||||||
result.Item2.Should().NotBe(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
sw.Stop();
|
|
||||||
|
|
||||||
Console.WriteLine("Took " + sw.Elapsed);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
24
NzbDrone.Core/Datastore/Migrations/Migration20110619.cs
Normal file
24
NzbDrone.Core/Datastore/Migrations/Migration20110619.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
using Migrator.Framework;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Datastore.Migrations
|
||||||
|
{
|
||||||
|
|
||||||
|
[Migration(20110619)]
|
||||||
|
public class Migration20110619 : Migration
|
||||||
|
{
|
||||||
|
public override void Up()
|
||||||
|
{
|
||||||
|
if (Database.TableExists("Histories"))
|
||||||
|
{
|
||||||
|
Database.RemoveTable("Histories");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Down()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -85,5 +85,31 @@ namespace NzbDrone.Core.Model
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
unchecked // Overflow is fine, just wrap
|
||||||
|
{
|
||||||
|
int hash = 17;
|
||||||
|
hash = hash * 23 + Proper.GetHashCode();
|
||||||
|
hash = hash * 23 + QualityType.GetHashCode();
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(Quality other)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, other)) return false;
|
||||||
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
return Equals(other.QualityType, QualityType) && other.Proper.Equals(Proper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, obj)) return false;
|
||||||
|
if (ReferenceEquals(this, obj)) return true;
|
||||||
|
if (obj.GetType() != typeof (Quality)) return false;
|
||||||
|
return Equals((Quality) obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,8 @@
|
|||||||
<Compile Include="Datastore\MigrationLogger.cs" />
|
<Compile Include="Datastore\MigrationLogger.cs" />
|
||||||
<Compile Include="Datastore\MigrationsHelper.cs" />
|
<Compile Include="Datastore\MigrationsHelper.cs" />
|
||||||
<Compile Include="Datastore\CustomeMapper.cs" />
|
<Compile Include="Datastore\CustomeMapper.cs" />
|
||||||
<Compile Include="Datastore\Migrations\Migration.cs" />
|
<Compile Include="Datastore\Migrations\Migration20110619.cs" />
|
||||||
|
<Compile Include="Datastore\Migrations\Migration20110616.cs" />
|
||||||
<Compile Include="Datastore\SqliteProvider.cs" />
|
<Compile Include="Datastore\SqliteProvider.cs" />
|
||||||
<Compile Include="Fluent.cs" />
|
<Compile Include="Fluent.cs" />
|
||||||
<Compile Include="Helpers\EpisodeRenameHelper.cs" />
|
<Compile Include="Helpers\EpisodeRenameHelper.cs" />
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
|
||||||
using Ninject;
|
using Ninject;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Core.Model;
|
using NzbDrone.Core.Model;
|
||||||
@ -15,12 +14,14 @@ namespace NzbDrone.Core.Providers
|
|||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
private readonly TvDbProvider _tvDbProvider;
|
private readonly TvDbProvider _tvDbProvider;
|
||||||
private readonly IDatabase _database;
|
private readonly IDatabase _database;
|
||||||
|
private readonly SeriesProvider _seriesProvider;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
public EpisodeProvider(TvDbProvider tvDbProviderProvider, IDatabase database)
|
public EpisodeProvider(IDatabase database, SeriesProvider seriesProvider, TvDbProvider tvDbProviderProvider)
|
||||||
{
|
{
|
||||||
_tvDbProvider = tvDbProviderProvider;
|
_tvDbProvider = tvDbProviderProvider;
|
||||||
_database = database;
|
_database = database;
|
||||||
|
_seriesProvider = seriesProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EpisodeProvider()
|
public EpisodeProvider()
|
||||||
@ -34,27 +35,27 @@ namespace NzbDrone.Core.Providers
|
|||||||
|
|
||||||
public virtual Episode GetEpisode(long id)
|
public virtual Episode GetEpisode(long id)
|
||||||
{
|
{
|
||||||
return _database.Single<Episode>(id);
|
return AttachSeries(_database.Single<Episode>(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber)
|
public virtual Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
return _database.SingleOrDefault<Episode>("WHERE SeriesId = @0 AND SeasonNumber = @1 AND EpisodeNumber = @2", seriesId, seasonNumber, episodeNumber);
|
return AttachSeries(_database.SingleOrDefault<Episode>("WHERE SeriesId = @0 AND SeasonNumber = @1 AND EpisodeNumber = @2", seriesId, seasonNumber, episodeNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Episode GetEpisode(int seriesId, DateTime date)
|
public virtual Episode GetEpisode(int seriesId, DateTime date)
|
||||||
{
|
{
|
||||||
return _database.SingleOrDefault<Episode>("WHERE SeriesId = @0 AND AirDate = @1", seriesId, date.Date);
|
return AttachSeries(_database.SingleOrDefault<Episode>("WHERE SeriesId = @0 AND AirDate = @1", seriesId, date.Date));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IList<Episode> GetEpisodeBySeries(long seriesId)
|
public virtual IList<Episode> GetEpisodeBySeries(long seriesId)
|
||||||
{
|
{
|
||||||
return _database.Fetch<Episode>("WHERE SeriesId = @0", seriesId);
|
return AttachSeries(_database.Fetch<Episode>("WHERE SeriesId = @0", seriesId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IList<Episode> GetEpisodesBySeason(long seriesId, int seasonNumber)
|
public virtual IList<Episode> GetEpisodesBySeason(long seriesId, int seasonNumber)
|
||||||
{
|
{
|
||||||
return _database.Fetch<Episode>("WHERE SeriesId = @0 AND SeasonNumber = @1", seriesId, seasonNumber);
|
return AttachSeries(_database.Fetch<Episode>("WHERE SeriesId = @0 AND SeasonNumber = @1", seriesId, seasonNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual List<Episode> GetEpisodes(EpisodeParseResult parseResult)
|
public virtual List<Episode> GetEpisodes(EpisodeParseResult parseResult)
|
||||||
@ -87,12 +88,12 @@ namespace NzbDrone.Core.Providers
|
|||||||
if (includeSpecials)
|
if (includeSpecials)
|
||||||
return episodes.Where(e => e.SeasonNumber > 0).ToList();
|
return episodes.Where(e => e.SeasonNumber > 0).ToList();
|
||||||
|
|
||||||
return episodes.ToList();
|
return AttachSeries(episodes.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IList<Episode> EpisodesByFileId(int episodeFileId)
|
public virtual IList<Episode> EpisodesByFileId(int episodeFileId)
|
||||||
{
|
{
|
||||||
return _database.Fetch<Episode>("WHERE EpisodeFileId = @0", episodeFileId);
|
return AttachSeries(_database.Fetch<Episode>("WHERE EpisodeFileId = @0", episodeFileId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RefreshEpisodeInfo(Series series)
|
public virtual void RefreshEpisodeInfo(Series series)
|
||||||
@ -219,5 +220,24 @@ namespace NzbDrone.Core.Providers
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IList<Episode> AttachSeries(IList<Episode> episodes)
|
||||||
|
{
|
||||||
|
if (episodes.Count == 0) return episodes;
|
||||||
|
|
||||||
|
if (episodes.Select(c => c.SeriesId).Distinct().Count() > 1)
|
||||||
|
throw new ArgumentException("Episodes belong to more than one series.");
|
||||||
|
|
||||||
|
var series = _seriesProvider.GetSeries(episodes.First().SeriesId);
|
||||||
|
episodes.ToList().ForEach(c => c.Series = series);
|
||||||
|
|
||||||
|
return episodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Episode AttachSeries(Episode episode)
|
||||||
|
{
|
||||||
|
episode.Series = _seriesProvider.GetSeries(episode.SeriesId);
|
||||||
|
return episode;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} |