@ -3,190 +3,287 @@ using ErsatzTV.Core.Domain.Filler;
@@ -3,190 +3,287 @@ using ErsatzTV.Core.Domain.Filler;
using ErsatzTV.Core.Interfaces.Scheduling ;
using ErsatzTV.Core.Scheduling ;
using FluentAssertions ;
using Microsoft.Extensions.Logging ;
using Moq ;
using NUnit.Framework ;
namespace ErsatzTV.Core.Tests.Scheduling ;
[TestFixture]
public class PlayoutModeSchedulerBaseTests
public class PlayoutModeSchedulerBaseTests : SchedulerTestBase
{
[Test]
public void CalculateEndTimeWithFiller_Should_Not_Touch_Enumerator ( )
[TestFixture ]
public class CalculateEndTimeWithFiller
{
var collection = new Collection
[Test]
public void Should_Not_Touch_Enumerator ( )
{
Id = 1 ,
Name = "Filler Items" ,
MediaItems = new List < MediaItem > ( )
} ;
var collection = new Collection
{
Id = 1 ,
Name = "Filler Items" ,
MediaItems = new List < MediaItem > ( )
} ;
for ( var i = 0 ; i < 5 ; i + + )
{
collection . MediaItems . Add ( TestMovie ( i + 1 , TimeSpan . FromHours ( i + 1 ) , new DateTime ( 2 0 2 0 , 2 , i + 1 ) ) ) ;
for ( var i = 0 ; i < 5 ; i + + )
{
collection . MediaItems . Add ( TestMovie ( i + 1 , TimeSpan . FromHours ( i + 1 ) , new DateTime ( 2 0 2 0 , 2 , i + 1 ) ) ) ;
}
var fillerPreset = new FillerPreset
{
FillerKind = FillerKind . PreRoll ,
FillerMode = FillerMode . Count ,
Count = 3 ,
Collection = collection ,
CollectionId = collection . Id
} ;
var enumerator = new ChronologicalMediaCollectionEnumerator (
collection . MediaItems ,
new CollectionEnumeratorState { Index = 0 , Seed = 1 } ) ;
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator >
{
{ CollectionKey . ForFillerPreset ( fillerPreset ) , enumerator }
} ,
new ProgramScheduleItemOne
{
PreRollFiller = fillerPreset
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 8 , 1 2 , 3 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
enumerator . State . Index . Should ( ) . Be ( 0 ) ;
enumerator . State . Seed . Should ( ) . Be ( 1 ) ;
}
var fillerPreset = new FillerPreset
[Test]
public void Should_Pad_To_15_Minutes_15 ( )
{
FillerKind = FillerKind . PreRoll ,
FillerMode = FillerMode . Count ,
Count = 3 ,
Collection = collection ,
CollectionId = collection . Id
} ;
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
var enumerator = new ChronologicalMediaCollectionEnumerator (
collection . MediaItems ,
new CollectionEnumeratorState { Index = 0 , Seed = 1 } ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 1 5 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator >
{
{ CollectionKey . ForFillerPreset ( fillerPreset ) , enumerator }
} ,
new ProgramScheduleItemOne
{
PreRollFiller = fillerPreset
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 8 , 1 2 , 3 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
enumerator . State . Index . Should ( ) . Be ( 0 ) ;
enumerator . State . Seed . Should ( ) . Be ( 1 ) ;
}
[Test]
public void Should_Pad_To_15_Minutes_30 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
MidRollFiller = new F illerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 1 6 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
[Test]
public void CalculateEndTimeWithFiller_Should_Pad_To_15_Minutes_15 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
MidRollFiller = new FillerPreset
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 3 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void Should_Pad_To_15_Minutes_45 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 1 5 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void CalculateEndTimeWithFiller_Should_Pad_To_15_Minutes_30 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
MidRollFiller = new FillerPreset
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 3 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 4 5 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void Should_Pad_To_15_Minutes_00 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 1 6 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 3 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void CalculateEndTimeWithFiller_Should_Pad_To_15_Minutes_45 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
MidRollFiller = new FillerPreset
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 4 6 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 3 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void Should_Pad_To_30_Minutes_30 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 3 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 4 5 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void CalculateEndTimeWithFiller_Should_Pad_To_15_Minutes_00 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
MidRollFiller = new FillerPreset
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 3 0
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 3 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void Should_Pad_To_30_Minutes_00 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 4 6 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 3 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 3 0
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 2 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 3 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
}
[Test]
public void CalculateEndTimeWithFiller_Should_Pad_To_30_Minutes_30 ( )
[TestFixture ]
public class AddFiller
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
[Test]
public void Should_Not_Crash_Mid_Roll_Zero_Chapters ( )
{
Collection collectionOne = TwoItemCollection ( 1 , 2 , TimeSpan . FromHours ( 1 ) ) ;
var scheduleItem = new ProgramScheduleItemOne
{
MidRollFiller = new FillerPreset
{
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 3 0
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 3 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
}
[Test]
public void CalculateEndTimeWithFiller_Should_Pad_To_30_Minutes_00 ( )
{
DateTimeOffset result = PlayoutModeSchedulerBase < ProgramScheduleItem >
. CalculateEndTimeWithFiller (
new Dictionary < CollectionKey , IMediaCollectionEnumerator > ( ) ,
new ProgramScheduleItemOne
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ;
var scheduleItemsEnumerator = new OrderedScheduleItemsEnumerator (
new List < ProgramScheduleItem > { scheduleItem } ,
new CollectionEnumeratorState ( ) ) ;
var enumerator = new ChronologicalMediaCollectionEnumerator (
collectionOne . MediaItems ,
new CollectionEnumeratorState ( ) ) ;
PlayoutBuilderState startState = StartState ( scheduleItemsEnumerator ) ;
List < PlayoutItem > playoutItems = PlayoutModeSchedulerBase < ProgramScheduleItem >
. AddFiller (
startState ,
CollectionEnumerators ( scheduleItem , enumerator ) ,
scheduleItem ,
new PlayoutItem ( ) ,
new List < MediaChapter > ( ) ) ;
playoutItems . Count . Should ( ) . Be ( 1 ) ;
}
[Test]
public void Should_Not_Crash_Mid_Roll_One_Chapter ( )
{
Collection collectionOne = TwoItemCollection ( 1 , 2 , TimeSpan . FromHours ( 1 ) ) ;
var scheduleItem = new ProgramScheduleItemOne
{
Id = 1 ,
Index = 1 ,
Collection = collectionOne ,
CollectionId = collectionOne . Id ,
StartTime = null ,
PlaybackOrder = PlaybackOrder . Chronological ,
TailFiller = null ,
FallbackFiller = null ,
MidRollFiller = new FillerPreset
{
MidRollFiller = new FillerPreset
{
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 3 0
}
} ,
new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 2 , 2 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ,
new TimeSpan ( 0 , 1 2 , 3 0 ) ,
new List < MediaChapter > ( ) ) ;
result . Should ( ) . Be ( new DateTimeOffset ( 2 0 2 0 , 2 , 1 , 1 3 , 0 , 0 , TimeSpan . FromHours ( - 5 ) ) ) ;
FillerKind = FillerKind . MidRoll ,
FillerMode = FillerMode . Pad ,
PadToNearestMinute = 1 5
}
} ;
var scheduleItemsEnumerator = new OrderedScheduleItemsEnumerator (
new List < ProgramScheduleItem > { scheduleItem } ,
new CollectionEnumeratorState ( ) ) ;
var enumerator = new ChronologicalMediaCollectionEnumerator (
collectionOne . MediaItems ,
new CollectionEnumeratorState ( ) ) ;
PlayoutBuilderState startState = StartState ( scheduleItemsEnumerator ) ;
Dictionary < CollectionKey , IMediaCollectionEnumerator > enumerators = CollectionEnumerators (
scheduleItem ,
enumerator ) ;
// too lazy to make another enumerator for the filler that we don't want
enumerators . Add ( CollectionKey . ForFillerPreset ( scheduleItem . MidRollFiller ) , enumerator ) ;
List < PlayoutItem > playoutItems = PlayoutModeSchedulerBase < ProgramScheduleItem >
. AddFiller (
startState ,
enumerators ,
scheduleItem ,
new PlayoutItem ( ) ,
new List < MediaChapter > { new ( ) } ) ;
playoutItems . Count . Should ( ) . Be ( 1 ) ;
}
}
private static Movie TestMovie ( int id , TimeSpan duration , DateTime aired ) = >