260 lines
8.3 KiB
C#
260 lines
8.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
using MfGames.Gallium;
|
|
using MfGames.Nitride.Tests;
|
|
|
|
using NodaTime;
|
|
using NodaTime.Testing;
|
|
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
using YamlDotNet.Serialization;
|
|
using YamlDotNet.Serialization.NamingConventions;
|
|
|
|
using Zio;
|
|
|
|
namespace MfGames.Nitride.Temporal.Schedules.Tests;
|
|
|
|
public class IndexedPathRegexScheduleTest : TemporalSchedulesTestBase
|
|
{
|
|
public IndexedPathRegexScheduleTest(ITestOutputHelper output)
|
|
: base(output)
|
|
{
|
|
}
|
|
|
|
[Fact]
|
|
public void DeserializedSetupWorks()
|
|
{
|
|
using TemporalSchedulesTestContext context = this.CreateContext();
|
|
|
|
// Create a numerical series of entities.
|
|
var input = new List<Entity>
|
|
{
|
|
new Entity().SetAll((UPath)"/chapter-01.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-02.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-03.md", new TestModel()),
|
|
};
|
|
|
|
TestModel model = new DeserializerBuilder()
|
|
.WithNamingConvention(CamelCaseNamingConvention.Instance)
|
|
.Build()
|
|
.Deserialize<TestModel>(
|
|
string.Join(
|
|
"\n",
|
|
"---",
|
|
"access: custom",
|
|
"schedules:",
|
|
" pathRegex: chapter-(\\d+)",
|
|
" indexes:",
|
|
" 1:",
|
|
" scheduleStart: 2020-01-01",
|
|
" schedulePeriod: instant",
|
|
" access: t-1",
|
|
" 2:",
|
|
" scheduleStart: 2023-01-02",
|
|
" schedulePeriod: 1 week",
|
|
" access: t-2",
|
|
""));
|
|
var schedules = model.Schedules!;
|
|
|
|
// Create the operation and run it, but treat it as being set after the
|
|
// second but before the third item.
|
|
TimeService time = context.Resolve<TimeService>();
|
|
ApplySchedules op = context.Resolve<ApplySchedules>()
|
|
.WithGetSchedules(_ => new ISchedule[] { schedules });
|
|
var now = Instant.FromUtc(2023, 1, 3, 0, 0);
|
|
|
|
time.Clock = new FakeClock(now);
|
|
|
|
var actual = op
|
|
.Run(input)
|
|
.Select(
|
|
a => string.Format(
|
|
"{0} -- {1} -- {2}",
|
|
a.Get<UPath>().ToString(),
|
|
a.Has<Instant>()
|
|
? time
|
|
.ToDateTime(a.Get<Instant>())
|
|
.ToString("yyyy-MM-dd")
|
|
: "none",
|
|
a.Get<TestModel>().Access))
|
|
.ToList();
|
|
|
|
var expected = new List<string>
|
|
{
|
|
"/chapter-01.md -- 2020-01-01 -- t-1",
|
|
"/chapter-02.md -- 2023-01-02 -- t-2",
|
|
"/chapter-03.md -- none -- private",
|
|
};
|
|
|
|
TestHelper.CompareObjects(expected, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void ManualSetupWorks()
|
|
{
|
|
using TemporalSchedulesTestContext context = this.CreateContext();
|
|
|
|
// Create a numerical series of entities.
|
|
var input = new List<Entity>
|
|
{
|
|
new Entity().SetAll((UPath)"/chapter-01.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-02.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-03.md", new TestModel()),
|
|
};
|
|
|
|
var schedules = new TestRegexSchedule
|
|
{
|
|
Indexes = new Dictionary<int, TestSchedule>
|
|
{
|
|
[1] = new TestSchedule
|
|
{
|
|
ScheduleStart = DateTime.Parse("2023-01-01"),
|
|
Access = "public",
|
|
},
|
|
},
|
|
};
|
|
|
|
// Create the operation and run it, but treat it as being set after the
|
|
// second but before the third item.
|
|
TimeService time = context.Resolve<TimeService>();
|
|
ApplySchedules op = context.Resolve<ApplySchedules>()
|
|
.WithGetSchedules(_ => new ISchedule[] { schedules });
|
|
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
|
|
|
|
time.Clock = new FakeClock(now);
|
|
|
|
var actual = op
|
|
.Run(input)
|
|
.Select(
|
|
a => string.Format(
|
|
"{0} -- {1} -- {2}",
|
|
a.Get<UPath>().ToString(),
|
|
a.Has<Instant>()
|
|
? time
|
|
.ToDateTime(a.Get<Instant>())
|
|
.ToString("yyyy-MM-dd")
|
|
: "none",
|
|
a.Get<TestModel>().Access))
|
|
.ToList();
|
|
|
|
var expected = new List<string>
|
|
{
|
|
"/chapter-01.md -- 2023-01-01 -- public",
|
|
"/chapter-02.md -- 2023-01-08 -- public",
|
|
"/chapter-03.md -- none -- private",
|
|
};
|
|
|
|
TestHelper.CompareObjects(expected, actual);
|
|
}
|
|
|
|
[Fact]
|
|
public void SequencedScheduleWorks()
|
|
{
|
|
using TemporalSchedulesTestContext context = this.CreateContext();
|
|
|
|
// Create a numerical series of entities.
|
|
var input = new List<Entity>
|
|
{
|
|
new Entity().SetAll((UPath)"/chapter-01.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-02.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-03.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-04.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-05.md", new TestModel()),
|
|
new Entity().SetAll((UPath)"/chapter-06.md", new TestModel()),
|
|
};
|
|
|
|
var schedules = new TestRegexSchedule()
|
|
{
|
|
Indexes = new Dictionary<int, TestSchedule>
|
|
{
|
|
[1] = new()
|
|
{
|
|
ScheduleStart = DateTime.Parse("2020-01-01"),
|
|
Access = "subscriber",
|
|
SchedulePeriodTimeSpan = TimeSpan.FromDays(7),
|
|
},
|
|
[3] = new()
|
|
{
|
|
ScheduleStart = DateTime.Parse("2023-01-07"),
|
|
Access = "public",
|
|
SchedulePeriodTimeSpan = TimeSpan.Zero,
|
|
},
|
|
[5] = new()
|
|
{
|
|
SchedulePeriod = "never",
|
|
},
|
|
},
|
|
};
|
|
|
|
// Create the operation and run it, but treat it as being set after the
|
|
// second but before the third item.
|
|
TimeService time = context.Resolve<TimeService>();
|
|
ApplySchedules op = context.Resolve<ApplySchedules>()
|
|
.WithGetSchedules(_ => new ISchedule[] { schedules });
|
|
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
|
|
|
|
time.Clock = new FakeClock(now);
|
|
|
|
var actual = op
|
|
.Run(input)
|
|
.Select(
|
|
a => string.Format(
|
|
"{0} -- {1} -- {2}",
|
|
a.Get<UPath>().ToString(),
|
|
a.Has<Instant>()
|
|
? time
|
|
.ToDateTime(a.Get<Instant>())
|
|
.ToString("yyyy-MM-dd")
|
|
: "none",
|
|
a.Get<TestModel>().Access))
|
|
.ToList();
|
|
|
|
var expected = new List<string>
|
|
{
|
|
"/chapter-01.md -- 2020-01-01 -- subscriber",
|
|
"/chapter-02.md -- 2020-01-08 -- subscriber",
|
|
"/chapter-03.md -- 2023-01-07 -- public",
|
|
"/chapter-04.md -- 2023-01-07 -- public",
|
|
"/chapter-05.md -- none -- private",
|
|
"/chapter-06.md -- none -- private",
|
|
};
|
|
|
|
TestHelper.CompareObjects(expected, actual);
|
|
}
|
|
|
|
public class TestModel
|
|
{
|
|
public string? Access { get; set; } = "private";
|
|
|
|
public TestRegexSchedule? Schedules { get; set; }
|
|
}
|
|
|
|
public class TestRegexSchedule : IndexedPathRegexSchedule<TestSchedule>
|
|
{
|
|
}
|
|
|
|
public class TestSchedule : IndexedSchedule
|
|
{
|
|
public TestSchedule()
|
|
{
|
|
this.SchedulePeriod = "1 week";
|
|
}
|
|
|
|
public string? Access { get; set; }
|
|
|
|
/// <inheritdoc />
|
|
protected override Entity Apply(
|
|
Entity entity,
|
|
int number,
|
|
Instant instant)
|
|
{
|
|
TestModel model = entity.Get<TestModel>();
|
|
model.Access = this.Access;
|
|
return entity.SetAll(instant, model);
|
|
}
|
|
}
|
|
}
|