@ -1151,6 +1151,212 @@ namespace ErsatzTV.Core.Tests.Scheduling
@@ -1151,6 +1151,212 @@ namespace ErsatzTV.Core.Tests.Scheduling
result . Anchor . NextScheduleItem . Should ( ) . Be ( items [ 1 ] ) ;
result . Anchor . DurationFinish . Should ( ) . Be ( HoursAfterMidnight ( 6 ) . UtcDateTime ) ;
}
[Test]
public async Task Alternating_Duration_With_Filler_Should_Alternate_Schedule_Items ( )
{
var collectionOne = new Collection
{
Id = 1 ,
Name = "Duration Items 1" ,
MediaItems = new List < MediaItem >
{
TestMovie ( 1 , TimeSpan . FromMinutes ( 5 5 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) )
}
} ;
var collectionTwo = new Collection
{
Id = 2 ,
Name = "Duration Items 2" ,
MediaItems = new List < MediaItem >
{
TestMovie ( 2 , TimeSpan . FromMinutes ( 5 5 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) )
}
} ;
var collectionThree = new Collection
{
Id = 3 ,
Name = "Filler Items" ,
MediaItems = new List < MediaItem >
{
TestMovie ( 3 , TimeSpan . FromMinutes ( 5 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) )
}
} ;
var fakeRepository = new FakeMediaCollectionRepository (
Map (
( collectionOne . Id , collectionOne . MediaItems . ToList ( ) ) ,
( collectionTwo . Id , collectionTwo . MediaItems . ToList ( ) ) ,
( collectionThree . Id , collectionThree . MediaItems . ToList ( ) ) ) ) ;
var items = new List < ProgramScheduleItem >
{
new ProgramScheduleItemDuration
{
Id = 1 ,
Index = 1 ,
Collection = collectionOne ,
CollectionId = collectionOne . Id ,
StartTime = null ,
PlayoutDuration = TimeSpan . FromHours ( 3 ) ,
PlaybackOrder = PlaybackOrder . Chronological ,
TailMode = TailMode . Filler ,
TailCollectionType = ProgramScheduleItemCollectionType . Collection ,
TailCollection = collectionThree ,
TailCollectionId = collectionThree . Id
} ,
new ProgramScheduleItemDuration
{
Id = 2 ,
Index = 2 ,
Collection = collectionTwo ,
CollectionId = collectionTwo . Id ,
StartTime = null ,
PlayoutDuration = TimeSpan . FromHours ( 3 ) ,
PlaybackOrder = PlaybackOrder . Chronological ,
TailMode = TailMode . Filler ,
TailCollectionType = ProgramScheduleItemCollectionType . Collection ,
TailCollection = collectionThree ,
TailCollectionId = collectionThree . Id
}
} ;
var playout = new Playout
{
ProgramSchedule = new ProgramSchedule
{
Items = items
} ,
Channel = new Channel ( Guid . Empty ) { Id = 1 , Name = "Test Channel" } ,
} ;
var configRepo = new Mock < IConfigElementRepository > ( ) ;
var televisionRepo = new FakeTelevisionRepository ( ) ;
var artistRepo = new Mock < IArtistRepository > ( ) ;
var builder = new PlayoutBuilder (
configRepo . Object ,
fakeRepository ,
televisionRepo ,
artistRepo . Object ,
_l ogger ) ;
DateTimeOffset start = HoursAfterMidnight ( 0 ) ;
DateTimeOffset finish = start + TimeSpan . FromHours ( 6 ) ;
Playout result = await builder . BuildPlayoutItems ( playout , start , finish ) ;
result . Items . Count . Should ( ) . Be ( 1 2 ) ;
result . Items [ 0 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromMinutes ( 0 ) ) ;
result . Items [ 0 ] . MediaItemId . Should ( ) . Be ( 1 ) ;
result . Items [ 1 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromMinutes ( 5 5 ) ) ;
result . Items [ 1 ] . MediaItemId . Should ( ) . Be ( 1 ) ;
result . Items [ 2 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 1 , 5 0 , 0 ) ) ;
result . Items [ 2 ] . MediaItemId . Should ( ) . Be ( 1 ) ;
result . Items [ 3 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 2 , 4 5 , 0 ) ) ;
result . Items [ 3 ] . MediaItemId . Should ( ) . Be ( 3 ) ;
result . Items [ 4 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 2 , 5 0 , 0 ) ) ;
result . Items [ 4 ] . MediaItemId . Should ( ) . Be ( 3 ) ;
result . Items [ 5 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 2 , 5 5 , 0 ) ) ;
result . Items [ 5 ] . MediaItemId . Should ( ) . Be ( 3 ) ;
result . Items [ 6 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 3 ) ) ;
result . Items [ 6 ] . MediaItemId . Should ( ) . Be ( 2 ) ;
result . Items [ 7 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 3 , 5 5 , 0 ) ) ;
result . Items [ 7 ] . MediaItemId . Should ( ) . Be ( 2 ) ;
result . Items [ 8 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 4 , 5 0 , 0 ) ) ;
result . Items [ 8 ] . MediaItemId . Should ( ) . Be ( 2 ) ;
result . Items [ 9 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 5 , 4 5 , 0 ) ) ;
result . Items [ 9 ] . MediaItemId . Should ( ) . Be ( 3 ) ;
result . Items [ 1 0 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 5 , 5 0 , 0 ) ) ;
result . Items [ 1 0 ] . MediaItemId . Should ( ) . Be ( 3 ) ;
result . Items [ 1 1 ] . StartOffset . TimeOfDay . Should ( ) . Be ( new TimeSpan ( 5 , 5 5 , 0 ) ) ;
result . Items [ 1 1 ] . MediaItemId . Should ( ) . Be ( 3 ) ;
result . Anchor . NextScheduleItem . Should ( ) . Be ( items [ 0 ] ) ;
result . Anchor . DurationFinish . Should ( ) . BeNull ( ) ;
}
[Test]
public async Task Duration_Should_Skip_Items_That_Are_Too_Long ( )
{
var collectionOne = new Collection
{
Id = 1 ,
Name = "Duration Items 1" ,
MediaItems = new List < MediaItem >
{
TestMovie ( 1 , TimeSpan . FromHours ( 2 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) ) ,
TestMovie ( 2 , TimeSpan . FromHours ( 1 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) ) ,
TestMovie ( 3 , TimeSpan . FromHours ( 2 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) ) ,
TestMovie ( 4 , TimeSpan . FromHours ( 1 ) , new DateTime ( 2 0 2 0 , 1 , 1 ) )
}
} ;
var fakeRepository =
new FakeMediaCollectionRepository ( Map ( ( collectionOne . Id , collectionOne . MediaItems . ToList ( ) ) ) ) ;
var items = new List < ProgramScheduleItem >
{
new ProgramScheduleItemDuration
{
Id = 1 ,
Index = 1 ,
Collection = collectionOne ,
CollectionId = collectionOne . Id ,
StartTime = null ,
PlayoutDuration = TimeSpan . FromHours ( 1 ) ,
PlaybackOrder = PlaybackOrder . Chronological ,
TailMode = TailMode . None ,
}
} ;
var playout = new Playout
{
ProgramSchedule = new ProgramSchedule
{
Items = items
} ,
Channel = new Channel ( Guid . Empty ) { Id = 1 , Name = "Test Channel" } ,
} ;
var configRepo = new Mock < IConfigElementRepository > ( ) ;
var televisionRepo = new FakeTelevisionRepository ( ) ;
var artistRepo = new Mock < IArtistRepository > ( ) ;
var builder = new PlayoutBuilder (
configRepo . Object ,
fakeRepository ,
televisionRepo ,
artistRepo . Object ,
_l ogger ) ;
DateTimeOffset start = HoursAfterMidnight ( 0 ) ;
DateTimeOffset finish = start + TimeSpan . FromHours ( 6 ) ;
Playout result = await builder . BuildPlayoutItems ( playout , start , finish ) ;
result . Items . Count . Should ( ) . Be ( 6 ) ;
result . Items [ 0 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 0 ) ) ;
result . Items [ 0 ] . MediaItemId . Should ( ) . Be ( 2 ) ;
result . Items [ 1 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 1 ) ) ;
result . Items [ 1 ] . MediaItemId . Should ( ) . Be ( 4 ) ;
result . Items [ 2 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 2 ) ) ;
result . Items [ 2 ] . MediaItemId . Should ( ) . Be ( 2 ) ;
result . Items [ 3 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 3 ) ) ;
result . Items [ 3 ] . MediaItemId . Should ( ) . Be ( 4 ) ;
result . Items [ 4 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 4 ) ) ;
result . Items [ 4 ] . MediaItemId . Should ( ) . Be ( 2 ) ;
result . Items [ 5 ] . StartOffset . TimeOfDay . Should ( ) . Be ( TimeSpan . FromHours ( 5 ) ) ;
result . Items [ 5 ] . MediaItemId . Should ( ) . Be ( 4 ) ;
result . Anchor . NextScheduleItem . Should ( ) . Be ( items [ 0 ] ) ;
result . Anchor . DurationFinish . Should ( ) . BeNull ( ) ;
}
private static DateTimeOffset HoursAfterMidnight ( int hours )
{