mirror of https://github.com/ErsatzTV/ErsatzTV.git
13 changed files with 1841 additions and 6 deletions
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Scheduling; |
||||
using FluentAssertions; |
||||
using NUnit.Framework; |
||||
using static LanguageExt.Prelude; |
||||
|
||||
namespace ErsatzTV.Core.Tests.Scheduling |
||||
{ |
||||
public class CustomOrderContentTests |
||||
{ |
||||
[Test] |
||||
public void MediaItems_Should_Sort_By_CustomOrder() |
||||
{ |
||||
Collection collection = CreateCollection(10); |
||||
List<MediaItem> contents = Episodes(10); |
||||
var state = new CollectionEnumeratorState(); |
||||
|
||||
var customOrderContent = new CustomOrderCollectionEnumerator(collection, contents, state); |
||||
|
||||
for (var i = 10; i >= 1; i--) |
||||
{ |
||||
customOrderContent.Current.IsSome.Should().BeTrue(); |
||||
customOrderContent.Current.Map(x => x.Id).IfNone(-1).Should().Be(i); |
||||
customOrderContent.MoveNext(); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void State_Index_Should_Increment() |
||||
{ |
||||
Collection collection = CreateCollection(10); |
||||
List<MediaItem> contents = Episodes(10); |
||||
var state = new CollectionEnumeratorState(); |
||||
|
||||
var customOrderContent = new CustomOrderCollectionEnumerator(collection, contents, state); |
||||
|
||||
for (var i = 0; i < 10; i++) |
||||
{ |
||||
customOrderContent.State.Index.Should().Be(i % 10); |
||||
customOrderContent.MoveNext(); |
||||
} |
||||
} |
||||
|
||||
[Test] |
||||
public void State_Should_Impact_Iterator_Start() |
||||
{ |
||||
Collection collection = CreateCollection(10); |
||||
List<MediaItem> contents = Episodes(10); |
||||
var state = new CollectionEnumeratorState { Index = 5 }; |
||||
|
||||
var customOrderContent = new CustomOrderCollectionEnumerator(collection, contents, state); |
||||
|
||||
for (var i = 5; i >= 1; i--) |
||||
{ |
||||
customOrderContent.Current.IsSome.Should().BeTrue(); |
||||
customOrderContent.Current.Map(x => x.Id).IfNone(-1).Should().Be(i); |
||||
customOrderContent.State.Index.Should().Be(5 - i + 5); // 5 through 10
|
||||
customOrderContent.MoveNext(); |
||||
} |
||||
} |
||||
|
||||
private static Collection CreateCollection(int episodeCount) |
||||
{ |
||||
var collection = new Collection { CollectionItems = new List<CollectionItem>() }; |
||||
|
||||
for (var i = 1; i <= episodeCount; i++) |
||||
{ |
||||
collection.CollectionItems.Add( |
||||
new CollectionItem |
||||
{ |
||||
MediaItemId = i, |
||||
// reverse order
|
||||
CustomIndex = episodeCount - i |
||||
}); |
||||
} |
||||
|
||||
return collection; |
||||
} |
||||
|
||||
|
||||
private static List<MediaItem> Episodes(int count) => |
||||
Range(1, count).Map( |
||||
i => (MediaItem) new Episode |
||||
{ |
||||
Id = i, |
||||
EpisodeMetadata = new List<EpisodeMetadata> |
||||
{ |
||||
new() |
||||
{ |
||||
ReleaseDate = new DateTime(2020, 1, i) |
||||
} |
||||
} |
||||
}) |
||||
.Reverse() |
||||
.ToList(); |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Interfaces.Scheduling; |
||||
using LanguageExt; |
||||
using static LanguageExt.Prelude; |
||||
|
||||
namespace ErsatzTV.Core.Scheduling |
||||
{ |
||||
public class CustomOrderCollectionEnumerator : IMediaCollectionEnumerator |
||||
{ |
||||
private readonly IList<MediaItem> _sortedMediaItems; |
||||
|
||||
public CustomOrderCollectionEnumerator( |
||||
Collection collection, |
||||
List<MediaItem> mediaItems, |
||||
CollectionEnumeratorState state) |
||||
{ |
||||
// TODO: this will break if we allow shows and seasons
|
||||
_sortedMediaItems = collection.CollectionItems |
||||
.OrderBy(ci => ci.CustomIndex) |
||||
.Map(ci => mediaItems.First(mi => mi.Id == ci.MediaItemId)) |
||||
.ToList(); |
||||
|
||||
State = new CollectionEnumeratorState { Seed = state.Seed }; |
||||
while (State.Index < state.Index) |
||||
{ |
||||
MoveNext(); |
||||
} |
||||
} |
||||
|
||||
public CollectionEnumeratorState State { get; } |
||||
|
||||
public Option<MediaItem> Current => _sortedMediaItems.Any() ? _sortedMediaItems[State.Index] : None; |
||||
|
||||
public void MoveNext() => State.Index = (State.Index + 1) % _sortedMediaItems.Count; |
||||
} |
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
using ErsatzTV.Core.Domain; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Data.Configurations |
||||
{ |
||||
public class CollectionItemConfiguration : IEntityTypeConfiguration<CollectionItem> |
||||
{ |
||||
public void Configure(EntityTypeBuilder<CollectionItem> builder) => builder.ToTable("CollectionItem"); |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace ErsatzTV.Infrastructure.Migrations |
||||
{ |
||||
public partial class Add_CollectionItem_CustomIndex : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) => |
||||
migrationBuilder.AddColumn<int>( |
||||
"CustomIndex", |
||||
"CollectionItem", |
||||
"INTEGER", |
||||
nullable: true); |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) => |
||||
migrationBuilder.DropColumn( |
||||
"CustomIndex", |
||||
"CollectionItem"); |
||||
} |
||||
} |
||||
Loading…
Reference in new issue