NEO-70: Emit explicit nulls on CraftResponse optional fields.
Serialize reasonCode and xpGrantSummary as null when absent so Bruno deny tests match inventory POST wire shape; assert JSON nulls in API tests.pull/104/head
parent
2221dc6b4b
commit
87c27e231b
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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<CraftIoAppliedJson> OutputsGranted { get; init; }
|
||||
|
||||
[JsonPropertyName("xpGrantSummary")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public CraftXpGrantSummaryJson? XpGrantSummary { get; init; }
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue