Rewrite of InventoryProvider

pull/2/head
kay.one 13 years ago
parent f62b02a36b
commit 1239da656e

@ -10,8 +10,10 @@ using Moq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
// ReSharper disable InconsistentNaming
namespace NzbDrone.Core.Test
{
[TestFixture]
@ -23,10 +25,11 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
var parseResult = Builder<EpisodeParseResult>.CreateNew()
.With(e => e.Episodes = Builder<Episode>.CreateListOfSize(2)
.WhereTheFirst(1).Has(s => s.EpisodeId = 12)
.AndTheNext(1).Has(s => s.EpisodeId = 99)
.Build())
.Build();
.WhereTheFirst(1).Has(s => s.EpisodeId = 12)
.AndTheNext(1).Has(s => s.EpisodeId = 99)
.Build())
.With(c => c.Quality = new Quality(QualityTypes.DVD, false))
.Build();
const string sabTitle = "My fake sab title";
mocker.GetMock<SabProvider>()
@ -38,18 +41,18 @@ namespace NzbDrone.Core.Test
.Returns(true);
mocker.GetMock<SabProvider>()
.Setup(s => s.GetSabTitle(parseResult))
.Returns(sabTitle);
.Setup(s => s.GetSabTitle(parseResult))
.Returns(sabTitle);
mocker.GetMock<HistoryProvider>()
.Setup(s => s.Add(It.Is<History>(h=>h.EpisodeId == 12)));
.Setup(s => s.Add(It.Is<History>(h => h.EpisodeId == 12)));
mocker.GetMock<HistoryProvider>()
.Setup(s => s.Add(It.Is<History>(h => h.EpisodeId == 99)));
.Setup(s => s.Add(It.Is<History>(h => h.EpisodeId == 99)));
mocker.Resolve<DownloadProvider>().DownloadReport(parseResult);
mocker.VerifyAllMocks();
}
}
}
}

@ -21,7 +21,7 @@ namespace NzbDrone.Core.Test
public class EpisodeSearchJobTest : TestBase
{
[Test]
public void ParseResult_should_return_after_match()
public void processResults_ParseResult_should_return_after_match()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(5)
.Build();
@ -31,29 +31,31 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(true);
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Returns(true);
mocker.GetMock<DownloadProvider>()
.Setup(c => c.DownloadReport(It.IsAny<EpisodeParseResult>())).Returns(true);
//Act
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Once());
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.IsAny<EpisodeParseResult>()), Times.Once());
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Once());
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.IsAny<EpisodeParseResult>()),
Times.Once());
}
[Test]
public void higher_quality_should_be_called_first()
public void processResults_higher_quality_should_be_called_first()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(2)
.WhereTheFirst(1).Has(c => c.Quality = QualityTypes.Bluray1080p)
.AndTheNext(1).Has(c => c.Quality = QualityTypes.DVD)
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(10)
.WhereAll().Have(c => c.Quality = new Quality(QualityTypes.DVD, true))
.WhereRandom(1).Has(c => c.Quality = new Quality(QualityTypes.Bluray1080p, true))
.Build();
var episode = Builder<Episode>.CreateNew().Build();
@ -61,41 +63,48 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(parseResults[0])).Returns(true);
.Setup(
c =>
c.IsQualityNeeded(It.Is<EpisodeParseResult>(d => d.Quality.QualityType == QualityTypes.Bluray1080p)))
.Returns(true);
mocker.GetMock<DownloadProvider>()
.Setup(c => c.DownloadReport(parseResults[0])).Returns(true);
.Setup(
c =>
c.DownloadReport(It.Is<EpisodeParseResult>(d => d.Quality.QualityType == QualityTypes.Bluray1080p)))
.Returns(true);
//Act
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(parseResults[0]), Times.Once());
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(parseResults[0]), Times.Once());
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Once());
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.IsAny<EpisodeParseResult>()),
Times.Once());
}
[Test]
public void when_same_quality_proper_should_be_called_first()
public void processResults_when_same_quality_proper_should_be_called_first()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(20)
.WhereAll().Have(c => c.Quality = QualityTypes.DVD)
.And(c => c.Proper = false)
.WhereRandom(1).Has(c => c.Proper = true)
.WhereAll().Have(c => c.Quality = new Quality(QualityTypes.DVD, false))
.WhereRandom(1).Has(c => c.Quality = new Quality(QualityTypes.DVD, true))
.Build();
Assert.Count(1, parseResults.Where(c => c.Proper));
Assert.Count(1, parseResults.Where(c => c.Quality.Proper));
var episode = Builder<Episode>.CreateNew().Build();
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(It.Is<EpisodeParseResult>(p => p.Proper))).Returns(true);
.Setup(c => c.IsQualityNeeded(It.Is<EpisodeParseResult>(p => p.Quality.Proper))).Returns(true);
mocker.GetMock<DownloadProvider>()
.Setup(c => c.DownloadReport(It.Is<EpisodeParseResult>(p => p.Proper))).Returns(true);
.Setup(c => c.DownloadReport(It.Is<EpisodeParseResult>(p => p.Quality.Proper))).Returns(true);
//Act
@ -103,13 +112,15 @@ namespace NzbDrone.Core.Test
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.Is<EpisodeParseResult>(p => p.Proper)), Times.Once());
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.Is<EpisodeParseResult>(p => p.Proper)), Times.Once());
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Once());
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.IsAny<EpisodeParseResult>()),
Times.Once());
}
[Test]
public void when_not_needed_should_check_the_rest()
public void processResults_when_not_needed_should_check_the_rest()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
.Build();
@ -119,20 +130,21 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
//Act
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(4));
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Exactly(4));
ExceptionVerification.ExcpectedWarns(1);
}
[Test]
public void failed_IsNeeded_should_check_the_rest()
public void processResults_failed_IsNeeded_should_check_the_rest()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
.Build();
@ -142,34 +154,64 @@ namespace NzbDrone.Core.Test
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Throws(new Exception());
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Throws(new Exception());
//Act
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(4));
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Exactly(4));
ExceptionVerification.ExcpectedErrors(4);
ExceptionVerification.ExcpectedWarns(1);
}
[Test]
public void processResults_failed_download_should_not_check_the_rest()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
.Build();
var episode = Builder<Episode>.CreateNew().Build();
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>())).Returns(true);
mocker.GetMock<DownloadProvider>()
.Setup(c => c.DownloadReport(It.IsAny<EpisodeParseResult>())).Throws(new Exception());
//Act
mocker.Resolve<EpisodeSearchJob>().ProcessResults(new ProgressNotification("Test"), episode, parseResults);
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Exactly(1));
mocker.GetMock<DownloadProvider>().Verify(c => c.DownloadReport(It.IsAny<EpisodeParseResult>()),
Times.Exactly(1));
ExceptionVerification.ExcpectedErrors(1);
}
[Test]
[Row(0)]
[Row(-1)]
[Row(-100)]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void target_id_less_than_0_throws_exception(int target)
public void start_target_id_less_than_0_throws_exception(int target)
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), target);
}
[Test]
public void should_search_all_providers()
public void start_should_search_all_providers()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
.Build();
@ -201,7 +243,7 @@ namespace NzbDrone.Core.Test
.Returns(indexers);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
.Setup(c => c.IsQualityNeeded(It.Is<EpisodeParseResult>(d => d.Series != null && d.Episodes.Count != 0))).Returns(false);
//Act
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), episode.EpisodeId);
@ -209,7 +251,8 @@ namespace NzbDrone.Core.Test
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(8));
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Exactly(8));
ExceptionVerification.ExcpectedWarns(1);
indexer1.VerifyAll();
indexer2.VerifyAll();
@ -217,7 +260,7 @@ namespace NzbDrone.Core.Test
[Test]
public void failed_indexer_should_not_break_job()
public void start_failed_indexer_should_not_break_job()
{
var parseResults = Builder<EpisodeParseResult>.CreateListOfSize(4)
.Build();
@ -254,7 +297,7 @@ namespace NzbDrone.Core.Test
.Returns(indexers);
mocker.GetMock<InventoryProvider>()
.Setup(c => c.IsNeeded(It.IsAny<EpisodeParseResult>())).Returns(false);
.Setup(c => c.IsQualityNeeded(It.Is<EpisodeParseResult>(d => d.Series != null && d.Episodes.Count != 0))).Returns(false);
//Act
mocker.Resolve<EpisodeSearchJob>().Start(new ProgressNotification("Test"), episode.EpisodeId);
@ -262,7 +305,8 @@ namespace NzbDrone.Core.Test
//Assert
mocker.VerifyAllMocks();
mocker.GetMock<InventoryProvider>().Verify(c => c.IsNeeded(It.IsAny<EpisodeParseResult>()), Times.Exactly(8));
mocker.GetMock<InventoryProvider>().Verify(c => c.IsQualityNeeded(It.IsAny<EpisodeParseResult>()),
Times.Exactly(8));
ExceptionVerification.ExcpectedWarns(1);
ExceptionVerification.ExcpectedErrors(1);
@ -272,9 +316,8 @@ namespace NzbDrone.Core.Test
}
[Test]
public void no_episode_found_should_return_with_error_logged()
public void start_no_episode_found_should_return_with_error_logged()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
@ -290,6 +333,5 @@ namespace NzbDrone.Core.Test
mocker.VerifyAllMocks();
ExceptionVerification.ExcpectedErrors(1);
}
}
}
}

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using AutoMoq;
using FizzWare.NBuilder;
using MbUnit.Framework;
using Moq;
using NzbDrone.Core.Providers;
@ -59,6 +60,38 @@ namespace NzbDrone.Core.Test
}
[Test]
public void GetBestQualityInHistory_no_result()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.SetConstant(MockLib.GetEmptyRepository());
//Act
var result = mocker.Resolve<HistoryProvider>().GetBestQualityInHistory(12);
//Assert
Assert.IsNull(result);
}
[Test]
public void GetBestQualityInHistory_single_result()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
var repo = MockLib.GetEmptyRepository();
var history = Builder<History>.CreateNew().Build();
repo.Add(history);
mocker.SetConstant(repo);
//Act
var result = mocker.Resolve<HistoryProvider>().GetBestQualityInHistory(history.EpisodeId);
//Assert
Assert.IsNotNull(result);
}
[Test]
public void add_item()
{
@ -95,83 +128,6 @@ namespace NzbDrone.Core.Test
Assert.AreEqual(history.Indexer, newHistiory.Indexer);
}
[Test]
[Ignore]
public void Exists_True()
{
//Todo: This test fails... Moq Setup doesn't return the expected value
//Setup
var season = new Season { SeasonId = 4321, SeasonNumber = 1, SeriesId = 5656, Monitored = true };
var episode = new Episode
{
AirDate = DateTime.Today.AddDays(-1),
EpisodeId = 1234,
EpisodeNumber = 5,
Overview = "This is an Overview",
SeasonNumber = 1,
SeasonId = 4321,
Season = season,
SeriesId = 5656
};
var proper = false;
var repo = new Mock<IRepository>();
repo.Setup(r => r.Exists<History>(h => h.EpisodeId == episode.EpisodeId && h.IsProper == proper)).Returns(
true);
var target = new HistoryProvider(repo.Object);
//Act
var result = target.Exists(episode.EpisodeId, QualityTypes.SDTV, false);
//Assert
Assert.AreEqual(result, true);
}
[Test]
[Ignore]
public void Exists_False()
{
//Todo: This test fails... Moq Setup doesn't return the expected value
//Setup
var season = new Season { SeasonId = 4321, SeasonNumber = 1, SeriesId = 5656, Monitored = true };
var episode = new Episode
{
AirDate = DateTime.Today.AddDays(-1),
EpisodeId = 1234,
EpisodeNumber = 5,
Overview = "This is an Overview",
SeasonNumber = 1,
SeasonId = 4321,
Season = season,
SeriesId = 5656
};
var list = new List<History>
{
new History
{
HistoryId = new int(),
Date = DateTime.Now,
IsProper = false,
Quality = QualityTypes.SDTV,
EpisodeId = episode.EpisodeId
}
};
var repo = new Mock<IRepository>();
repo.Setup(r => r.Exists<History>(h => h.Episode == episode && h.IsProper == list[0].IsProper)).Returns(
false);
var target = new HistoryProvider(repo.Object);
//Act
var result = target.Exists(episode.EpisodeId, QualityTypes.SDTV, true);
//Assert
Assert.AreEqual(result, false);
}
}
}

@ -156,7 +156,7 @@ namespace NzbDrone.Core.Test
protected override Model.EpisodeParseResult CustomParser(SyndicationItem item, Model.EpisodeParseResult currentResult)
{
if (currentResult == null) currentResult = new EpisodeParseResult();
currentResult.EpisodeTitle = item.Summary.Text;
currentResult.Language = LanguageType.Finnish;
return currentResult;
}
}

@ -10,6 +10,7 @@ using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
using Moq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.Indexer;
@ -114,10 +115,10 @@ namespace NzbDrone.Core.Test
var result = mocker.Resolve<CustomParserIndexer>().ParseFeed(fakeRssItem);
Assert.IsNotNull(result);
Assert.AreEqual(summary, result.EpisodeTitle);
Assert.AreEqual(LanguageType.Finnish, result.Language);
Assert.AreEqual(season, result.SeasonNumber);
Assert.AreEqual(episode, result.EpisodeNumbers[0]);
Assert.AreEqual(quality, result.Quality);
Assert.AreEqual(quality, result.Quality.QualityType);
}
@ -142,7 +143,7 @@ namespace NzbDrone.Core.Test
var result = mocker.Resolve<CustomParserIndexer>().ParseFeed(fakeRssItem);
Assert.IsNotNull(result);
Assert.AreEqual(summary, result.EpisodeTitle);
Assert.AreEqual(LanguageType.Finnish, result.Language);
ExceptionVerification.ExcpectedWarns(1);
}

@ -1,430 +0,0 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.ServiceModel.Syndication;
using AutoMoq;
using FizzWare.NBuilder;
using MbUnit.Framework;
using Moq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.ExternalNotification;
using NzbDrone.Core.Providers.Indexer;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class InventoryProviderTest : TestBase
{
private EpisodeParseResult parseResultMulti;
private Series series;
private Episode episode;
private Episode episode2;
private EpisodeParseResult parseResultSingle;
[SetUp]
public new void Setup()
{
parseResultMulti = new EpisodeParseResult()
{
CleanTitle = "Title",
EpisodeTitle = "EpisodeTitle",
Language = LanguageType.English,
Proper = true,
Quality = QualityTypes.Bluray720p,
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
};
parseResultSingle = new EpisodeParseResult()
{
CleanTitle = "Title",
EpisodeTitle = "EpisodeTitle",
Language = LanguageType.English,
Proper = true,
Quality = QualityTypes.Bluray720p,
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date
};
series = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.Build();
episode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[0])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.Build();
episode2 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[1])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.Build();
base.Setup();
}
[Test]
public void not_monitored_series_should_be_skipped()
{
series.Monitored = false;
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void no_db_series_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns<Series>(null);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void unwannted_quality_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void ignored_season_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(true);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void unwannted_file_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode2.SeriesId, episode2.SeasonNumber, episode2.EpisodeNumber))
.Returns(episode2);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode2))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void file_in_history_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultSingle.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultSingle, episode))
.Returns(true);
mocker.GetMock<HistoryProvider>()
.Setup(p => p.Exists(episode.EpisodeId, parseResultSingle.Quality, parseResultSingle.Proper))
.Returns(true);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void dailyshow_should_do_daily_lookup()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns<Episode>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.AirDate))
.Returns(episode);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultSingle.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultSingle, episode))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void none_db_episode_should_be_added()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultSingle.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns<Episode>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.AirDate))
.Returns<Episode>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.AddEpisode(It.IsAny<Episode>()))
.Returns(12);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultSingle, It.IsAny<Episode>()))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void first_file_needed_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode2.SeriesId, episode2.SeasonNumber, episode2.EpisodeNumber))
.Returns(episode2);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode))
.Returns(true);
mocker.GetMock<HistoryProvider>()
.Setup(p => p.Exists(episode.EpisodeId, parseResultMulti.Quality, parseResultMulti.Proper))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsTrue(result);
Assert.Contains(parseResultMulti.Episodes, episode);
Assert.Contains(parseResultMulti.Episodes, episode2);
Assert.AreEqual(series, parseResultMulti.Series);
mocker.VerifyAllMocks();
}
[Test]
public void second_file_needed_should_return_true()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns(episode);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode2.SeriesId, episode2.SeasonNumber, episode2.EpisodeNumber))
.Returns(episode2);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.QualityWanted(series.SeriesId, parseResultMulti.Quality))
.Returns(true);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.IsNeeded(parseResultMulti, episode2))
.Returns(true);
mocker.GetMock<HistoryProvider>()
.Setup(p => p.Exists(episode2.EpisodeId, parseResultMulti.Quality, parseResultMulti.Proper))
.Returns(false);
//Act
var result = mocker.Resolve<InventoryProvider>().IsNeeded(parseResultMulti);
//Assert
Assert.IsTrue(result);
Assert.Contains(parseResultMulti.Episodes, episode);
Assert.Contains(parseResultMulti.Episodes, episode2);
Assert.AreEqual(series, parseResultMulti.Series);
mocker.VerifyAllMocks();
}
}
}

@ -0,0 +1,207 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.ServiceModel.Syndication;
using AutoMoq;
using FizzWare.NBuilder;
using MbUnit.Framework;
using Moq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Providers.ExternalNotification;
using NzbDrone.Core.Providers.Indexer;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class InventoryProvider_IsMonitoredTest : TestBase
{
private EpisodeParseResult parseResultMulti;
private Series series;
private Episode episode;
private Episode episode2;
private EpisodeParseResult parseResultSingle;
[SetUp]
public new void Setup()
{
parseResultMulti = new EpisodeParseResult()
{
CleanTitle = "Title",
Language = LanguageType.English,
Quality = new Quality(QualityTypes.Bluray720p, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date,
};
parseResultSingle = new EpisodeParseResult()
{
CleanTitle = "Title",
Language = LanguageType.English,
Quality = new Quality(QualityTypes.Bluray720p, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date,
};
episode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[0])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.With(c => c.Title = "EpisodeTitle1")
.Build();
episode2 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[1])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.With(c => c.Title = "EpisodeTitle2")
.Build();
series = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.Build();
base.Setup();
}
[Test]
public void not_monitored_series_should_be_skipped()
{
series.Monitored = false;
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
//Act
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultMulti);
//Assert
Assert.IsFalse(result);
Assert.AreSame(series, parseResultMulti.Series);
mocker.VerifyAllMocks();
}
[Test]
public void not_in_db_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns<Series>(null);
//Act
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void ignored_season_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultMulti.SeasonNumber))
.Returns(true);
//Act
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultMulti);
//Assert
Assert.IsFalse(result);
Assert.AreSame(series, parseResultMulti.Series);
mocker.VerifyAllMocks();
}
[Test]
public void IsMonitored_dailyshow_should_do_daily_lookup()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns<Episode>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.AirDate))
.Returns(episode);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultSingle);
//Assert
Assert.IsTrue(result);
Assert.AreSame(series, parseResultSingle.Series);
mocker.VerifyAllMocks();
}
[Test]
public void none_db_episode_should_be_added()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
mocker.GetMock<SeriesProvider>()
.Setup(p => p.FindSeries(It.IsAny<String>()))
.Returns(series);
mocker.GetMock<SeasonProvider>()
.Setup(p => p.IsIgnored(series.SeriesId, parseResultSingle.SeasonNumber))
.Returns(false);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.SeasonNumber, episode.EpisodeNumber))
.Returns<Episode>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.GetEpisode(episode.SeriesId, episode.AirDate))
.Returns<Episode>(null);
mocker.GetMock<EpisodeProvider>()
.Setup(p => p.AddEpisode(It.IsAny<Episode>()))
.Returns(12);
//Act
var result = mocker.Resolve<InventoryProvider>().IsMonitored(parseResultSingle);
//Assert
Assert.IsTrue(result);
Assert.AreSame(series, parseResultSingle.Series);
Assert.Count(1, parseResultSingle.Episodes);
Assert.AreEqual("TBD", parseResultSingle.Episodes[0].Title);
mocker.VerifyAllMocks();
}
}
}

@ -0,0 +1,234 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using AutoMoq;
using FizzWare.NBuilder;
using MbUnit.Framework;
using Moq;
using NzbDrone.Core.Model;
using NzbDrone.Core.Providers;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using NzbDrone.Core.Test.Framework;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class InventoryProvider_QualityNeededTest : TestBase
{
private Episode episode;
private Episode episode2;
private EpisodeFile episodeFile;
private QualityProfile hdProfile;
private EpisodeParseResult parseResultMulti;
private EpisodeParseResult parseResultSingle;
private QualityProfile sdProfile;
private Series series;
[SetUp]
public new void Setup()
{
parseResultMulti = new EpisodeParseResult
{
CleanTitle = "Title",
Language = LanguageType.English,
Quality = new Quality(QualityTypes.Bluray720p, true),
EpisodeNumbers = new List<int> { 3, 4 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date,
Episodes = new List<Episode>()
};
parseResultSingle = new EpisodeParseResult
{
CleanTitle = "Title",
Language = LanguageType.English,
Quality = new Quality(QualityTypes.Bluray720p, true),
EpisodeNumbers = new List<int> { 3 },
SeasonNumber = 12,
AirDate = DateTime.Now.AddDays(-12).Date,
Episodes = new List<Episode>()
};
episodeFile = Builder<EpisodeFile>.CreateNew().With(c => c.Quality = QualityTypes.DVD).Build();
episode = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[0])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.With(c => c.Title = "EpisodeTitle1")
.With(c => c.EpisodeFile = episodeFile)
.Build();
episode2 = Builder<Episode>.CreateNew()
.With(c => c.EpisodeNumber = parseResultMulti.EpisodeNumbers[1])
.With(c => c.SeasonNumber = parseResultMulti.SeasonNumber)
.With(c => c.AirDate = parseResultMulti.AirDate)
.With(c => c.Title = "EpisodeTitle2")
.With(c => c.EpisodeFile = episodeFile)
.Build();
sdProfile = new QualityProfile
{
Name = "SD",
Allowed = new List<QualityTypes> { QualityTypes.SDTV, QualityTypes.DVD },
Cutoff = QualityTypes.DVD
};
hdProfile = new QualityProfile
{
Name = "HD",
Allowed =
new List<QualityTypes>
{
QualityTypes.HDTV,
QualityTypes.WEBDL,
QualityTypes.Bluray720p,
QualityTypes.Bluray1080p
},
Cutoff = QualityTypes.Bluray720p
};
series = Builder<Series>.CreateNew()
.With(c => c.Monitored = true)
.With(d => d.CleanTitle = parseResultMulti.CleanTitle)
.With(c => c.QualityProfile = sdProfile)
.Build();
parseResultMulti.Series = series;
parseResultSingle.Series = series;
parseResultSingle.Episodes.Add(episode);
parseResultMulti.Episodes.Add(episode);
parseResultMulti.Episodes.Add(episode2);
base.Setup();
}
[Test]
public void IsQualityNeeded_report_not_in_quality_profile_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series.QualityProfile = sdProfile;
parseResultMulti.Quality = new Quality(QualityTypes.HDTV, true);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void IsQualityNeeded_file_already_at_cut_off_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultMulti.Series.QualityProfile = hdProfile;
parseResultMulti.Episodes[0].EpisodeFile.Quality = QualityTypes.Bluray720p;
parseResultMulti.Quality = new Quality(QualityTypes.HDTV, true);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultMulti);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void IsQualityNeeded_file_in_history_should_be_skipped()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series.QualityProfile = sdProfile;
parseResultSingle.Episodes[0].EpisodeFile.Quality = QualityTypes.SDTV;
parseResultSingle.Quality.QualityType = QualityTypes.DVD;
mocker.GetMock<HistoryProvider>()
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns(new Quality(QualityTypes.DVD, true));
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);
//Assert
Assert.IsFalse(result);
mocker.VerifyAllMocks();
}
[Test]
public void IsQualityNeeded_lesser_file_in_history_should_be_downloaded()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series.QualityProfile = sdProfile;
parseResultSingle.Episodes[0].EpisodeFile.Quality = QualityTypes.SDTV;
parseResultSingle.Quality.QualityType = QualityTypes.DVD;
mocker.GetMock<HistoryProvider>()
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns(new Quality(QualityTypes.SDTV, true));
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);
//Assert
Assert.IsTrue(result);
mocker.VerifyAllMocks();
}
[Test]
public void IsQualityNeeded_file_not_in_history_should_be_downloaded()
{
var mocker = new AutoMoqer(MockBehavior.Strict);
parseResultSingle.Series.QualityProfile = sdProfile;
parseResultSingle.Episodes[0].EpisodeFile.Quality = QualityTypes.SDTV;
parseResultSingle.Quality.QualityType = QualityTypes.DVD;
mocker.GetMock<HistoryProvider>()
.Setup(p => p.GetBestQualityInHistory(episode.EpisodeId))
.Returns<Quality>(null);
//Act
bool result = mocker.Resolve<InventoryProvider>().IsQualityNeeded(parseResultSingle);
//Assert
Assert.IsTrue(result);
mocker.VerifyAllMocks();
}
//Should Download
[Test]
[Row(QualityTypes.SDTV, true, QualityTypes.HDTV, false, true)]
[Row(QualityTypes.DVD, true, QualityTypes.Bluray720p, true, true)]
[Row(QualityTypes.HDTV, false, QualityTypes.HDTV, true, true)]
[Row(QualityTypes.HDTV, false, QualityTypes.HDTV, false, false)]
[Row(QualityTypes.Bluray720p, true, QualityTypes.Bluray1080p, false, false)]
[Row(QualityTypes.HDTV, true, QualityTypes.Bluray720p, true, true)]
[Row(QualityTypes.Bluray1080p, true, QualityTypes.Bluray720p, true, false)]
[Row(QualityTypes.Bluray1080p, true, QualityTypes.Bluray720p, false, false)]
[Row(QualityTypes.Bluray1080p, false, QualityTypes.Bluray720p, true, false)]
[Row(QualityTypes.HDTV, false, QualityTypes.Bluray720p, true, true)]
[Row(QualityTypes.HDTV, true, QualityTypes.HDTV, false, false)]
public void Is_upgrade(QualityTypes fileQuality, bool isFileProper, QualityTypes reportQuality,
bool isReportProper, bool excpected)
{
//Setup
var currentQuality = new Quality(fileQuality, isFileProper);
var newQuality = new Quality(reportQuality, isReportProper);
bool result = InventoryProvider.IsUpgrade(currentQuality, newQuality, QualityTypes.Bluray720p);
Assert.AreEqual(excpected, result);
}
}
}

@ -85,13 +85,14 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="InventoryProvider_IsMonitoredTest.cs" />
<Compile Include="DownloadProviderTest.cs" />
<Compile Include="EpisodeSearchJobTest.cs" />
<Compile Include="EpisodeStatusTest.cs" />
<Compile Include="ImportNewSeriesJobTest.cs" />
<Compile Include="DiskScanJobTest.cs" />
<Compile Include="IndexerTests.cs" />
<Compile Include="InventoryProviderTest.cs" />
<Compile Include="InventoryProvider_QualityNeededTest.cs" />
<Compile Include="Framework\AutoMoq\AutoMoqer.cs" />
<Compile Include="Framework\AutoMoq\AutoMoqerTest.cs" />
<Compile Include="Framework\AutoMoq\Unity\AutoMockingBuilderStrategy.cs">
@ -103,6 +104,7 @@
<Compile Include="Framework\ExceptionVerification.cs" />
<Compile Include="Framework\TestBase.cs" />
<Compile Include="JobProviderTest.cs" />
<Compile Include="QualityTest.cs" />
<Compile Include="RepositoryProviderTest.cs" />
<Compile Include="RootDirProviderTest.cs" />
<Compile Include="IndexerProviderTest.cs" />

@ -100,14 +100,14 @@ namespace NzbDrone.Core.Test
public void quality_parse(string postTitle, object quality)
{
var result = Parser.ParseQuality(postTitle);
Assert.AreEqual(quality, result);
Assert.AreEqual(quality, result.QualityType);
}
[Test]
public void parsing_our_own_quality_enum()
{
var qualityEnums = Enum.GetValues(typeof(QualityTypes));
foreach (var qualityEnum in qualityEnums)
{
@ -115,14 +115,14 @@ namespace NzbDrone.Core.Test
var extention = "mkv";
if (qualityEnum.ToString() ==QualityTypes.SDTV.ToString() || qualityEnum.ToString() ==QualityTypes.DVD.ToString())
if (qualityEnum.ToString() == QualityTypes.SDTV.ToString() || qualityEnum.ToString() == QualityTypes.DVD.ToString())
{
extention = "avi";
}
var fileName = String.Format("My series S01E01 [{0}].{1}", qualityEnum,extention);
var fileName = String.Format("My series S01E01 [{0}].{1}", qualityEnum, extention);
var result = Parser.ParseQuality(fileName);
Assert.AreEqual(qualityEnum, result);
Assert.AreEqual(qualityEnum, result.QualityType);
}
}

@ -0,0 +1,130 @@
using System;
using System.Collections.Generic;
using System.Text;
using Gallio.Framework;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
using NzbDrone.Core.Model;
using NzbDrone.Core.Repository.Quality;
namespace NzbDrone.Core.Test
{
[TestFixture]
// ReSharper disable InconsistentNaming
public class QualityTest
{
[Test]
public void Icomparer_greater_test()
{
var first = new Quality(QualityTypes.DVD, true);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.GreaterThan(second, first);
}
[Test]
public void Icomparer_greater_proper()
{
var first = new Quality(QualityTypes.Bluray1080p, false);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.GreaterThan(second, first);
}
[Test]
public void Icomparer_lesser()
{
var first = new Quality(QualityTypes.DVD, true);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.LessThan(first, second);
}
[Test]
public void Icomparer_lesser_proper()
{
var first = new Quality(QualityTypes.DVD, false);
var second = new Quality(QualityTypes.DVD, true);
Assert.LessThan(first, second);
}
[Test]
public void equal_operand()
{
var first = new Quality(QualityTypes.Bluray1080p, true);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.IsTrue(first == second);
Assert.IsTrue(first >= second);
Assert.IsTrue(first <= second);
}
[Test]
public void equal_operand_false()
{
var first = new Quality(QualityTypes.Bluray1080p, true);
var second = new Quality(QualityTypes.Unknown, true);
Assert.IsFalse(first == second);
}
[Test]
public void equal_operand_false_proper()
{
var first = new Quality(QualityTypes.Bluray1080p, true);
var second = new Quality(QualityTypes.Bluray1080p, false);
Assert.IsFalse(first == second);
}
[Test]
public void not_equal_operand()
{
var first = new Quality(QualityTypes.Bluray1080p, true);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.IsFalse(first != second);
}
[Test]
public void not_equal_operand_false()
{
var first = new Quality(QualityTypes.Bluray1080p, true);
var second = new Quality(QualityTypes.Unknown, true);
Assert.IsTrue(first != second);
}
[Test]
public void not_equal_operand_false_proper()
{
var first = new Quality(QualityTypes.Bluray1080p, true);
var second = new Quality(QualityTypes.Bluray1080p, false);
Assert.IsTrue(first != second);
}
[Test]
public void greater_operand()
{
var first = new Quality(QualityTypes.DVD, true);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.IsTrue(first < second);
Assert.IsTrue(first <= second);
}
[Test]
public void lesser_operand()
{
var first = new Quality(QualityTypes.DVD, true);
var second = new Quality(QualityTypes.Bluray1080p, true);
Assert.IsTrue(second > first);
Assert.IsTrue(second >= first);
}
}
}

@ -39,6 +39,36 @@ namespace NzbDrone.Core.Test
Assert.AreEqual(fetchedSeries.Episodes[0].Title, fakeEpisode.Title);
}
[Test]
public void ToString_test_over_castle_proxy()
{
//Arrange
var fakeSeries = Builder<Series>.CreateNew().With(s => s.SeriesId = 69).Build();
var fakeEpisode = Builder<Episode>.CreateNew().With(c => c.SeriesId = 69).Build();
//Act
var repo = MockLib.GetEmptyRepository(true);
repo.Add(fakeSeries);
repo.Add(fakeEpisode);
Console.WriteLine("Getting single");
var fetchedEpisode = repo.Single<Episode>(fakeEpisode.EpisodeId);
//Assert
Console.WriteLine("Doing assert");
Assert.AreEqual(fakeEpisode.EpisodeId, fetchedEpisode.EpisodeId);
Console.WriteLine("Doing assert");
Assert.AreEqual(fakeEpisode.Title, fetchedEpisode.Title);
Console.WriteLine("=======================");
var ttt= fetchedEpisode.Series;
Console.WriteLine("=======================");
var tttd= fetchedEpisode.Series;
Console.WriteLine("=======================");
//Assert.Contains(fetchedEpisode.ToString(), fakeSeries.Title);
}
[Test]
[Description(
"This test confirms that the tvdb id stored in the db is preserved rather than being replaced by an auto incrementing value"

@ -1,5 +1,6 @@
// ReSharper disable RedundantUsingDirective
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AutoMoq;
@ -226,17 +227,20 @@ namespace NzbDrone.Core.Test
.With(c => c.Path = @"d:\tv shows\My Series Name")
.Build();
var episode = Builder<Episode>.CreateNew()
.With(e => e.Title = title)
.Build();
var parsResult = new EpisodeParseResult()
{
AirDate = DateTime.Now,
EpisodeNumbers = episodes.ToList(),
Proper = proper,
Quality = quality,
Quality = new Quality(quality,proper),
SeasonNumber = seasons,
EpisodeTitle = title,
Series = series
Series = series,
Episodes = new List<Episode>() { episode }
};
//Act
var actual = mocker.Resolve<SabProvider>().GetSabTitle(parsResult);

@ -13,13 +13,9 @@ namespace NzbDrone.Core.Model
internal List<int> EpisodeNumbers { get; set; }
internal string EpisodeTitle { get; set; }
internal DateTime AirDate { get; set; }
public bool Proper { get; set; }
public QualityTypes Quality { get; set; }
public Quality Quality { get; set; }
public LanguageType Language { get; set; }
@ -36,10 +32,10 @@ namespace NzbDrone.Core.Model
public override string ToString()
{
if (EpisodeNumbers == null)
return string.Format("{0} - {1}", CleanTitle, AirDate.Date);
return string.Format("{0} - {1} {2}", CleanTitle, AirDate.ToShortDateString(), Quality);
return string.Format("{0} - S{1:00}E{2}", CleanTitle, SeasonNumber,
String.Join("-", EpisodeNumbers));
return string.Format("{0} - S{1:00}E{2} {3}", CleanTitle, SeasonNumber,
String.Join("-", EpisodeNumbers),Quality);
}
}

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NzbDrone.Core.Repository.Quality;
namespace NzbDrone.Core.Model
{
public class Quality : IComparable<Quality>
{
public QualityTypes QualityType { get; set; }
public Boolean Proper { get; set; }
public Quality() { }
public Quality(QualityTypes quality, Boolean proper)
{
QualityType = quality;
Proper = proper;
}
public int CompareTo(Quality other)
{
if (other.QualityType > this.QualityType)
return -1;
if (other.QualityType < this.QualityType)
return 1;
if (other.QualityType == this.QualityType && other.Proper == this.Proper)
return 0;
if (this.Proper && !other.Proper)
return 1;
if (!this.Proper && other.Proper)
return -1;
return 0;
}
public static bool operator !=(Quality x, Quality y)
{
return !(x == y);
}
public static bool operator ==(Quality x, Quality y)
{
var xObj = (Object)x;
var yObj = (object)y;
if (xObj == null || yObj == null)
{
return xObj == yObj;
}
return x.CompareTo(y) == 0;
}
public static bool operator >(Quality x, Quality y)
{
return x.CompareTo(y) > 0;
}
public static bool operator <(Quality x, Quality y)
{
return x.CompareTo(y) < 1;
}
public static bool operator <=(Quality x, Quality y)
{
return x.CompareTo(y) <= 0;
}
public static bool operator >=(Quality x, Quality y)
{
return x.CompareTo(y) >= 0;
}
public override string ToString()
{
string result = QualityType.ToString();
if (Proper)
{
result += " [proper]";
}
return result;
}
}
}

@ -8,7 +8,7 @@ namespace NzbDrone.Core.Model
internal int SeasonNumber { get; set; }
internal int Year { get; set; }
public QualityTypes Quality { get; set; }
public Quality Quality { get; set; }
public override string ToString()
{

@ -169,6 +169,7 @@
<Compile Include="Model\ConnectionInfoModel.cs" />
<Compile Include="Model\ExternalNotificationType.cs" />
<Compile Include="Model\LanguageType.cs" />
<Compile Include="Model\Quality.cs" />
<Compile Include="Model\SabnzbdInfoModel.cs" />
<Compile Include="Providers\DownloadProvider.cs" />
<Compile Include="Providers\ExternalNotification\ExternalNotificationProviderBase.cs" />

@ -65,7 +65,6 @@ namespace NzbDrone.Core
parsedEpisode = new EpisodeParseResult
{
Proper = title.ToLower().Contains("proper"),
CleanTitle = seriesName,
SeasonNumber = season,
EpisodeNumbers = new List<int>()
@ -99,7 +98,6 @@ namespace NzbDrone.Core
parsedEpisode = new EpisodeParseResult
{
Proper = title.ToLower().Contains("proper"),
CleanTitle = seriesName,
AirDate = new DateTime(airyear, airmonth, airday),
Language = ParseLanguage(simpleTitle)
@ -200,49 +198,65 @@ namespace NzbDrone.Core
return title.ToLower().Contains("proper");
}
internal static QualityTypes ParseQuality(string name)
internal static Quality ParseQuality(string name)
{
Logger.Trace("Trying to parse quality for {0}", name);
name = name.Trim();
var normilizedName = NormalizeTitle(name);
var result = QualityTypes.Unknown;
var result = new Quality { QualityType = QualityTypes.Unknown };
result.Proper = normilizedName.Contains("proper");
if (normilizedName.Contains("dvd") || normilizedName.Contains("bdrip") || normilizedName.Contains("brrip"))
{
return QualityTypes.DVD;
result.QualityType = QualityTypes.DVD;
return result;
}
if (normilizedName.Contains("xvid") || normilizedName.Contains("divx"))
{
if (normilizedName.Contains("bluray"))
{
return QualityTypes.DVD;
result.QualityType = QualityTypes.DVD;
return result;
}
return QualityTypes.SDTV;
result.QualityType = QualityTypes.SDTV;
return result;
}
if (normilizedName.Contains("bluray"))
{
if (normilizedName.Contains("720p"))
return QualityTypes.Bluray720p;
{
result.QualityType = QualityTypes.Bluray720p;
return result;
}
if (normilizedName.Contains("1080p"))
return QualityTypes.Bluray1080p;
{
result.QualityType = QualityTypes.Bluray1080p;
return result;
}
return QualityTypes.Bluray720p;
result.QualityType = QualityTypes.Bluray720p;
return result;
}
if (normilizedName.Contains("webdl"))
return QualityTypes.WEBDL;
{
result.QualityType = QualityTypes.WEBDL;
return result;
}
if (normilizedName.Contains("x264") || normilizedName.Contains("h264") || normilizedName.Contains("720p"))
return QualityTypes.HDTV;
{
result.QualityType = QualityTypes.HDTV;
return result;
}
//Based on extension
if (result == QualityTypes.Unknown)
if (result.QualityType == QualityTypes.Unknown)
{
try
{
@ -253,12 +267,12 @@ namespace NzbDrone.Core
case ".wmv":
case ".mp4":
{
result = QualityTypes.SDTV;
result.QualityType = QualityTypes.SDTV;
break;
}
case ".mkv":
{
result = QualityTypes.HDTV;
result.QualityType = QualityTypes.HDTV;
break;
}
}
@ -270,15 +284,18 @@ namespace NzbDrone.Core
}
}
if (normilizedName.Contains("sdtv") || (result == QualityTypes.Unknown && normilizedName.Contains("hdtv")))
if (normilizedName.Contains("sdtv") || (result.QualityType == QualityTypes.Unknown && normilizedName.Contains("hdtv")))
{
return QualityTypes.SDTV;
result.QualityType = QualityTypes.SDTV;
return result;
}
Logger.Trace("Quality Parsed:{0} Title:", result, name);
return result;
}
internal static LanguageType ParseLanguage(string title)
{
if (title.ToLower().Contains("english"))

@ -47,8 +47,8 @@ namespace NzbDrone.Core.Providers
var history = new History();
history.Date = DateTime.Now;
history.Indexer = parseResult.Indexer;
history.IsProper = parseResult.Proper;
history.Quality = parseResult.Quality;
history.IsProper = parseResult.Quality.Proper;
history.Quality = parseResult.Quality.QualityType;
history.NzbTitle = parseResult.NzbTitle;
history.EpisodeId = episode.EpisodeId;

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
using SubSonic.Repository;
@ -46,16 +47,11 @@ namespace NzbDrone.Core.Providers
Logger.Debug("Item added to history: {0}", item.NzbTitle);
}
public virtual bool Exists(int episodeId, QualityTypes quality, bool proper)
public virtual Quality GetBestQualityInHistory(long episodeId)
{
//Looks for the existence of this episode in History
if (_repository.Exists<History>(h => h.EpisodeId == episodeId && h.Quality == quality && h.IsProper == proper))
{
Logger.Debug("Episode in History. ID:{0} Q:{1} Proper:{2}", episodeId, quality, proper);
return true;
}
Logger.Debug("Episode not in History. ID:{0} Q:{1} Proper:{2}", episodeId, quality, proper);
return false;
var history = AllItems().Where(c => c.EpisodeId == episodeId).Select(d => new Quality() { QualityType = d.Quality, Proper = d.IsProper }).ToList();
history.Sort();
return history.FirstOrDefault();
}
public virtual void Delete(int historyId)

@ -53,10 +53,8 @@ namespace NzbDrone.Core.Providers.Indexer
if (currentResult != null)
{
var quality = Parser.ParseQuality(item.Summary.Text);
var proper = Parser.ParseProper(item.Summary.Text);
currentResult.Quality = quality;
currentResult.Proper = proper;
currentResult.Quality = quality;
}
return currentResult;
}

@ -3,6 +3,7 @@ using System.Collections.Generic;
using NLog;
using NzbDrone.Core.Model;
using NzbDrone.Core.Repository;
using NzbDrone.Core.Repository.Quality;
namespace NzbDrone.Core.Providers
{
@ -25,10 +26,11 @@ namespace NzbDrone.Core.Providers
public InventoryProvider()
{
}
public virtual bool IsNeeded(EpisodeParseResult parseResult)
public virtual bool IsMonitored(EpisodeParseResult parseResult)
{
var series = _seriesProvider.FindSeries(parseResult.CleanTitle);
@ -47,12 +49,6 @@ namespace NzbDrone.Core.Providers
return false;
}
if (!_seriesProvider.QualityWanted(series.SeriesId, parseResult.Quality))
{
Logger.Debug("Post doesn't meet the quality requirements [{0}]. skipping.", parseResult.Quality);
return false;
}
if (_seasonProvider.IsIgnored(series.SeriesId, parseResult.SeasonNumber))
{
Logger.Debug("Season {0} is currently set to ignore. skipping.", parseResult.SeasonNumber);
@ -76,7 +72,7 @@ namespace NzbDrone.Core.Providers
AirDate = DateTime.Now.Date,
EpisodeNumber = episodeNumber,
SeasonNumber = parseResult.SeasonNumber,
Title = parseResult.EpisodeTitle,
Title = "TBD",
Overview = String.Empty,
};
@ -86,34 +82,79 @@ namespace NzbDrone.Core.Providers
parseResult.Episodes.Add(episodeInfo);
}
foreach (var episode in parseResult.Episodes)
{
//Todo: How to handle full season files? Currently the episode list is completely empty for these releases
//Todo: Should we assume that the release contains all the episodes that belong to this season and add them from the DB?
//Todo: Fix this so it properly handles multi-epsiode releases (Currently as long as the first episode is needed we download it)
//Todo: for small releases this is less of an issue, but for Full Season Releases this could be an issue if we only need the first episode (or first few)
return true;
}
/// <summary>
/// Comprehensive check on whether or not this episode is needed.
/// </summary>
/// <param name = "parsedReport">Episode that needs to be checked</param>
/// <returns>Whether or not the file quality meets the requirements </returns>
/// <remarks>for multi episode files, all episodes need to meet the requirement
/// before the report is downloaded</remarks>
public virtual bool IsQualityNeeded(EpisodeParseResult parsedReport)
{
Logger.Trace("Checking if report meets quality requirements. {0}", parsedReport.Quality);
if (!parsedReport.Series.QualityProfile.Allowed.Contains(parsedReport.Quality.QualityType))
{
Logger.Trace("Quality {0} rejected by Series' quality profile", parsedReport.Quality);
return false;
}
var cutoff = parsedReport.Series.QualityProfile.Cutoff;
if (!_episodeProvider.IsNeeded(parseResult, episode))
foreach (var episode in parsedReport.Episodes)
{
//Checking File
var file = episode.EpisodeFile;
if (file != null)
{
Logger.Debug("Episode {0} is not needed. skipping.", parseResult);
continue;
Logger.Trace("Comparing file quality with report. Existing file is {0} proper:{1}", file.Quality, file.Proper);
if (!IsUpgrade(new Quality { QualityType = file.Quality, Proper = file.Proper }, parsedReport.Quality, cutoff))
return false;
}
if (_historyProvider.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper))
//Checking History
var bestQualityInHistory = _historyProvider.GetBestQualityInHistory(episode.EpisodeId);
if (bestQualityInHistory != null)
{
Logger.Debug("Episode {0} is in history. skipping.", parseResult);
continue;
Logger.Trace("Comparing history quality with report. History is {0}", bestQualityInHistory);
if (!IsUpgrade(bestQualityInHistory, parsedReport.Quality, cutoff))
return false;
}
//Congragulations younge feed item! you have made it this far. you are truly special!!!
Logger.Debug("Episode {0} is needed", parseResult);
}
Logger.Debug("Episode {0} is needed", parsedReport);
return true; //If we get to this point and the file has not yet been rejected then accept it
}
public static bool IsUpgrade(Quality currentQuality, Quality newQuality, QualityTypes cutOff)
{
if (currentQuality.QualityType >= cutOff)
{
Logger.Trace("Existing file meets cut-off. skipping.");
return false;
}
if (newQuality > currentQuality)
return true;
if (currentQuality > newQuality)
{
Logger.Trace("existing item has better quality. skipping");
return false;
}
if (currentQuality == newQuality && !newQuality.Proper)
{
Logger.Trace("same quality. not proper skipping");
return false;
}
return false;
Logger.Debug("New item has better quality than existing item");
return true;
}
}
}

@ -45,7 +45,7 @@ namespace NzbDrone.Core.Providers.Jobs
var episode = _episodeProvider.GetEpisode(targetId);
if (episode == null)
{
Logger.Error("Unbale to find an episode {0} in database", targetId);
Logger.Error("Unable to find an episode {0} in database", targetId);
return;
}
@ -80,19 +80,36 @@ namespace NzbDrone.Core.Providers.Jobs
Logger.Debug("Finished searching all indexers. Total {0}", reports.Count);
notification.CurrentMessage = "Processing search results";
reports.ForEach(c =>
{
c.Series = episode.Series;
c.Episodes = new List<Episode> { episode };
});
ProcessResults(notification, episode, reports);
}
public void ProcessResults(ProgressNotification notification, Episode episode, IEnumerable<EpisodeParseResult> reports)
{
foreach (var episodeParseResult in reports.OrderByDescending(c => c.Quality).ThenByDescending(c => c.Proper))
foreach (var episodeParseResult in reports.OrderByDescending(c => c.Quality))
{
try
{
if (_inventoryProvider.IsNeeded(episodeParseResult))
Logger.Trace("Analysing report " + episodeParseResult);
if (_inventoryProvider.IsQualityNeeded(episodeParseResult))
{
_downloadProvider.DownloadReport(episodeParseResult);
notification.CurrentMessage = String.Format("{0} {1} Added to download queue", episode, episodeParseResult.Quality);
Logger.Debug("Found '{0}'. Adding to download queue.", episodeParseResult);
try
{
_downloadProvider.DownloadReport(episodeParseResult);
notification.CurrentMessage = String.Format("{0} {1} Added to download queue", episode, episodeParseResult.Quality);
}
catch (Exception e)
{
Logger.ErrorException("Unable to add report to download queue." + episodeParseResult, e);
notification.CurrentMessage = String.Format("Unable to add report to download queue. {0}", episodeParseResult);
}
return;
}
}
@ -103,6 +120,7 @@ namespace NzbDrone.Core.Providers.Jobs
}
Logger.Warn("Unable to find {0} in any of indexers.", episode);
notification.CurrentMessage = String.Format("Unable to find {0} in any of indexers.", episode);
}
}
}

@ -49,18 +49,18 @@ namespace NzbDrone.Core.Providers.Jobs
}
catch (Exception e)
{
Logger.ErrorException("An error has occured while fetching items from " + indexer.Name, e);
Logger.ErrorException("An error has occurred while fetching items from " + indexer.Name, e);
}
}
Logger.Debug("Finished fetching reports from all indexers. Total {0}", reports.Count);
notification.CurrentMessage = "Proccessing downloaded RSS";
notification.CurrentMessage = "Processing downloaded RSS";
foreach (var episodeParseResult in reports)
{
try
{
if (_inventoryProvider.IsNeeded(episodeParseResult))
if (_inventoryProvider.IsMonitored(episodeParseResult) && _inventoryProvider.IsQualityNeeded(episodeParseResult))
{
_downloadProvider.DownloadReport(episodeParseResult);
}

@ -123,8 +123,8 @@ namespace NzbDrone.Core.Providers
episodeFile.SeriesId = series.SeriesId;
episodeFile.Path = Parser.NormalizePath(filePath);
episodeFile.Size = size;
episodeFile.Quality = parseResult.Quality;
episodeFile.Proper = Parser.ParseProper(filePath);
episodeFile.Quality = parseResult.Quality.QualityType;
episodeFile.Proper = parseResult.Quality.Proper;
var fileId = (int)_repository.Add(episodeFile);
//This is for logging + updating the episodes that are linked to this EpisodeFile

@ -105,9 +105,9 @@ namespace NzbDrone.Core.Providers
var epNumberString = String.Join("-", episodeString);
var result = String.Format("{0} - {1} - {2} [{3}]", new DirectoryInfo(parseResult.Series.Path).Name, epNumberString, parseResult.EpisodeTitle, parseResult.Quality);
var result = String.Format("{0} - {1} - {2} [{3}]", new DirectoryInfo(parseResult.Series.Path).Name, epNumberString, parseResult.Episodes.FirstOrDefault().Title, parseResult.Quality.QualityType);
if (parseResult.Proper)
if (parseResult.Quality.Proper)
{
result += " [Proper]";
}

@ -54,13 +54,6 @@ namespace NzbDrone.Core.Providers
return _repository.Exists<Series>(c => c.SeriesId == id && c.Monitored);
}
public virtual bool QualityWanted(int seriesId, QualityTypes quality)
{
var series = _repository.Single<Series>(seriesId);
Logger.Trace("Series {0} is using quality profile {1}", seriesId, series.QualityProfile.Name);
return series.QualityProfile.Allowed.Contains(quality);
}
public virtual TvdbSeries MapPathToSeries(string path)
{
var seriesPath = new DirectoryInfo(path);

@ -1,29 +1,30 @@
using System;
using System.Collections.Generic;
using Castle.DynamicProxy;
using NzbDrone.Core.Model;
using SubSonic.SqlGeneration.Schema;
namespace NzbDrone.Core.Repository
{
public class Episode
public class Episode
{
[SubSonicPrimaryKey]
public virtual int EpisodeId { get; set; }
public int? TvDbEpisodeId { get; set; }
public virtual int? TvDbEpisodeId { get; set; }
public virtual int SeriesId { get; set; }
public virtual int EpisodeFileId { get; set; }
public virtual int SeasonId { get; set; }
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public string Title { get; set; }
public DateTime AirDate { get; set; }
public virtual int SeasonNumber { get; set; }
public virtual int EpisodeNumber { get; set; }
public virtual string Title { get; set; }
public virtual DateTime AirDate { get; set; }
[SubSonicLongString]
public string Overview { get; set; }
public virtual string Overview { get; set; }
public Boolean Ignored { get; set; }
public virtual Boolean Ignored { get; set; }
[SubSonicIgnore]
public Boolean IsDailyEpisode
@ -41,7 +42,7 @@ namespace NzbDrone.Core.Repository
/// Used to specify when the episode was grapped.
/// this filed is used by status as an expirable "Grabbed" status.
/// </remarks>
public DateTime? GrabDate { get; set; }
public virtual DateTime? GrabDate { get; set; }
[SubSonicIgnore]
public EpisodeStatusType Status
@ -85,7 +86,7 @@ namespace NzbDrone.Core.Repository
if (IsDailyEpisode)
return string.Format("{0} - {1}", seriesTitle, AirDate.Date);
return string.Format("{0} - S{1:00}E{2}", seriesTitle, SeasonNumber, EpisodeNumber);
return string.Format("{0} - S{1:00}E{2:00}", seriesTitle, SeasonNumber, EpisodeNumber);
}
}

Loading…
Cancel
Save