neon-sprawl/server/NeonSprawl.Server.Tests/Game/Encounters/InMemoryEncounterCompleteEv...

68 lines
2.3 KiB
C#

using NeonSprawl.Server.Game.Encounters;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Encounters;
public sealed class InMemoryEncounterCompleteEventStoreTests
{
private const string PlayerId = "dev-local-1";
private const string EncounterId = "prototype_combat_pocket";
private static readonly DateTimeOffset CompletedAt = new(2026, 5, 31, 20, 0, 0, TimeSpan.Zero);
[Fact]
public void TryRecord_ShouldBeIdempotent_AtStoreLayer()
{
// Arrange
var store = new InMemoryEncounterCompleteEventStore();
var completeEvent = CreatePrototypeEvent();
// Act
var first = store.TryRecord(completeEvent);
var second = store.TryRecord(completeEvent with { CompletedAt = CompletedAt.AddHours(1) });
// Assert
Assert.True(first);
Assert.False(second);
Assert.True(store.TryGet(PlayerId, EncounterId, out var stored));
Assert.Equal(completeEvent.IdempotencyKey, stored.IdempotencyKey);
Assert.Equal(CompletedAt, stored.CompletedAt);
Assert.Equal(2, stored.GrantedItems.Count);
}
[Fact]
public void TryRecord_ShouldFailClosed_WhenPlayerIdIsEmpty()
{
// Arrange
var store = new InMemoryEncounterCompleteEventStore();
var invalidEvent = CreatePrototypeEvent() with { PlayerId = " " };
// Act
var recorded = store.TryRecord(invalidEvent);
// Assert
Assert.False(recorded);
Assert.False(store.TryGet(" ", EncounterId, out _));
}
[Fact]
public void TryRecord_ShouldFailClosed_WhenEncounterIdIsEmpty()
{
// Arrange
var store = new InMemoryEncounterCompleteEventStore();
var invalidEvent = CreatePrototypeEvent() with { EncounterId = " " };
// Act
var recorded = store.TryRecord(invalidEvent);
// Assert
Assert.False(recorded);
Assert.False(store.TryGet(PlayerId, " ", out _));
}
private static EncounterCompleteEvent CreatePrototypeEvent() =>
new(
PlayerId,
EncounterId,
"prototype_combat_pocket_clear",
[
new EncounterGrantApplied("scrap_metal_bulk", 10),
new EncounterGrantApplied("contract_handoff_token", 1),
],
CompletedAt,
$"{PlayerId}:{EncounterId}");
}