fix(guild_chat): wait_interval as raw int + capture-replay request field name

Remove StringifiedIntConverter from GuildChatMessagesResponse.WaitInterval so the
wire emits a raw JSON number (3) matching prod, not a quoted string ("3").
Update GuildChatPollTests (2 assertions) and GuildCaptureReplayTests (1 assertion +
comment) to expect JsonValueKind.Number. Fix last_message_id → start_message_id typo
in GuildChatMessages_Member_ReturnsProdShape request body.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
gamer147
2026-06-27 15:40:30 -04:00
parent 6467223b52
commit 754b2ca466
3 changed files with 15 additions and 18 deletions

View File

@@ -1,6 +1,5 @@
using MessagePack;
using System.Text.Json.Serialization;
using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
using SVSim.EmulatedEntrypoint.Models.Dtos.Common.Guild;
namespace SVSim.EmulatedEntrypoint.Models.Dtos.GuildChat;
@@ -25,7 +24,7 @@ public class GuildChatMessagesResponse
public List<ChatMessageDto> ChatMessage { get; set; } = new();
/// <summary>Server-driven polling interval in seconds. Client uses this for the next poll.</summary>
[JsonPropertyName("wait_interval"), Key("wait_interval"), JsonConverter(typeof(StringifiedIntConverter)),
[JsonPropertyName("wait_interval"), Key("wait_interval"),
JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public int WaitInterval { get; set; }
}

View File

@@ -215,11 +215,11 @@ public class GuildCaptureReplayTests
Assert.That(createResp.IsSuccessStatusCode, Is.True,
$"guild/create failed: {await createResp.Content.ReadAsStringAsync()}");
// Poll messages — last_message_id=0 means "give me everything"
// Poll messages — start_message_id=0 means "give me everything"
var resp = await client.PostAsync("/guild_chat/messages",
JsonContent.Create(new
{
last_message_id = 0,
start_message_id = 0,
viewer_id = Vid, steam_id = Sid, steam_session_ticket = Stk,
}));
@@ -236,17 +236,12 @@ public class GuildCaptureReplayTests
Assert.That(chatArr.ValueKind, Is.EqualTo(JsonValueKind.Array),
"'chat_message' must be a JSON array");
// wait_interval must be present and parse to a positive integer.
// Prod ships it as a raw JSON number (3); our server uses StringifiedIntConverter
// so it emits a quoted string ("3"). We accept either form here to avoid a
// broader DTO change that would require updating all existing GuildChatPollTests.
// wait_interval must be a raw JSON number matching prod (prod sends 3, not "3").
Assert.That(root.TryGetProperty("wait_interval", out var waitEl), Is.True,
"Response must have 'wait_interval' field");
int waitValue = waitEl.ValueKind == JsonValueKind.Number
? waitEl.GetInt32()
: int.Parse(waitEl.GetString()!);
Assert.That(waitValue, Is.GreaterThan(0),
"'wait_interval' must be positive");
Assert.That(waitEl.ValueKind, Is.EqualTo(JsonValueKind.Number),
"'wait_interval' must be a raw JSON number (prod sends 3, not \"3\")");
Assert.That(waitEl.GetInt32(), Is.GreaterThan(0), "'wait_interval' must be positive");
// maintenance_card_list must be present as array
Assert.That(root.TryGetProperty("maintenance_card_list", out var maintArr), Is.True,

View File

@@ -330,9 +330,12 @@ public class GuildChatPollTests
Assert.That(messages.GetArrayLength(), Is.EqualTo(0),
"chat_message must be empty for a viewer not in a guild");
// wait_interval is stringified; idle default is ChatPollIdleSeconds (10)
int waitInterval = GetStringifiedInt(root, "wait_interval");
Assert.That(waitInterval, Is.GreaterThan(0), "wait_interval must be positive");
// wait_interval is a raw JSON number; idle default is ChatPollIdleSeconds (10)
Assert.That(root.TryGetProperty("wait_interval", out var waitEl), Is.True,
"Response must have 'wait_interval' field");
Assert.That(waitEl.ValueKind, Is.EqualTo(JsonValueKind.Number),
"'wait_interval' must be a raw JSON number (prod sends 3, not \"3\")");
Assert.That(waitEl.GetInt32(), Is.GreaterThan(0), "wait_interval must be positive");
}
// =========================================================================
@@ -354,11 +357,11 @@ public class GuildChatPollTests
// Leader gets messages → active interval
var activePoll = await PollAsync(leaderClient, startMessageId: 0, direction: 1);
int activeWait = GetStringifiedInt(activePoll, "wait_interval");
int activeWait = activePoll.GetProperty("wait_interval").GetInt32();
// Lonely viewer not in a guild → idle interval
var idlePoll = await PollAsync(lonelyClient, startMessageId: 0, direction: 1);
int idleWait = GetStringifiedInt(idlePoll, "wait_interval");
int idleWait = idlePoll.GetProperty("wait_interval").GetInt32();
Assert.That(activeWait, Is.LessThan(idleWait),
$"Active interval ({activeWait}s) must be less than idle interval ({idleWait}s)");