NEO-29: normalize hotbar API tests to explicit AAA style

Add explicit Arrange/Act/Assert sections to each hotbar API test method to align with the C# test style guide while preserving existing coverage and behavior.
pull/54/head
VinPropane 2026-04-25 22:52:03 -04:00
parent e6f3d63318
commit 3dccab8edb
1 changed files with 50 additions and 16 deletions

View File

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