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:
@@ -1,6 +1,5 @@
|
|||||||
using MessagePack;
|
using MessagePack;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Common;
|
|
||||||
using SVSim.EmulatedEntrypoint.Models.Dtos.Common.Guild;
|
using SVSim.EmulatedEntrypoint.Models.Dtos.Common.Guild;
|
||||||
|
|
||||||
namespace SVSim.EmulatedEntrypoint.Models.Dtos.GuildChat;
|
namespace SVSim.EmulatedEntrypoint.Models.Dtos.GuildChat;
|
||||||
@@ -25,7 +24,7 @@ public class GuildChatMessagesResponse
|
|||||||
public List<ChatMessageDto> ChatMessage { get; set; } = new();
|
public List<ChatMessageDto> ChatMessage { get; set; } = new();
|
||||||
|
|
||||||
/// <summary>Server-driven polling interval in seconds. Client uses this for the next poll.</summary>
|
/// <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)]
|
JsonIgnore(Condition = JsonIgnoreCondition.Never)]
|
||||||
public int WaitInterval { get; set; }
|
public int WaitInterval { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -215,11 +215,11 @@ public class GuildCaptureReplayTests
|
|||||||
Assert.That(createResp.IsSuccessStatusCode, Is.True,
|
Assert.That(createResp.IsSuccessStatusCode, Is.True,
|
||||||
$"guild/create failed: {await createResp.Content.ReadAsStringAsync()}");
|
$"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",
|
var resp = await client.PostAsync("/guild_chat/messages",
|
||||||
JsonContent.Create(new
|
JsonContent.Create(new
|
||||||
{
|
{
|
||||||
last_message_id = 0,
|
start_message_id = 0,
|
||||||
viewer_id = Vid, steam_id = Sid, steam_session_ticket = Stk,
|
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),
|
Assert.That(chatArr.ValueKind, Is.EqualTo(JsonValueKind.Array),
|
||||||
"'chat_message' must be a JSON array");
|
"'chat_message' must be a JSON array");
|
||||||
|
|
||||||
// wait_interval must be present and parse to a positive integer.
|
// wait_interval must be a raw JSON number matching prod (prod sends 3, not "3").
|
||||||
// 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.
|
|
||||||
Assert.That(root.TryGetProperty("wait_interval", out var waitEl), Is.True,
|
Assert.That(root.TryGetProperty("wait_interval", out var waitEl), Is.True,
|
||||||
"Response must have 'wait_interval' field");
|
"Response must have 'wait_interval' field");
|
||||||
int waitValue = waitEl.ValueKind == JsonValueKind.Number
|
Assert.That(waitEl.ValueKind, Is.EqualTo(JsonValueKind.Number),
|
||||||
? waitEl.GetInt32()
|
"'wait_interval' must be a raw JSON number (prod sends 3, not \"3\")");
|
||||||
: int.Parse(waitEl.GetString()!);
|
Assert.That(waitEl.GetInt32(), Is.GreaterThan(0), "'wait_interval' must be positive");
|
||||||
Assert.That(waitValue, Is.GreaterThan(0),
|
|
||||||
"'wait_interval' must be positive");
|
|
||||||
|
|
||||||
// maintenance_card_list must be present as array
|
// maintenance_card_list must be present as array
|
||||||
Assert.That(root.TryGetProperty("maintenance_card_list", out var maintArr), Is.True,
|
Assert.That(root.TryGetProperty("maintenance_card_list", out var maintArr), Is.True,
|
||||||
|
|||||||
@@ -330,9 +330,12 @@ public class GuildChatPollTests
|
|||||||
Assert.That(messages.GetArrayLength(), Is.EqualTo(0),
|
Assert.That(messages.GetArrayLength(), Is.EqualTo(0),
|
||||||
"chat_message must be empty for a viewer not in a guild");
|
"chat_message must be empty for a viewer not in a guild");
|
||||||
|
|
||||||
// wait_interval is stringified; idle default is ChatPollIdleSeconds (10)
|
// wait_interval is a raw JSON number; idle default is ChatPollIdleSeconds (10)
|
||||||
int waitInterval = GetStringifiedInt(root, "wait_interval");
|
Assert.That(root.TryGetProperty("wait_interval", out var waitEl), Is.True,
|
||||||
Assert.That(waitInterval, Is.GreaterThan(0), "wait_interval must be positive");
|
"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
|
// Leader gets messages → active interval
|
||||||
var activePoll = await PollAsync(leaderClient, startMessageId: 0, direction: 1);
|
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
|
// Lonely viewer not in a guild → idle interval
|
||||||
var idlePoll = await PollAsync(lonelyClient, startMessageId: 0, direction: 1);
|
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),
|
Assert.That(activeWait, Is.LessThan(idleWait),
|
||||||
$"Active interval ({activeWait}s) must be less than idle interval ({idleWait}s)");
|
$"Active interval ({activeWait}s) must be less than idle interval ({idleWait}s)");
|
||||||
|
|||||||
Reference in New Issue
Block a user