-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEventsHostedServiceTickTests.cs
More file actions
70 lines (62 loc) · 2.82 KB
/
Copy pathEventsHostedServiceTickTests.cs
File metadata and controls
70 lines (62 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using NSubstitute;
using RustPlusBot.Abstractions.Events;
using RustPlusBot.Abstractions.Time;
using RustPlusBot.Features.Connections;
using RustPlusBot.Features.Events.Hosting;
using RustPlusBot.Features.Events.State;
namespace RustPlusBot.Features.Events.Tests.Hosting;
public sealed class EventsHostedServiceTickTests
{
[Fact]
public async Task TickOnce_publishes_a_crate_lootable_event_when_active_window_elapsed()
{
var clock = new TestClock();
var options = Options.Create(new ConnectionOptions());
var rigStore = new RigStateStore(clock, options);
var bus = Substitute.For<IEventBus>();
var server = Guid.NewGuid();
rigStore.Apply(new RigStateChangedEvent(1UL, server, RigKind.Small, RigEventKind.Activated, 1f, 2f, null));
clock.UtcNow = clock.UtcNow.Add(options.Value.RigActiveWindow);
var service = EventsHostedServiceTestAccess.Create(bus, rigStore, clock, options);
await service.TickOnceAsync(CancellationToken.None);
await bus.Received(1).PublishAsync(
Arg.Is<RigStateChangedEvent>(e => e!.Kind == RigEventKind.CrateLootable && e.Rig == RigKind.Small),
Arg.Any<CancellationToken>());
}
private sealed class TestClock : IClock
{
public DateTimeOffset UtcNow { get; set; } = new(2026, 6, 17, 12, 0, 0, TimeSpan.Zero);
}
}
/// <summary>Test-only factory that constructs <see cref="EventsHostedService"/> with minimal real dependencies.</summary>
internal static class EventsHostedServiceTestAccess
{
/// <summary>Creates an <see cref="EventsHostedService"/> wired to the provided bus, rig store, clock, and options.
/// Dependencies not exercised by <see cref="EventsHostedService.TickOnceAsync"/> are stubbed.</summary>
/// <param name="eventBus">The event bus to publish crossings on.</param>
/// <param name="rigStore">The rig state store to advance.</param>
/// <param name="clock">Supplies the current time.</param>
/// <param name="options">Supplies rig timing windows.</param>
/// <returns>A constructed <see cref="EventsHostedService"/>.</returns>
internal static EventsHostedService Create(
IEventBus eventBus,
RigStateStore rigStore,
IClock clock,
IOptions<ConnectionOptions> options)
{
var eventStateStore = new EventStateStore(clock);
var scopeFactory = Substitute.For<IServiceScopeFactory>();
var logger = NullLogger<EventsHostedService>.Instance;
return new EventsHostedService(
eventBus,
relay: null!,
new EventStores(eventStateStore, rigStore),
clock,
options,
scopeFactory,
logger);
}
}