NEO-48: omit null reasonCode from success JSON responses

WhenWritingNull on PerkBranchSelectResponse and SkillProgressionGrantResponse
matches hotbar/cast/interaction; fixes Bruno tier1 undefined check.
pull/83/head
VinPropane 2026-05-17 20:46:28 -04:00
parent e9c02eded7
commit aa83790703
4 changed files with 11 additions and 1 deletions

View File

@ -6,6 +6,7 @@ meta {
docs {
NEO-48: tier-1 salvage branch pick. Run skill-progression grant (100+ XP for level 2) first if this denies level_too_low.
On success, reasonCode is omitted from JSON (not null); test expects undefined.
}
post {

View File

@ -2,6 +2,7 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Json;
using System.Text;
using NeonSprawl.Server.Game.Mastery;
using NeonSprawl.Server.Game.Skills;
@ -156,7 +157,13 @@ public sealed class PerkStateApiTests
// Assert
Assert.Equal(HttpStatusCode.OK, post.StatusCode);
var envelope = await post.Content.ReadFromJsonAsync<PerkBranchSelectResponse>();
var json = await post.Content.ReadAsStringAsync();
using (var doc = JsonDocument.Parse(json))
{
Assert.False(doc.RootElement.TryGetProperty("reasonCode", out _));
}
var envelope = JsonSerializer.Deserialize<PerkBranchSelectResponse>(json);
Assert.NotNull(envelope);
Assert.True(envelope!.Selected);
Assert.Null(envelope.ReasonCode);

View File

@ -69,6 +69,7 @@ public sealed class PerkBranchSelectResponse
public bool Selected { get; init; }
[JsonPropertyName("reasonCode")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ReasonCode { get; init; }
[JsonPropertyName("perkState")]

View File

@ -34,6 +34,7 @@ public sealed class SkillProgressionGrantResponse
/// <remarks>Set when <see cref="Granted"/> is <c>false</c>; stable snake_case values (see README).</remarks>
[JsonPropertyName("reasonCode")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? ReasonCode { get; init; }
[JsonPropertyName("progression")]