diff --git a/server/NeonSprawl.Server.Tests/Game/AbilityInput/HotbarLoadoutApiTests.cs b/server/NeonSprawl.Server.Tests/Game/AbilityInput/HotbarLoadoutApiTests.cs index 0a38c70..4dda54c 100644 --- a/server/NeonSprawl.Server.Tests/Game/AbilityInput/HotbarLoadoutApiTests.cs +++ b/server/NeonSprawl.Server.Tests/Game/AbilityInput/HotbarLoadoutApiTests.cs @@ -11,13 +11,16 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task GetHotbarLoadout_ShouldReturnEightSlots_WhenPlayerKnown() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var response = await client.GetAsync("/game/players/dev-local-1/hotbar-loadout"); - Assert.Equal(HttpStatusCode.OK, response.StatusCode); - var body = await response.Content.ReadFromJsonAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(body); Assert.Equal(HotbarLoadoutResponse.CurrentSchemaVersion, body!.SchemaVersion); Assert.Equal(HotbarLoadoutResponse.SlotCountV1, body.SlotCount); @@ -28,9 +31,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldPersistBindings_AndRoundTripInGet() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -42,16 +47,16 @@ public sealed class HotbarLoadoutApiTests new HotbarSlotBindingJson { SlotIndex = 3, AbilityId = PrototypeAbilityRegistry.PrototypeBurst }, ], }); - Assert.Equal(HttpStatusCode.OK, post.StatusCode); - var postBody = await post.Content.ReadFromJsonAsync(); + var get = await client.GetFromJsonAsync("/game/players/dev-local-1/hotbar-loadout"); + + // Assert + Assert.Equal(HttpStatusCode.OK, post.StatusCode); Assert.NotNull(postBody); Assert.True(postBody!.Updated); Assert.Null(postBody.ReasonCode); Assert.Equal(PrototypeAbilityRegistry.PrototypePulse, postBody.Loadout.Slots[0].AbilityId); Assert.Equal(PrototypeAbilityRegistry.PrototypeBurst, postBody.Loadout.Slots[3].AbilityId); - - var get = await client.GetFromJsonAsync("/game/players/dev-local-1/hotbar-loadout"); Assert.NotNull(get); Assert.Equal(PrototypeAbilityRegistry.PrototypePulse, get!.Slots[0].AbilityId); Assert.Equal(PrototypeAbilityRegistry.PrototypeBurst, get.Slots[3].AbilityId); @@ -60,9 +65,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldDenyOutOfBounds_WithReasonCode() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -70,9 +77,10 @@ public sealed class HotbarLoadoutApiTests SchemaVersion = HotbarLoadoutUpdateRequest.CurrentSchemaVersion, Slots = [new HotbarSlotBindingJson { SlotIndex = 8, AbilityId = PrototypeAbilityRegistry.PrototypePulse }], }); - Assert.Equal(HttpStatusCode.OK, post.StatusCode); - var body = await post.Content.ReadFromJsonAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, post.StatusCode); Assert.NotNull(body); Assert.False(body!.Updated); Assert.Equal(HotbarLoadoutApi.ReasonSlotOutOfBounds, body.ReasonCode); @@ -81,9 +89,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldDenyNegativeSlot_WithReasonCode() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -91,9 +101,10 @@ public sealed class HotbarLoadoutApiTests SchemaVersion = HotbarLoadoutUpdateRequest.CurrentSchemaVersion, Slots = [new HotbarSlotBindingJson { SlotIndex = -1, AbilityId = PrototypeAbilityRegistry.PrototypePulse }], }); - Assert.Equal(HttpStatusCode.OK, post.StatusCode); - var body = await post.Content.ReadFromJsonAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, post.StatusCode); Assert.NotNull(body); Assert.False(body!.Updated); Assert.Equal(HotbarLoadoutApi.ReasonSlotOutOfBounds, body.ReasonCode); @@ -102,9 +113,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldDenyUnknownAbility_WithReasonCode() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -112,9 +125,10 @@ public sealed class HotbarLoadoutApiTests SchemaVersion = HotbarLoadoutUpdateRequest.CurrentSchemaVersion, Slots = [new HotbarSlotBindingJson { SlotIndex = 2, AbilityId = "missing_ability" }], }); - Assert.Equal(HttpStatusCode.OK, post.StatusCode); - var body = await post.Content.ReadFromJsonAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, post.StatusCode); Assert.NotNull(body); Assert.False(body!.Updated); Assert.Equal(HotbarLoadoutApi.ReasonUnknownAbility, body.ReasonCode); @@ -123,9 +137,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldDenyDuplicateSlots_WithReasonCode() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -137,9 +153,10 @@ public sealed class HotbarLoadoutApiTests new HotbarSlotBindingJson { SlotIndex = 1, AbilityId = PrototypeAbilityRegistry.PrototypeGuard }, ], }); - Assert.Equal(HttpStatusCode.OK, post.StatusCode); - var body = await post.Content.ReadFromJsonAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, post.StatusCode); Assert.NotNull(body); Assert.False(body!.Updated); Assert.Equal(HotbarLoadoutApi.ReasonDuplicateSlot, body.ReasonCode); @@ -148,9 +165,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldNormalizeAbilityIdCaseAndWhitespace_WhenKnownAbility() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -158,9 +177,10 @@ public sealed class HotbarLoadoutApiTests SchemaVersion = HotbarLoadoutUpdateRequest.CurrentSchemaVersion, Slots = [new HotbarSlotBindingJson { SlotIndex = 5, AbilityId = " PROTOTYPE_DASH " }], }); - Assert.Equal(HttpStatusCode.OK, post.StatusCode); - var body = await post.Content.ReadFromJsonAsync(); + + // Assert + Assert.Equal(HttpStatusCode.OK, post.StatusCode); Assert.NotNull(body); Assert.True(body!.Updated); Assert.Equal(PrototypeAbilityRegistry.PrototypeDash, body.Loadout.Slots[5].AbilityId); @@ -169,9 +189,11 @@ public sealed class HotbarLoadoutApiTests [Fact] public async Task PostHotbarLoadout_ShouldReturnBadRequest_WhenSchemaVersionWrong() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/dev-local-1/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -180,38 +202,48 @@ public sealed class HotbarLoadoutApiTests Slots = [new HotbarSlotBindingJson { SlotIndex = 0, AbilityId = PrototypeAbilityRegistry.PrototypePulse }], }); + // Assert Assert.Equal(HttpStatusCode.BadRequest, post.StatusCode); } [Fact] public async Task PostHotbarLoadout_ShouldReturnBadRequest_WhenBodyMalformed() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var response = await client.PostAsync( "/game/players/dev-local-1/hotbar-loadout", new StringContent("{\"schemaVersion\":1,\"slots\":[", Encoding.UTF8, "application/json")); + // Assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } [Fact] public async Task GetHotbarLoadout_ShouldReturnNotFound_WhenPlayerUnknown() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var response = await client.GetAsync("/game/players/missing-player/hotbar-loadout"); + + // Assert Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task PostHotbarLoadout_ShouldReturnNotFound_WhenPlayerUnknown() { + // Arrange await using var factory = new InMemoryWebApplicationFactory(); var client = factory.CreateClient(); + // Act var post = await client.PostAsJsonAsync( "/game/players/missing-player/hotbar-loadout", new HotbarLoadoutUpdateRequest @@ -219,6 +251,8 @@ public sealed class HotbarLoadoutApiTests SchemaVersion = HotbarLoadoutUpdateRequest.CurrentSchemaVersion, Slots = [new HotbarSlotBindingJson { SlotIndex = 0, AbilityId = PrototypeAbilityRegistry.PrototypePulse }], }); + + // Assert Assert.Equal(HttpStatusCode.NotFound, post.StatusCode); } }