neon-sprawl/server/NeonSprawl.Server.Tests/Game/Mastery/MasteryFixtureApiTests.cs

104 lines
4.1 KiB
C#

using System.Net;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Skills;
using Xunit;
namespace NeonSprawl.Server.Tests.Game.Mastery;
public sealed class MasteryFixtureApiTests
{
private const string DevPlayer = "dev-local-1";
[Fact]
public async Task PostMasteryFixture_ShouldReturnNotFound_WhenRouteNotRegistered()
{
// Arrange — Production + fixture flag off => endpoint not mapped
await using var factory = new InMemoryWebApplicationFactory();
var client = factory.WithWebHostBuilder(b =>
{
b.UseEnvironment("Production");
b.UseSetting("Game:EnableMasteryFixtureApi", "false");
}).CreateClient();
// Act
var response = await client.PostAsJsonAsync(
$"/game/players/{DevPlayer}/__dev/mastery-fixture",
new MasteryFixtureRequest
{
SchemaVersion = MasteryFixtureRequest.CurrentSchemaVersion,
ResetPerkState = true,
SkillXp = new Dictionary<string, int> { ["salvage"] = 0 },
});
// Assert
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Fact]
public async Task PostMasteryFixture_ShouldResetSalvageXpAndPerkState_ThenLevelTooLowDenies()
{
// Arrange
await using var factory = new InMemoryWebApplicationFactory();
var client = factory.CreateClient();
Assert.Equal(HttpStatusCode.OK, (await client.PostAsJsonAsync(
$"/game/players/{DevPlayer}/skill-progression",
new SkillProgressionGrantRequest
{
SchemaVersion = SkillProgressionGrantRequest.CurrentSchemaVersion,
SkillId = "salvage",
Amount = 100,
SourceKind = "activity",
})).StatusCode);
Assert.Equal(HttpStatusCode.OK, (await client.PostAsJsonAsync(
$"/game/players/{DevPlayer}/perk-state",
new PerkBranchSelectRequest
{
SchemaVersion = PerkBranchSelectRequest.CurrentSchemaVersion,
SkillId = "salvage",
TierIndex = 1,
BranchId = "scrap_efficiency",
})).StatusCode);
// Act
var reset = await client.PostAsJsonAsync(
$"/game/players/{DevPlayer}/__dev/mastery-fixture",
new MasteryFixtureRequest
{
SchemaVersion = MasteryFixtureRequest.CurrentSchemaVersion,
ResetPerkState = true,
SkillXp = new Dictionary<string, int> { ["salvage"] = 0 },
});
var deny = await client.PostAsJsonAsync(
$"/game/players/{DevPlayer}/perk-state",
new PerkBranchSelectRequest
{
SchemaVersion = PerkBranchSelectRequest.CurrentSchemaVersion,
SkillId = "salvage",
TierIndex = 1,
BranchId = "scrap_efficiency",
});
// Assert
Assert.Equal(HttpStatusCode.OK, reset.StatusCode);
var resetBody = await reset.Content.ReadFromJsonAsync<MasteryFixtureResponse>();
Assert.NotNull(resetBody);
Assert.True(resetBody!.Applied);
var progression = await client.GetFromJsonAsync<SkillProgressionSnapshotResponse>(
$"/game/players/{DevPlayer}/skill-progression");
var salvage = Assert.Single(progression!.Skills!, static s => s.Id == "salvage");
Assert.Equal(0, salvage.Xp);
Assert.Equal(1, salvage.Level);
var perkGet = await client.GetFromJsonAsync<PerkStateSnapshotResponse>(
$"/game/players/{DevPlayer}/perk-state");
Assert.Empty(perkGet!.BranchPicks);
Assert.Equal(HttpStatusCode.OK, deny.StatusCode);
var envelope = await deny.Content.ReadFromJsonAsync<PerkBranchSelectResponse>();
Assert.NotNull(envelope);
Assert.False(envelope!.Selected);
Assert.Equal(PerkUnlockReasonCodes.LevelTooLow, envelope.ReasonCode);
}
}