From ccbbad54cee408d05879cf57db184fb72e3ad0ec Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 22 Apr 2011 12:15:47 -0700 Subject: [PATCH 1/6] Added default mock behavior to automocker --- NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs | 21 +++++++++++++++---- .../Unity/AutoMockingBuilderStrategy.cs | 9 ++++---- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs b/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs index b5535fb24..91803a469 100644 --- a/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs +++ b/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs @@ -14,6 +14,7 @@ namespace AutoMoq { public class AutoMoqer { + internal readonly MockBehavior DefaultBehavior = MockBehavior.Default; internal Type ResolveType; private IUnityContainer container; private IDictionary registeredMocks; @@ -23,6 +24,13 @@ public AutoMoqer() SetupAutoMoqer(new UnityContainer()); } + public AutoMoqer(MockBehavior defaultBehavior) + { + DefaultBehavior = defaultBehavior; + SetupAutoMoqer(new UnityContainer()); + + } + internal AutoMoqer(IUnityContainer container) { SetupAutoMoqer(container); @@ -37,7 +45,12 @@ public virtual T Resolve() return result; } - public virtual Mock GetMock(MockBehavior behavior = MockBehavior.Default) where T : class + public virtual Mock GetMock() where T : class + { + return GetMock(DefaultBehavior); + } + + public virtual Mock GetMock(MockBehavior behavior) where T : class { ResolveType = null; var type = GetTheMockType(); @@ -112,10 +125,10 @@ public void VerifyAllMocks() private void SetupAutoMoqer(IUnityContainer container) { this.container = container; - registeredMocks = new Dictionary(); - - AddTheAutoMockingContainerExtensionToTheContainer(container); container.RegisterInstance(this); + + registeredMocks = new Dictionary(); + AddTheAutoMockingContainerExtensionToTheContainer(container); } private static void AddTheAutoMockingContainerExtensionToTheContainer(IUnityContainer container) diff --git a/NzbDrone.Core.Test/AutoMoq/Unity/AutoMockingBuilderStrategy.cs b/NzbDrone.Core.Test/AutoMoq/Unity/AutoMockingBuilderStrategy.cs index 26297916e..c89ab8491 100644 --- a/NzbDrone.Core.Test/AutoMoq/Unity/AutoMockingBuilderStrategy.cs +++ b/NzbDrone.Core.Test/AutoMoq/Unity/AutoMockingBuilderStrategy.cs @@ -16,7 +16,8 @@ internal class AutoMockingBuilderStrategy : BuilderStrategy public AutoMockingBuilderStrategy(IEnumerable registeredTypes, IUnityContainer container) { - mockFactory = new MockFactory(MockBehavior.Loose); + var autoMoqer = container.Resolve(); + mockFactory = new MockFactory(autoMoqer.DefaultBehavior); this.registeredTypes = registeredTypes; this.container = container; } @@ -62,19 +63,19 @@ private Mock CreateAMockObject(Type type) private Mock InvokeTheMockCreationMethod(MethodInfo createMethod) { - return (Mock) createMethod.Invoke(mockFactory, new object[] {new List().ToArray()}); + return (Mock)createMethod.Invoke(mockFactory, new object[] { new List().ToArray() }); } private MethodInfo GenerateAnInterfaceMockCreationMethod(Type type) { var createMethodWithNoParameters = mockFactory.GetType().GetMethod("Create", EmptyArgumentList()); - return createMethodWithNoParameters.MakeGenericMethod(new[] {type}); + return createMethodWithNoParameters.MakeGenericMethod(new[] { type }); } private static Type[] EmptyArgumentList() { - return new[] {typeof (object[])}; + return new[] { typeof(object[]) }; } #endregion From 23f6cc3901e01575fb75692208f5d279c89b5c92 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 22 Apr 2011 12:16:52 -0700 Subject: [PATCH 2/6] More tests --- NzbDrone.Core.Test/IndexerProviderTest.cs | 15 +- NzbDrone.Core.Test/MockLib.cs | 13 +- NzbDrone.Core.Test/ParserTest.cs | 136 ++++++++++++++---- NzbDrone.Core.Test/SeriesProviderTest.cs | 60 +++++++- NzbDrone.Core/Model/EpisodeParseResult.cs | 6 +- NzbDrone.Core/Parser.cs | 4 +- .../Providers/Indexer/IndexerProviderBase.cs | 12 +- NzbDrone.Core/Providers/SeriesProvider.cs | 3 +- NzbDrone/Program.cs | 4 + 9 files changed, 203 insertions(+), 50 deletions(-) diff --git a/NzbDrone.Core.Test/IndexerProviderTest.cs b/NzbDrone.Core.Test/IndexerProviderTest.cs index bd350e1df..11e7639f7 100644 --- a/NzbDrone.Core.Test/IndexerProviderTest.cs +++ b/NzbDrone.Core.Test/IndexerProviderTest.cs @@ -53,11 +53,24 @@ public void Init_indexer_test() //Assert Assert.Count(1, indexers); } + + [Test] + public void unmapped_series_shouldnt_call_any_providers() + { + var mocker = new AutoMoqer(MockBehavior.Strict); + mocker.GetMock() + .Setup(c => c.FindSeries(It.IsAny())) + .Returns(null); + + var indexer = mocker.Resolve(); + indexer.ProcessItem(new SyndicationItem { Title = new TextSyndicationContent("Adventure.Inc.S01E18.DVDRip.XviD-OSiTV") }); + } } public class MockIndexerProvider : IndexerProviderBase { - public MockIndexerProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, EpisodeProvider episodeProvider, ConfigProvider configProvider, HttpProvider httpProvider, IndexerProvider indexerProvider, HistoryProvider historyProvider) : base(seriesProvider, seasonProvider, episodeProvider, configProvider, httpProvider, indexerProvider, historyProvider) + public MockIndexerProvider(SeriesProvider seriesProvider, SeasonProvider seasonProvider, EpisodeProvider episodeProvider, ConfigProvider configProvider, HttpProvider httpProvider, IndexerProvider indexerProvider, HistoryProvider historyProvider) + : base(seriesProvider, seasonProvider, episodeProvider, configProvider, httpProvider, indexerProvider, historyProvider) { } diff --git a/NzbDrone.Core.Test/MockLib.cs b/NzbDrone.Core.Test/MockLib.cs index a6f9bb5ba..fa74f4822 100644 --- a/NzbDrone.Core.Test/MockLib.cs +++ b/NzbDrone.Core.Test/MockLib.cs @@ -2,9 +2,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using FizzWare.NBuilder; using Moq; using NzbDrone.Core.Instrumentation; using NzbDrone.Core.Providers.Core; +using NzbDrone.Core.Repository; using SubSonic.DataProviders; using SubSonic.Repository; @@ -17,7 +19,7 @@ internal static class MockLib { public static string[] StandardSeries { - get { return new[] {"c:\\tv\\the simpsons", "c:\\tv\\family guy", "c:\\tv\\southpark", "c:\\tv\\24"}; } + get { return new[] { "c:\\tv\\the simpsons", "c:\\tv\\family guy", "c:\\tv\\southpark", "c:\\tv\\24" }; } } public static ConfigProvider StandardConfig @@ -71,5 +73,14 @@ public static DiskProvider GetStandardDisk(int seasons, int episodes) return mock.Object; } + + public static Series GetFakeSeries(int id, string title) + { + return Builder.CreateNew() + .With(c => c.SeriesId = id) + .With(c => c.Title = title) + .With(c => c.CleanTitle = Parser.NormalizeTitle(title)) + .Build(); + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/ParserTest.cs b/NzbDrone.Core.Test/ParserTest.cs index 2fdf25a7a..fc0d0bc4c 100644 --- a/NzbDrone.Core.Test/ParserTest.cs +++ b/NzbDrone.Core.Test/ParserTest.cs @@ -16,31 +16,41 @@ public class ParserTest */ [Test] - [Timeout(1)] - [Row("Sonny.With.a.Chance.S02E15", 2, 15)] - [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, 1)] - [Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", 1, 3)] - [Row("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", 1, 13)] - [Row("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", 10, 13)] - [Row("Chuck.4x05.HDTV.XviD-LOL", 4, 5)] - [Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", 3, 6)] - [Row("Degrassi.S10E27.WS.DSR.XviD-2HD", 10, 27)] + [Row("Sonny.With.a.Chance.S02E15", "Sonny.With.a.Chance", 2, 15)] + [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, 1)] + [Row("Two.and.a.Half.Me.103.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 3)] + [Row("Two.and.a.Half.Me.113.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 1, 13)] + [Row("Two.and.a.Half.Me.1013.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Me", 10, 13)] + [Row("Chuck.4x05.HDTV.XviD-LOL", "Chuck", 4, 5)] + [Row("The.Girls.Next.Door.S03E06.DVDRip.XviD-WiDE", "The.Girls.Next.Door", 3, 6)] + [Row("Degrassi.S10E27.WS.DSR.XviD-2HD", "Degrassi", 10, 27)] + [Row("Parenthood.2010.S02E14.HDTV.XviD-LOL", "Parenthood", 2, 14)] + [Row("Hawaii Five 0 S01E19 720p WEB DL DD5 1 H 264 NT", "Hawaii Five", 1, 19)] + [Row("The Event S01E14 A Message Back 720p WEB DL DD5 1 H264 SURFER", "The Event", 1, 14)] + [Row("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)] + [Row("Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", "Adam Hills In Gordon St Tonight", 1, 7)] + [Row("Adventure.Inc.S03E19.DVDRip.XviD-OSiTV", "Adventure.Inc", 3, 19)] + //[Row("The.Kennedys.Part.2.DSR.XviD-SYS", 1, 2)] + public void episode_parse(string postTitle, string title, int season, int episode) + { + var result = Parser.ParseEpisodeInfo(postTitle); + Assert.AreEqual(season, result.SeasonNumber); + Assert.AreEqual(episode, result.Episodes[0]); + Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle); + } + + [Test] [Row(@"z:\tv shows\battlestar galactica (2003)\Season 3\S03E05 - Collaborators.mkv", 3, 5)] [Row(@"z:\tv shows\modern marvels\Season 16\S16E03 - The Potato.mkv", 16, 3)] [Row(@"z:\tv shows\robot chicken\Specials\S00E16 - Dear Consumer - SD TV.avi", 0, 16)] - [Row(@"Parenthood.2010.S02E14.HDTV.XviD-LOL", 2, 14)] - [Row(@"Hawaii Five 0 S01E19 720p WEB DL DD5 1 H 264 NT", 1, 19)] - [Row(@"The Event S01E14 A Message Back 720p WEB DL DD5 1 H264 SURFER", 1, 14)] - [Row(@"Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", 1, 7)] - [Row(@"Adam Hills In Gordon St Tonight S01E07 WS PDTV XviD FUtV", 1, 7)] - //[Row("The.Kennedys.Part.2.DSR.XviD-SYS", 1, 2)] - public void episode_parse(string path, int season, int episode) + public void file_path_parse(string path, int season, int episode) { var result = Parser.ParseEpisodeInfo(path); Assert.AreEqual(season, result.SeasonNumber); Assert.AreEqual(episode, result.Episodes[0]); } + [Test] [Timeout(1)] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", QualityTypes.BDRip)] @@ -62,37 +72,40 @@ public void episode_parse(string path, int season, int episode) [Row("Chuck - S01E03 - Come Fly With Me - 1080p BluRay.mkv", QualityTypes.Bluray1080)] [Row("Chuck - S11E06 - D-Yikes! - 720p WEB-DL.mkv", QualityTypes.WEBDL)] [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD.avi", QualityTypes.BDRip)] - public void quality_parse(string path, object quality) + public void quality_parse(string postTitle, object quality) { - var result = Parser.ParseEpisodeInfo(path).Quality; + var result = Parser.ParseEpisodeInfo(postTitle).Quality; Assert.AreEqual(quality, result); } [Test] [Timeout(1)] - [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", 3, new[] { 1, 2, 3, 4, 5, 6 })] - [Row("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", 1, new[] { 3, 4 })] - [Row("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", 3, new[] { 1, 2 })] - [Row("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", 1, new[] { 1, 2 })] - [Row("Big Time Rush 1x01 to 10 480i DD2 0 Sianto", 1, new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })] - [Row("White.Collar.2x04.2x05.720p.BluRay-FUTV", 2, new[] { 4, 5 })] + [Row("WEEDS.S03E01-06.DUAL.BDRip.XviD.AC3.-HELLYWOOD", "WEEDS", 3, new[] { 1, 2, 3, 4, 5, 6 })] + [Row("Two.and.a.Half.Men.103.104.720p.HDTV.X264-DIMENSION", "Two.and.a.Half.Men", 1, new[] { 3, 4 })] + [Row("Weeds.S03E01.S03E02.720p.HDTV.X264-DIMENSION", "Weeds", 3, new[] { 1, 2 })] + [Row("The Borgias S01e01 e02 ShoHD On Demand 1080i DD5 1 ALANiS", "The Borgias", 1, new[] { 1, 2 })] + [Row("Big Time Rush 1x01 to 10 480i DD2 0 Sianto", "Big Time Rush", 1, new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })] + [Row("White.Collar.2x04.2x05.720p.BluRay-FUTV", "White.Collar", 2, new[] { 4, 5 })] //[Row("The.Kennedys.Part.1.and.Part.2.DSR.XviD-SYS", 1, new[] { 1, 2 })] - public void episode_multipart_parse(string path, int season, int[] episodes) + public void episode_multipart_parse(string postTitle, string title, int season, int[] episodes) { - var result = Parser.ParseEpisodeInfo(path); + var result = Parser.ParseEpisodeInfo(postTitle); Assert.AreEqual(season, result.SeasonNumber); Assert.Count(episodes.Length, result.Episodes); Assert.AreElementsEqualIgnoringOrder(episodes, result.Episodes); + Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle); } [Test] - [Row("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", 2011, 04, 18)] - [Row("The Tonight Show With Jay Leno 2011 04 15 1080i HDTV DD5 1 MPEG2 TrollHD", 2011, 04, 15)] - public void episode_daily_parse(string path, int year, int month, int day) + [Row("Conan 2011 04 18 Emma Roberts HDTV XviD BFF", "Conan", 2011, 04, 18)] + [Row("The Tonight Show With Jay Leno 2011 04 15 1080i HDTV DD5 1 MPEG2 TrollHD", "The Tonight Show With Jay Leno", 2011, 04, 15)] + [Row("The.Daily.Show.2010.10.11.Johnny.Knoxville.iTouch-MW", "The.Daily.Show", 2010, 10, 11)] + [Row("The Daily Show - 2011-04-12 - Gov. Deval Patrick", "The.Daily.Show", 2011, 04, 12)] + public void episode_daily_parse(string postTitle, string title, int year, int month, int day) { - var result = Parser.ParseEpisodeInfo(path); + var result = Parser.ParseEpisodeInfo(postTitle); var airDate = new DateTime(year, month, day); - + Assert.AreEqual(Parser.NormalizeTitle(title), result.CleanTitle); Assert.AreEqual(airDate, result.AirDate); } @@ -107,5 +120,66 @@ public void Normalize_Path(string dirty, string clean) var result = Parser.NormalizePath(dirty); Assert.AreEqual(clean, result); } + + [Test] + [Row("CaPitAl", "capital")] + [Row("peri.od", "period")] + [Row("this.^&%^**$%@#$!That", "thisthat")] + public void Normalize_Title(string dirty, string clean) + { + var result = Parser.NormalizeTitle(dirty); + Assert.AreEqual(clean, result); + } + + [Test] + [Row("the")] + [Row("And")] + [Row("Or")] + public void Normalize_removed_common_words(string word) + { + var dirtyFormat = new[] + { + "word.{0}.word", + "word {0} word", + "word-{0}-word", + "{0}.word.word", + "{0}-word-word", + "{0} word word", + "word.word.{0}", + "word-word-{0}", + "word-word {0}", + }; + + foreach (var s in dirtyFormat) + { + var dirty = String.Format(s, word); + Assert.AreEqual("wordword", Parser.NormalizeTitle(dirty)); + } + + } + + [Test] + [Row("the")] + [Row("And")] + [Row("Or")] + public void Normalize_not_removed_common_words_in_the_middle(string word) + { + var dirtyFormat = new[] + { + "word.{0}word", + "word {0}word", + "word-{0}word", + "word{0}.word", + "word{0}-word", + "word{0}-word", + }; + + foreach (var s in dirtyFormat) + { + var dirty = String.Format(s, word); + Assert.AreEqual("word" + word.ToLower() + "word", Parser.NormalizeTitle(dirty)); + } + + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/SeriesProviderTest.cs b/NzbDrone.Core.Test/SeriesProviderTest.cs index d17151258..06a8d448b 100644 --- a/NzbDrone.Core.Test/SeriesProviderTest.cs +++ b/NzbDrone.Core.Test/SeriesProviderTest.cs @@ -80,12 +80,62 @@ public void Add_new_series() Assert.AreEqual(qualityProfileId, series.First().QualityProfileId); } + [Test] + public void find_series_empty_repo() + { + var mocker = new AutoMoqer(); + mocker.SetConstant(MockLib.GetEmptyRepository()); + + //Act + var seriesProvider = mocker.Resolve(); + var series = seriesProvider.FindSeries("My Title"); + + + //Assert + Assert.IsNull(series); + } [Test] - [Row(new object[] {"That's Life - 2x03 -The Devil and Miss DeLucca", "That's Life"})] - [Row(new object[] {"Van.Duin.Op.Zn.Best.S02E05.DUTCH.WS.PDTV.XViD-DiFFERENT", "Van Duin Op Zn Best"})] - [Row(new object[] {"Dollhouse.S02E06.The.Left.Hand.720p.BluRay.x264-SiNNERS", "Dollhouse"})] - [Row(new object[] {"Heroes.S02.COMPLETE.German.PROPER.DVDRip.XviD-Prim3time", "Heroes"})] + public void find_series_empty_match() + { + var mocker = new AutoMoqer(); + var emptyRepository = MockLib.GetEmptyRepository(); + mocker.SetConstant(emptyRepository); + emptyRepository.Add(MockLib.GetFakeSeries(1, "MyTitle")); + //Act + var seriesProvider = mocker.Resolve(); + var series = seriesProvider.FindSeries("WrongTitle"); + + + //Assert + Assert.IsNull(series); + } + + [Test] + [Row("The Test", "Test")] + [Row("The Test Title", "test title")] + public void find_series_match(string title, string searchTitle) + { + var mocker = new AutoMoqer(); + var emptyRepository = MockLib.GetEmptyRepository(); + mocker.SetConstant(emptyRepository); + emptyRepository.Add(MockLib.GetFakeSeries(1, title)); + //Act + var seriesProvider = mocker.Resolve(); + var series = seriesProvider.FindSeries(searchTitle); + + + //Assert + Assert.IsNotNull(series); + Assert.AreEqual(title, series.Title); + } + + + [Test] + [Row(new object[] { "That's Life - 2x03 -The Devil and Miss DeLucca", "That's Life" })] + [Row(new object[] { "Van.Duin.Op.Zn.Best.S02E05.DUTCH.WS.PDTV.XViD-DiFFERENT", "Van Duin Op Zn Best" })] + [Row(new object[] { "Dollhouse.S02E06.The.Left.Hand.720p.BluRay.x264-SiNNERS", "Dollhouse" })] + [Row(new object[] { "Heroes.S02.COMPLETE.German.PROPER.DVDRip.XviD-Prim3time", "Heroes" })] [Ignore("should be updated to validate agains a remote episode instance rather than just the title string")] public void Test_Parse_Success(string postTitle, string title) { @@ -129,7 +179,7 @@ public void Test_is_monitored() public void QualityWanted(int seriesId, QualityTypes qualityTypes, Boolean result) { var quality = Builder.CreateNew() - .With(q => q.Allowed = new List {QualityTypes.BDRip, QualityTypes.DVD, QualityTypes.TV}) + .With(q => q.Allowed = new List { QualityTypes.BDRip, QualityTypes.DVD, QualityTypes.TV }) .With(q => q.Cutoff = QualityTypes.DVD) .Build(); diff --git a/NzbDrone.Core/Model/EpisodeParseResult.cs b/NzbDrone.Core/Model/EpisodeParseResult.cs index 990f87315..64312c2e4 100644 --- a/NzbDrone.Core/Model/EpisodeParseResult.cs +++ b/NzbDrone.Core/Model/EpisodeParseResult.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.Model { public class EpisodeParseResult { - internal string SeriesTitle { get; set; } + internal string CleanTitle { get; set; } public int SeriesId { get; set; } internal int SeasonNumber { get; set; } @@ -24,9 +24,9 @@ public class EpisodeParseResult public override string ToString() { if (Episodes == null) - return string.Format("Series:{0} Air Date:{1}", SeriesTitle, AirDate.Date); + return string.Format("Series:{0} Air Date:{1}", CleanTitle, AirDate.Date); - return string.Format("Series:{0} Season:{1} Episode:{2}", SeriesTitle, SeasonNumber, + return string.Format("Series:{0} Season:{1} Episode:{2}", CleanTitle, SeasonNumber, String.Join(",", Episodes)); } diff --git a/NzbDrone.Core/Parser.cs b/NzbDrone.Core/Parser.cs index 957847dec..2c9a5a5cb 100644 --- a/NzbDrone.Core/Parser.cs +++ b/NzbDrone.Core/Parser.cs @@ -76,7 +76,7 @@ internal static EpisodeParseResult ParseEpisodeInfo(string title) parsedEpisode = new EpisodeParseResult { Proper = title.ToLower().Contains("proper"), - SeriesTitle = seriesName, + CleanTitle = seriesName, SeasonNumber = season, Year = year, Episodes = new List() @@ -106,7 +106,7 @@ internal static EpisodeParseResult ParseEpisodeInfo(string title) parsedEpisode = new EpisodeParseResult { Proper = title.ToLower().Contains("proper"), - SeriesTitle = seriesName, + CleanTitle = seriesName, Year = year, AirDate = new DateTime(airyear, airmonth, airday) }; diff --git a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs index ebe41399f..d08d37537 100644 --- a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs +++ b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs @@ -80,17 +80,17 @@ public void Fetch() _logger.Info("Finished processing feeds from " + Settings.Name); } - private void ProcessItem(SyndicationItem feedItem) + internal void ProcessItem(SyndicationItem feedItem) { _logger.Info("Processing RSS feed item " + feedItem.Title.Text); var parseResult = ParseFeed(feedItem); - if (parseResult != null) + if (parseResult != null && parseResult.SeriesId != 0) { if (!_seriesProvider.IsMonitored(parseResult.SeriesId)) { - _logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.SeriesTitle); + _logger.Debug("{0} is present in the DB but not tracked. skipping.", parseResult.CleanTitle); return; } @@ -147,16 +147,16 @@ protected EpisodeParseResult ParseFeed(SyndicationItem item) var episodeParseResult = Parser.ParseEpisodeInfo(item.Title.Text); if (episodeParseResult == null) return CustomParser(item, null); - var seriesInfo = _seriesProvider.FindSeries(episodeParseResult.SeriesTitle); + var seriesInfo = _seriesProvider.FindSeries(episodeParseResult.CleanTitle); if (seriesInfo != null) { episodeParseResult.SeriesId = seriesInfo.SeriesId; - episodeParseResult.SeriesTitle = seriesInfo.Title; + episodeParseResult.CleanTitle = seriesInfo.Title; return CustomParser(item, episodeParseResult); } - _logger.Debug("Unable to map {0} to any of series in database", episodeParseResult.SeriesTitle); + _logger.Debug("Unable to map {0} to any of series in database", episodeParseResult.CleanTitle); return CustomParser(item, episodeParseResult); } diff --git a/NzbDrone.Core/Providers/SeriesProvider.cs b/NzbDrone.Core/Providers/SeriesProvider.cs index ba656c630..5349cc2b6 100644 --- a/NzbDrone.Core/Providers/SeriesProvider.cs +++ b/NzbDrone.Core/Providers/SeriesProvider.cs @@ -112,7 +112,8 @@ public virtual void AddSeries(string path, int tvDbSeriesId, int qualityProfileI public virtual Series FindSeries(string title) { - return _sonioRepo.Single(s => s.CleanTitle == Parser.NormalizeTitle(title)); + var normalizeTitle = Parser.NormalizeTitle(title); + return _sonioRepo.Single(s => s.CleanTitle == normalizeTitle); } public virtual void UpdateSeries(Series series) diff --git a/NzbDrone/Program.cs b/NzbDrone/Program.cs index 6645bbebf..a737f7cdf 100644 --- a/NzbDrone/Program.cs +++ b/NzbDrone/Program.cs @@ -46,6 +46,10 @@ private static void Main() AppDomainException(e); } + while (true) + { + Console.ReadLine(); + } } private static void Attach() From 282870cd805a28a6c672eec16558fc7259c312bd Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 22 Apr 2011 13:13:32 -0700 Subject: [PATCH 3/6] Fixed AutoMoqer VerifyAll() bug --- NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs b/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs index 91803a469..9af4fd78e 100644 --- a/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs +++ b/NzbDrone.Core.Test/AutoMoq/AutoMoqer.cs @@ -116,7 +116,8 @@ public void VerifyAllMocks() foreach (var registeredMock in registeredMocks) { var mock = registeredMock.Value as Mock; - mock.VerifyAll(); + if (mock != null) + mock.VerifyAll(); } } From e074164a478dc0a4a41f285d596103664170869d Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 22 Apr 2011 13:14:02 -0700 Subject: [PATCH 4/6] more tests and bug fixes --- NzbDrone.Core.Test/EpisodeProviderTest.cs | 29 +++++++++++++++++++ NzbDrone.Core.Test/HistoryProviderTest.cs | 25 ++++++++++++++++ NzbDrone.Core.Test/MockLib.cs | 9 ++++++ NzbDrone.Core.Test/SeriesProviderTest.cs | 2 +- NzbDrone.Core/Providers/EpisodeProvider.cs | 10 ++++--- NzbDrone.Core/Providers/HistoryProvider.cs | 6 ++-- .../Providers/Indexer/IndexerProviderBase.cs | 18 ++++++++---- 7 files changed, 86 insertions(+), 13 deletions(-) diff --git a/NzbDrone.Core.Test/EpisodeProviderTest.cs b/NzbDrone.Core.Test/EpisodeProviderTest.cs index d1e14ded1..b9da6abba 100644 --- a/NzbDrone.Core.Test/EpisodeProviderTest.cs +++ b/NzbDrone.Core.Test/EpisodeProviderTest.cs @@ -116,6 +116,35 @@ public void Is_Needed_Tv_Dvd_BluRay_BluRay720_Is_Cutoff(QualityTypes reportQuali Assert.AreEqual(excpected, result); } + [Test] + public void get_episode_by_parse_result() + { + var mocker = new AutoMoqer(); + var repo = MockLib.GetEmptyRepository(); + var fakeEpisodes = MockLib.GetFakeEpisodes(2); + repo.AddMany(fakeEpisodes); + mocker.SetConstant(repo); + + var targetEpisode = fakeEpisodes[4]; + + var parseResult1 = new EpisodeParseResult + { + SeriesId = targetEpisode.SeriesId, + SeasonNumber = targetEpisode.SeasonNumber, + Episodes = new List { targetEpisode.EpisodeNumber }, + Quality = QualityTypes.DVD + }; + + var result = mocker.Resolve().GetEpisodeByParseResult(parseResult1); + + + Assert.Count(1, result); + Assert.AreEqual(targetEpisode.EpisodeId, result.First().EpisodeId); + Assert.AreEqual(targetEpisode.EpisodeNumber, result.First().EpisodeNumber); + Assert.AreEqual(targetEpisode.SeasonNumber, result.First().SeasonNumber); + Assert.AreEqual(targetEpisode.SeriesId, result.First().SeriesId); + } + [Test] public void Missing_episode_should_be_added() { diff --git a/NzbDrone.Core.Test/HistoryProviderTest.cs b/NzbDrone.Core.Test/HistoryProviderTest.cs index d7cabdc34..71828312b 100644 --- a/NzbDrone.Core.Test/HistoryProviderTest.cs +++ b/NzbDrone.Core.Test/HistoryProviderTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using AutoMoq; using MbUnit.Framework; using Moq; using NzbDrone.Core.Providers; @@ -63,6 +64,30 @@ public void AllItems() Assert.AreEqual(result.Count(), 1); } + + [Test] + public void add_item() + { + var mocker = new AutoMoqer(); + var repo = MockLib.GetEmptyRepository(); + + mocker.SetConstant(repo); + + var episodes = MockLib.GetFakeEpisodes(1); + repo.AddMany(episodes); + + var episode = episodes[5]; + + var history = new History + { + Date = DateTime.Now, + EpisodeId = episode.EpisodeId, + NzbTitle = "my title" + }; + + mocker.Resolve().Add(history); + } + [Test] [Ignore] public void Exists_True() diff --git a/NzbDrone.Core.Test/MockLib.cs b/NzbDrone.Core.Test/MockLib.cs index fa74f4822..d2ddd35d6 100644 --- a/NzbDrone.Core.Test/MockLib.cs +++ b/NzbDrone.Core.Test/MockLib.cs @@ -82,5 +82,14 @@ public static Series GetFakeSeries(int id, string title) .With(c => c.CleanTitle = Parser.NormalizeTitle(title)) .Build(); } + + public static IList GetFakeEpisodes(int seriesId) + { + var epNumber = new SequentialGenerator(); + return Builder.CreateListOfSize(10) + .WhereAll().Have(c => c.SeriesId = seriesId) + .WhereAll().Have(c => c.EpisodeNumber = epNumber.Generate()) + .Build(); + } } } \ No newline at end of file diff --git a/NzbDrone.Core.Test/SeriesProviderTest.cs b/NzbDrone.Core.Test/SeriesProviderTest.cs index 06a8d448b..d1c781523 100644 --- a/NzbDrone.Core.Test/SeriesProviderTest.cs +++ b/NzbDrone.Core.Test/SeriesProviderTest.cs @@ -113,7 +113,7 @@ public void find_series_empty_match() [Test] [Row("The Test", "Test")] - [Row("The Test Title", "test title")] + [Row("Through the Wormhole", "Through.the.Wormhole")] public void find_series_match(string title, string searchTitle) { var mocker = new AutoMoqer(); diff --git a/NzbDrone.Core/Providers/EpisodeProvider.cs b/NzbDrone.Core/Providers/EpisodeProvider.cs index 5396499b4..be16000e6 100644 --- a/NzbDrone.Core/Providers/EpisodeProvider.cs +++ b/NzbDrone.Core/Providers/EpisodeProvider.cs @@ -57,10 +57,12 @@ public virtual IList GetEpisodeBySeason(long seasonId) public virtual IList GetEpisodeByParseResult(EpisodeParseResult parseResult) { - return _sonicRepo.Find(e => - e.SeriesId == parseResult.SeriesId && - e.SeasonNumber == parseResult.SeasonNumber && - parseResult.Episodes.Contains(e.EpisodeNumber)); + var seasonEpisodes = _sonicRepo.All().Where(e => + e.SeriesId == parseResult.SeriesId && + e.SeasonNumber == parseResult.SeasonNumber).ToList(); + + //Has to be done separately since subsonic doesn't support contain method + return seasonEpisodes.Where(c => parseResult.Episodes.Contains(c.EpisodeNumber)).ToList(); } diff --git a/NzbDrone.Core/Providers/HistoryProvider.cs b/NzbDrone.Core/Providers/HistoryProvider.cs index 8dba22e29..5b473a754 100644 --- a/NzbDrone.Core/Providers/HistoryProvider.cs +++ b/NzbDrone.Core/Providers/HistoryProvider.cs @@ -40,10 +40,10 @@ public virtual void Trim() Logger.Info("History has been trimmed, items older than 30 days have been removed"); } - public virtual void Insert(History item) + public virtual void Add(History item) { _sonicRepo.Add(item); - Logger.Debug("Item added to history: {0} - {1}x{2:00}", item.Episode.Series.Title, item.Episode.SeasonNumber, item.Episode.EpisodeNumber); + Logger.Debug("Item added to history: {0}", item.NzbTitle); } public virtual bool Exists(int episodeId, QualityTypes quality, bool proper) @@ -52,7 +52,7 @@ public virtual bool Exists(int episodeId, QualityTypes quality, bool proper) if (_sonicRepo.Exists(h => h.EpisodeId == episodeId && h.Quality == quality && h.IsProper == proper)) return true; - Logger.Debug("Episode not in History. ID:{0} Q:{1} Proper:{2}", episodeId , quality, proper); + Logger.Debug("Episode not in History. ID:{0} Q:{1} Proper:{2}", episodeId, quality, proper); return false; } } diff --git a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs index d08d37537..ff591d4da 100644 --- a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs +++ b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs @@ -68,12 +68,20 @@ public void Fetch() foreach (var item in feed) { - ProcessItem(item); + try + { + ProcessItem(item); + } + catch (Exception itemEx) + { + _logger.ErrorException("An error occurred while processing feed item", itemEx); + } + } } - catch (Exception e) + catch (Exception feedEx) { - _logger.ErrorException("An error occurred while processing feed", e); + _logger.ErrorException("An error occurred while processing feed", feedEx); } } @@ -82,7 +90,7 @@ public void Fetch() internal void ProcessItem(SyndicationItem feedItem) { - _logger.Info("Processing RSS feed item " + feedItem.Title.Text); + _logger.Debug("Processing RSS feed item " + feedItem.Title.Text); var parseResult = ParseFeed(feedItem); @@ -124,7 +132,7 @@ internal void ProcessItem(SyndicationItem feedItem) //TODO: Add episode to sab - _historyProvider.Insert(new History + _historyProvider.Add(new History { Date = DateTime.Now, EpisodeId = episode.EpisodeId, From af1511e1f3c02972b3f5c845ab0e148ce49f6fb3 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 22 Apr 2011 13:48:05 -0700 Subject: [PATCH 5/6] Fixed history grid layout --- .../Providers/Indexer/IndexerProviderBase.cs | 24 +++++++++---------- NzbDrone.Core/Repository/Episode.cs | 7 +++++- NzbDrone.Web/Views/History/Index.cshtml | 23 ++++++++---------- 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs index ff591d4da..063c5560a 100644 --- a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs +++ b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs @@ -127,21 +127,21 @@ internal void ProcessItem(SyndicationItem feedItem) if (_historyProvider.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper)) { _logger.Debug("Episode in history: {0}", episode.ToString()); - continue; } + else + { + //TODO: Add episode to sab - //TODO: Add episode to sab - - _historyProvider.Add(new History - { - Date = DateTime.Now, - EpisodeId = episode.EpisodeId, - IsProper = parseResult.Proper, - NzbTitle = feedItem.Title.Text, - Quality = parseResult.Quality - }); + _historyProvider.Add(new History + { + Date = DateTime.Now, + EpisodeId = episode.EpisodeId, + IsProper = parseResult.Proper, + NzbTitle = feedItem.Title.Text, + Quality = parseResult.Quality + }); + } } - } } diff --git a/NzbDrone.Core/Repository/Episode.cs b/NzbDrone.Core/Repository/Episode.cs index 39e4e0daa..008fd795e 100644 --- a/NzbDrone.Core/Repository/Episode.cs +++ b/NzbDrone.Core/Repository/Episode.cs @@ -38,6 +38,11 @@ public class Episode public virtual EpisodeFile EpisodeFile { get; set; } [SubSonicToManyRelation] - public virtual List Histories { get; private set; } + public virtual List Histories { get; protected set; } + + public override string ToString() + { + return String.Format("[Episode: '{0} S{1:00}E{2:00}']", Series.Title, SeasonNumber, EpisodeNumber); + } } } \ No newline at end of file diff --git a/NzbDrone.Web/Views/History/Index.cshtml b/NzbDrone.Web/Views/History/Index.cshtml index 51747ccaf..89727a00e 100644 --- a/NzbDrone.Web/Views/History/Index.cshtml +++ b/NzbDrone.Web/Views/History/Index.cshtml @@ -1,6 +1,5 @@ @model List @using NzbDrone.Web.Models - @section Scripts{ } - @section TitleContent{ - History +History } - @section ActionMenu{ @{Html.Telerik().Menu().Name("historyMenu").Items(items => { @@ -33,17 +30,17 @@ items.Add().Text("Purge History").Action("Purge", "History"); }).Render();} } - @section MainContent{ @{Html.Telerik().Grid().Name("history") + .TableHtmlAttributes(new { @class = "Grid" }) .Columns(columns => { columns.Bound(c => c.SeriesTitle).Title("Series Name").Width(120); - columns.Bound(c => c.SeasonNumber).Title("Season #").Width(10); - columns.Bound(c => c.EpisodeNumber).Title("Episode #").Width(10); - columns.Bound(c => c.EpisodeTitle).Title("Episode Title").Width(140); - columns.Bound(c => c.Quality).Title("Quality").Width(30); - columns.Bound(c => c.Date).Title("Date Grabbed").Width(60); + columns.Bound(c => c.SeasonNumber).Title("Season").Width(10); + columns.Bound(c => c.EpisodeNumber).Title("Episode").Width(10); + columns.Bound(c => c.EpisodeTitle).Title("Episode Title"); + columns.Bound(c => c.Quality).Title("Quality").Width(10); + columns.Bound(c => c.Date).Title("Date/Time Grabbed"); }) .DetailView(detailView => detailView.ClientTemplate( "
" + @@ -57,7 +54,7 @@ .Pageable( c => c.PageSize(50).Position(GridPagerPosition.Bottom).Style(GridPagerStyles.NextPrevious)) - //.Filterable() - //.ClientEvents(c => c.OnRowDataBound("onRowDataBound")) + //.Filterable() + //.ClientEvents(c => c.OnRowDataBound("onRowDataBound")) .Render();} -} \ No newline at end of file +} From 680ea4583958409035f091f56ce3be81237e86d5 Mon Sep 17 00:00:00 2001 From: "kay.one" Date: Fri, 22 Apr 2011 13:59:43 -0700 Subject: [PATCH 6/6] fixed Episode.ToString() bug --- NzbDrone.Core.Test/ParserTest.cs | 2 +- NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs | 2 +- NzbDrone.Core/Repository/Episode.cs | 4 ---- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/NzbDrone.Core.Test/ParserTest.cs b/NzbDrone.Core.Test/ParserTest.cs index fc0d0bc4c..56685fa7e 100644 --- a/NzbDrone.Core.Test/ParserTest.cs +++ b/NzbDrone.Core.Test/ParserTest.cs @@ -12,7 +12,7 @@ public class ParserTest /*Fucked-up hall of shame, * WWE.Wrestlemania.27.PPV.HDTV.XviD-KYR * The.Kennedys.Part.2.DSR.XviD-SYS - * + * Unreported.World.Chinas.Lost.Sons.WS.PDTV.XviD-FTP */ [Test] diff --git a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs index 063c5560a..797148584 100644 --- a/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs +++ b/NzbDrone.Core/Providers/Indexer/IndexerProviderBase.cs @@ -126,7 +126,7 @@ internal void ProcessItem(SyndicationItem feedItem) { if (_historyProvider.Exists(episode.EpisodeId, parseResult.Quality, parseResult.Proper)) { - _logger.Debug("Episode in history: {0}", episode.ToString()); + _logger.Debug("Episode in history: {0}", feedItem.Title.Text); } else { diff --git a/NzbDrone.Core/Repository/Episode.cs b/NzbDrone.Core/Repository/Episode.cs index 008fd795e..f9092512c 100644 --- a/NzbDrone.Core/Repository/Episode.cs +++ b/NzbDrone.Core/Repository/Episode.cs @@ -40,9 +40,5 @@ public class Episode [SubSonicToManyRelation] public virtual List Histories { get; protected set; } - public override string ToString() - { - return String.Format("[Episode: '{0} S{1:00}E{2:00}']", Series.Title, SeasonNumber, EpisodeNumber); - } } } \ No newline at end of file