119 lines
3.6 KiB
C#
119 lines
3.6 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using NeonSprawl.Server.Game.Combat;
|
|
using NeonSprawl.Server.Tests;
|
|
using Xunit;
|
|
|
|
namespace NeonSprawl.Server.Tests.Game.Combat;
|
|
|
|
public sealed class PlayerCombatHealthStoreTests
|
|
{
|
|
[Fact]
|
|
public void TryGet_ShouldLazyInitToMaxHp_OnFirstAccess()
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
// Act
|
|
var ok = store.TryGet("dev-local-1", out var snapshot);
|
|
// Assert
|
|
Assert.True(ok);
|
|
Assert.Equal("dev-local-1", snapshot.PlayerId);
|
|
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.MaxHp);
|
|
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
|
|
Assert.False(snapshot.Defeated);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryApplyDamage_ShouldDecreaseHp_AndFloorAtZero()
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
// Act
|
|
var ok = store.TryApplyDamage("dev-local-1", 15, out var snapshot);
|
|
// Assert
|
|
Assert.True(ok);
|
|
Assert.Equal(85, snapshot.CurrentHp);
|
|
Assert.False(snapshot.Defeated);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryApplyDamage_ShouldMarkDefeated_WhenHpReachesZero()
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
// Act
|
|
var ok = store.TryApplyDamage("dev-local-1", 100, out var snapshot);
|
|
// Assert
|
|
Assert.True(ok);
|
|
Assert.Equal(0, snapshot.CurrentHp);
|
|
Assert.True(snapshot.Defeated);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryApplyDamage_ShouldKeepHpAtZero_WhenAlreadyDefeated()
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
_ = store.TryApplyDamage("dev-local-1", 100, out _);
|
|
// Act
|
|
var ok = store.TryApplyDamage("dev-local-1", 25, out var snapshot);
|
|
// Assert
|
|
Assert.True(ok);
|
|
Assert.Equal(0, snapshot.CurrentHp);
|
|
Assert.True(snapshot.Defeated);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryResetToFull_ShouldRestoreMaxHp()
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
_ = store.TryApplyDamage("dev-local-1", 40, out _);
|
|
// Act
|
|
var ok = store.TryResetToFull("dev-local-1", out var snapshot);
|
|
// Assert
|
|
Assert.True(ok);
|
|
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
|
|
Assert.False(snapshot.Defeated);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null)]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
public void TryGet_ShouldReturnFalse_WhenPlayerIdInvalid(string? playerId)
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
// Act
|
|
var ok = store.TryGet(playerId, out var snapshot);
|
|
// Assert
|
|
Assert.False(ok);
|
|
Assert.Equal(default, snapshot);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryApplyDamage_ShouldReturnFalse_WhenDamageNegative()
|
|
{
|
|
// Arrange
|
|
var store = new InMemoryPlayerCombatHealthStore();
|
|
// Act
|
|
var ok = store.TryApplyDamage("dev-local-1", -1, out var snapshot);
|
|
// Assert
|
|
Assert.False(ok);
|
|
Assert.Equal(default, snapshot);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Host_ShouldResolvePlayerCombatHealthStoreFromDi_WhenStartupSucceeds()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
// Act
|
|
var store = factory.Services.GetRequiredService<IPlayerCombatHealthStore>();
|
|
// Assert
|
|
Assert.NotNull(store);
|
|
Assert.True(store.TryGet("dev-local-1", out var snapshot));
|
|
Assert.Equal(PlayerCombatHealthDefaults.MaxHp, snapshot.CurrentHp);
|
|
}
|
|
}
|