using System.Net; using System.Net.Http.Json; using System.Text; using Microsoft.AspNetCore.Mvc.Testing; using NeonSprawl.Server.Game.PositionState; using Xunit; namespace NeonSprawl.Server.Tests.Game.PositionState; /// /// NS-16: integration tests for POST /game/players/{{id}}/move on . /// Isolated host per test (fresh in-memory store). /// public class MoveCommandApiTests { [Fact] public async Task PostMove_ShouldPersistTargetAndIncrementSequence_WhenDevPlayerPostsValidMove() { // Arrange using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); var cmd = new MoveCommandRequest { SchemaVersion = MoveCommandRequest.CurrentSchemaVersion, Target = new PositionVector { X = 1.5, Y = -0.5, Z = 2.25 }, }; // Act var beforeMove = await client.GetFromJsonAsync("/game/players/dev-local-1/position"); var postResponse = await client.PostAsJsonAsync("/game/players/dev-local-1/move", cmd); var postBody = await postResponse.Content.ReadFromJsonAsync(); var afterMove = await client.GetFromJsonAsync("/game/players/dev-local-1/position"); // Assert Assert.NotNull(beforeMove); var seq0 = beforeMove!.Sequence; Assert.Equal(HttpStatusCode.OK, postResponse.StatusCode); Assert.NotNull(postBody); Assert.Equal(PositionStateResponse.CurrentSchemaVersion, postBody!.SchemaVersion); Assert.Equal("dev-local-1", postBody.PlayerId); Assert.Equal(seq0 + 1, postBody.Sequence); Assert.Equal(1.5, postBody.Position.X); Assert.Equal(-0.5, postBody.Position.Y); Assert.Equal(2.25, postBody.Position.Z); Assert.NotNull(afterMove); Assert.Equal(postBody.Position.X, afterMove!.Position.X); Assert.Equal(postBody.Position.Y, afterMove.Position.Y); Assert.Equal(postBody.Position.Z, afterMove.Position.Z); Assert.Equal(postBody.Sequence, afterMove.Sequence); } [Fact] public async Task PostMove_ShouldReturnNotFound_WhenPlayerIsUnknown() { // Arrange using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); var cmd = new MoveCommandRequest { SchemaVersion = MoveCommandRequest.CurrentSchemaVersion, Target = new PositionVector { X = 0, Y = 0, Z = 0 }, }; // Act var response = await client.PostAsJsonAsync("/game/players/unknown-player/move", cmd); // Assert Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task PostMove_ShouldReturnBadRequest_WhenSchemaVersionIsWrong() { // Arrange using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); var cmd = new MoveCommandRequest { SchemaVersion = 999, Target = new PositionVector { X = 0, Y = 0, Z = 0 }, }; // Act var response = await client.PostAsJsonAsync("/game/players/dev-local-1/move", cmd); // Assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } [Fact] public async Task PostMove_ShouldReturnBadRequest_WhenTargetIsMissing() { // Arrange using var factory = new WebApplicationFactory(); var client = factory.CreateClient(); var content = new StringContent( "{\"schemaVersion\":1}", Encoding.UTF8, "application/json"); // Act var response = await client.PostAsync("/game/players/dev-local-1/move", content); // Assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } }