Fixed: Daily series with multiple episodes on the same day

This commit is contained in:
Mark McDowall 2014-04-02 17:02:53 -07:00
parent a336726dd5
commit 9edb261c16
3 changed files with 113 additions and 11 deletions

View File

@ -213,6 +213,7 @@
<Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodesFixture.cs" /> <Compile Include="Housekeeping\Housekeepers\CleanupOrphanedEpisodesFixture.cs" />
<Compile Include="ThingiProviderTests\NullConfigFixture.cs" /> <Compile Include="ThingiProviderTests\NullConfigFixture.cs" />
<Compile Include="ThingiProvider\ProviderBaseFixture.cs" /> <Compile Include="ThingiProvider\ProviderBaseFixture.cs" />
<Compile Include="TvTests\EpisodeRepositoryTests\ByAirDateFixture.cs" />
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithFilesFixture.cs" /> <Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWithFilesFixture.cs" />
<Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWhereCutoffUnmetFixture.cs" /> <Compile Include="TvTests\EpisodeRepositoryTests\EpisodesWhereCutoffUnmetFixture.cs" />
<Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" /> <Compile Include="TvTests\RefreshEpisodeServiceFixture.cs" />

View File

@ -0,0 +1,71 @@
using System;
using FizzWare.NBuilder;
using FluentAssertions;
using NUnit.Framework;
using NzbDrone.Core.Test.Framework;
using NzbDrone.Core.Tv;
namespace NzbDrone.Core.Test.TvTests.EpisodeRepositoryTests
{
[TestFixture]
public class ByAirDateFixture : DbTest<EpisodeRepository, Episode>
{
private const int SERIES_ID = 1;
private const string AIR_DATE = "2014-04-02";
private void GivenEpisode(int seasonNumber)
{
var episode = Builder<Episode>.CreateNew()
.With(e => e.SeriesId = 1)
.With(e => e.SeasonNumber = seasonNumber)
.With(e => e.AirDate = AIR_DATE)
.BuildNew();
Db.Insert(episode);
}
[Test]
public void should_throw_when_multiple_regular_episodes_are_found()
{
GivenEpisode(1);
GivenEpisode(2);
Assert.Throws<InvalidOperationException>(() => Subject.Get(SERIES_ID, AIR_DATE));
Assert.Throws<InvalidOperationException>(() => Subject.Find(SERIES_ID, AIR_DATE));
}
[Test]
public void should_throw_when_get_finds_no_episode()
{
Assert.Throws<InvalidOperationException>(() => Subject.Get(SERIES_ID, AIR_DATE));
}
[Test]
public void should_get_episode_when_single_episode_exists_for_air_date()
{
GivenEpisode(1);
Subject.Get(SERIES_ID, AIR_DATE).Should().NotBeNull();
Subject.Find(SERIES_ID, AIR_DATE).Should().NotBeNull();
}
[Test]
public void should_get_episode_when_regular_episode_and_special_share_the_same_air_date()
{
GivenEpisode(1);
GivenEpisode(0);
Subject.Get(SERIES_ID, AIR_DATE).Should().NotBeNull();
Subject.Find(SERIES_ID, AIR_DATE).Should().NotBeNull();
}
[Test]
public void should_get_special_when_its_the_only_episode_for_the_date_provided()
{
GivenEpisode(0);
Subject.Get(SERIES_ID, AIR_DATE).Should().NotBeNull();
Subject.Find(SERIES_ID, AIR_DATE).Should().NotBeNull();
}
}
}

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using Marr.Data.QGen; using Marr.Data.QGen;
using NLog;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Datastore.Extentions; using NzbDrone.Core.Datastore.Extentions;
using NzbDrone.Core.Messaging.Events; using NzbDrone.Core.Messaging.Events;
@ -14,8 +16,8 @@ namespace NzbDrone.Core.Tv
{ {
Episode Find(int seriesId, int season, int episodeNumber); Episode Find(int seriesId, int season, int episodeNumber);
Episode Find(int seriesId, int absoluteEpisodeNumber); Episode Find(int seriesId, int absoluteEpisodeNumber);
Episode Get(int seriesId, String date); Episode Get(int seriesId, string date);
Episode Find(int seriesId, String date); Episode Find(int seriesId, string date);
List<Episode> GetEpisodes(int seriesId); List<Episode> GetEpisodes(int seriesId);
List<Episode> GetEpisodes(int seriesId, int seasonNumber); List<Episode> GetEpisodes(int seriesId, int seasonNumber);
List<Episode> GetEpisodeByFileId(int fileId); List<Episode> GetEpisodeByFileId(int fileId);
@ -32,11 +34,13 @@ namespace NzbDrone.Core.Tv
public class EpisodeRepository : BasicRepository<Episode>, IEpisodeRepository public class EpisodeRepository : BasicRepository<Episode>, IEpisodeRepository
{ {
private readonly IDatabase _database; private readonly IDatabase _database;
private readonly Logger _logger;
public EpisodeRepository(IDatabase database, IEventAggregator eventAggregator) public EpisodeRepository(IDatabase database, IEventAggregator eventAggregator, Logger logger)
: base(database, eventAggregator) : base(database, eventAggregator)
{ {
_database = database; _database = database;
_logger = logger;
} }
public Episode Find(int seriesId, int season, int episodeNumber) public Episode Find(int seriesId, int season, int episodeNumber)
@ -54,18 +58,21 @@ namespace NzbDrone.Core.Tv
.SingleOrDefault(); .SingleOrDefault();
} }
public Episode Get(int seriesId, String date) public Episode Get(int seriesId, string date)
{ {
return Query.Where(s => s.SeriesId == seriesId) var episode = FindOneByAirDate(seriesId, date);
.AndWhere(s => s.AirDate == date)
.Single(); if (episode == null)
{
throw new InvalidOperationException("Expected at one episode");
} }
public Episode Find(int seriesId, String date) return episode;
}
public Episode Find(int seriesId, string date)
{ {
return Query.Where(s => s.SeriesId == seriesId) return FindOneByAirDate(seriesId, date);
.AndWhere(s => s.AirDate == date)
.SingleOrDefault();
} }
public List<Episode> GetEpisodes(int seriesId) public List<Episode> GetEpisodes(int seriesId)
@ -207,5 +214,28 @@ namespace NzbDrone.Core.Tv
return String.Format("({0})", String.Join(" OR ", clauses)); return String.Format("({0})", String.Join(" OR ", clauses));
} }
private Episode FindOneByAirDate(int seriesId, string date)
{
var episodes = Query.Where(s => s.SeriesId == seriesId)
.AndWhere(s => s.AirDate == date)
.ToList();
if (!episodes.Any()) return null;
if (episodes.Count == 1) return episodes.First();
_logger.Debug("Multiple episodes with the same air date were found, will exclude specials");
var regularEpisodes = episodes.Where(e => e.SeasonNumber > 0).ToList();
if (regularEpisodes.Count == 1)
{
_logger.Debug("Left with one episode after excluding specials");
return regularEpisodes.First();
}
throw new InvalidOperationException("Multiple episodes with the same air date found");
}
} }
} }