172 lines
6.1 KiB
C#
172 lines
6.1 KiB
C#
using Microsoft.AspNetCore.Hosting;
|
|
using NeonSprawl.Server.Game.Mastery;
|
|
|
|
namespace NeonSprawl.Server.Tests.Game.Mastery;
|
|
|
|
public sealed class MasteryFixtureApiTests
|
|
{
|
|
private const string DevPlayer = "dev-local-1";
|
|
private const string FixturePath = $"/game/players/{DevPlayer}/__dev/mastery-fixture";
|
|
|
|
private static MasteryFixtureRequest ValidFixture(
|
|
bool resetPerkState = true,
|
|
Dictionary<string, int>? skillXp = null) =>
|
|
new()
|
|
{
|
|
SchemaVersion = MasteryFixtureRequest.CurrentSchemaVersion,
|
|
ResetPerkState = resetPerkState,
|
|
SkillXp = skillXp ?? new Dictionary<string, int> { ["salvage"] = 0 },
|
|
};
|
|
|
|
private static async Task ArrangeSalvageProgressedWithTier1PickAsync(HttpClient client)
|
|
{
|
|
var grant = await client.PostAsJsonAsync(
|
|
$"/game/players/{DevPlayer}/skill-progression",
|
|
new SkillProgressionGrantRequest
|
|
{
|
|
SchemaVersion = SkillProgressionGrantRequest.CurrentSchemaVersion,
|
|
SkillId = "salvage",
|
|
Amount = 100,
|
|
SourceKind = "activity",
|
|
});
|
|
Assert.Equal(HttpStatusCode.OK, grant.StatusCode);
|
|
var pick = await client.PostAsJsonAsync(
|
|
$"/game/players/{DevPlayer}/perk-state",
|
|
new PerkBranchSelectRequest
|
|
{
|
|
SchemaVersion = PerkBranchSelectRequest.CurrentSchemaVersion,
|
|
SkillId = "salvage",
|
|
TierIndex = 1,
|
|
BranchId = "scrap_efficiency",
|
|
});
|
|
Assert.Equal(HttpStatusCode.OK, pick.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PostMasteryFixture_ShouldReturnNotFound_WhenRouteNotRegistered()
|
|
{
|
|
// Arrange
|
|
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(FixturePath, ValidFixture());
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PostMasteryFixture_ShouldReturnBadRequest_WhenBodyNull()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var client = factory.CreateClient();
|
|
|
|
// Act
|
|
var response = await client.PostAsync(
|
|
FixturePath,
|
|
new StringContent(string.Empty, Encoding.UTF8, "application/json"));
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PostMasteryFixture_ShouldReturnBadRequest_WhenSchemaVersionMismatch()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var client = factory.CreateClient();
|
|
var request = ValidFixture();
|
|
request = new MasteryFixtureRequest
|
|
{
|
|
SchemaVersion = MasteryFixtureRequest.CurrentSchemaVersion + 99,
|
|
ResetPerkState = request.ResetPerkState,
|
|
SkillXp = request.SkillXp,
|
|
};
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync(FixturePath, request);
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PostMasteryFixture_ShouldReturnBadRequest_WhenSkillXpNegative()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var client = factory.CreateClient();
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync(
|
|
FixturePath,
|
|
ValidFixture(skillXp: new Dictionary<string, int> { ["salvage"] = -1 }));
|
|
|
|
// Assert
|
|
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task PostMasteryFixture_ShouldReturnNotFound_WhenPlayerUnknown()
|
|
{
|
|
// Arrange
|
|
await using var factory = new InMemoryWebApplicationFactory();
|
|
var client = factory.CreateClient();
|
|
|
|
// Act
|
|
var response = await client.PostAsJsonAsync(
|
|
"/game/players/missing-player/__dev/mastery-fixture",
|
|
ValidFixture());
|
|
|
|
// 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();
|
|
await ArrangeSalvageProgressedWithTier1PickAsync(client);
|
|
|
|
// Act
|
|
var reset = await client.PostAsJsonAsync(FixturePath, ValidFixture());
|
|
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);
|
|
}
|
|
}
|