diff --git a/bruno/neon-sprawl-server/craft/Post craft gather refine make spine.bru b/bruno/neon-sprawl-server/craft/Post craft gather refine make spine.bru index be3ddf6..ee244de 100644 --- a/bruno/neon-sprawl-server/craft/Post craft gather refine make spine.bru +++ b/bruno/neon-sprawl-server/craft/Post craft gather refine make spine.bru @@ -126,7 +126,7 @@ tests { const body = res.getBody(); expect(body.schemaVersion).to.equal(1); expect(body.success).to.equal(true); - expect(body.reasonCode).to.be.undefined; + expect(body.reasonCode).to.equal(null); expect(body.outputsGranted).to.deep.include({ itemId: "field_stim_mk0", quantity: 1 }); expect(body.xpGrantSummary).to.be.an("object"); expect(body.xpGrantSummary.skillId).to.equal("refine"); diff --git a/bruno/neon-sprawl-server/craft/folder.bru b/bruno/neon-sprawl-server/craft/folder.bru index 37a2533..8e412a1 100644 --- a/bruno/neon-sprawl-server/craft/folder.bru +++ b/bruno/neon-sprawl-server/craft/folder.bru @@ -3,5 +3,5 @@ meta { } docs { - NEO-70 craft HTTP. Run order within folder: deny requests (seq 1–4) then spine (seq 5). Full collection runs after dotnet test on shared Postgres — insufficient-materials clears refined stock; spine reuses persisted scrap and tolerates node_depleted gathers. Deny setup requests may use inventory POST only where noted. + NEO-70 craft HTTP. CraftResponse emits explicit null for reasonCode / xpGrantSummary when absent (mirror inventory POST). Run order within folder: deny requests (seq 1–4) then spine (seq 5). Full collection runs after dotnet test on shared Postgres — insufficient-materials clears refined stock; spine reuses persisted scrap and tolerates node_depleted gathers. Deny setup requests may use inventory POST only where noted. } diff --git a/server/NeonSprawl.Server.Tests/Game/Crafting/PlayerCraftApiTests.cs b/server/NeonSprawl.Server.Tests/Game/Crafting/PlayerCraftApiTests.cs index 23f452c..5838719 100644 --- a/server/NeonSprawl.Server.Tests/Game/Crafting/PlayerCraftApiTests.cs +++ b/server/NeonSprawl.Server.Tests/Game/Crafting/PlayerCraftApiTests.cs @@ -104,6 +104,8 @@ public sealed class PlayerCraftApiTests Assert.Equal("refine", body.XpGrantSummary!.SkillId); Assert.Equal(RefineSkillXpConstants.ActivityXpPerCraftRefineCompletion, body.XpGrantSummary.Amount); Assert.Equal(RefineSkillXpConstants.ActivitySourceKind, body.XpGrantSummary.SourceKind); + var json = await response.Content.ReadAsStringAsync(); + Assert.Contains("\"reasonCode\":null", json, StringComparison.Ordinal); } [Fact] @@ -179,6 +181,9 @@ public sealed class PlayerCraftApiTests Assert.Empty(body.InputsConsumed); Assert.Empty(body.OutputsGranted); Assert.Null(body.XpGrantSummary); + var json = await response.Content.ReadAsStringAsync(); + Assert.Contains("\"reasonCode\":\"unknown_recipe\"", json, StringComparison.Ordinal); + Assert.Contains("\"xpGrantSummary\":null", json, StringComparison.Ordinal); } [Fact] diff --git a/server/NeonSprawl.Server/Game/Crafting/CraftWireDtos.cs b/server/NeonSprawl.Server/Game/Crafting/CraftWireDtos.cs index feb87c2..b245f23 100644 --- a/server/NeonSprawl.Server/Game/Crafting/CraftWireDtos.cs +++ b/server/NeonSprawl.Server/Game/Crafting/CraftWireDtos.cs @@ -30,7 +30,6 @@ public sealed class CraftResponse public bool Success { get; init; } [JsonPropertyName("reasonCode")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public string? ReasonCode { get; init; } [JsonPropertyName("inputsConsumed")] @@ -40,7 +39,6 @@ public sealed class CraftResponse public required IReadOnlyList OutputsGranted { get; init; } [JsonPropertyName("xpGrantSummary")] - [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public CraftXpGrantSummaryJson? XpGrantSummary { get; init; } }