using NUnit.Framework; using System.Text.Json; using SVSim.EmulatedEntrypoint.Models.Dtos.Common.Guild; using SVSim.EmulatedEntrypoint.Models.Dtos.Guild; namespace SVSim.UnitTests.Wire; [TestFixture] public class GuildWireShape { private static readonly JsonSerializerOptions Opts = new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull, }; [Test] public void EmblemList_serializes_as_array_of_objects_with_emblem_id() { // GuildEmblemListTask.Parse() reads jsonData[i]["emblem_id"].ToLong() // → wire must be an array of objects, each with an "emblem_id" string field. var resp = new GuildEmblemListResponse { EmblemList = new() { new GuildEmblemEntry { EmblemId = 100_000_001L }, new GuildEmblemEntry { EmblemId = 100_000_002L } } }; var json = JsonSerializer.Serialize(resp, Opts); using var doc = JsonDocument.Parse(json); var arr = doc.RootElement.GetProperty("guild_emblem_list"); Assert.That(arr.ValueKind, Is.EqualTo(JsonValueKind.Array)); Assert.That(arr.GetArrayLength(), Is.EqualTo(2)); var first = arr[0]; Assert.That(first.ValueKind, Is.EqualTo(JsonValueKind.Object)); Assert.That(first.GetProperty("emblem_id").ValueKind, Is.EqualTo(JsonValueKind.String)); Assert.That(first.GetProperty("emblem_id").GetString(), Is.EqualTo("100000001")); } private static GuildDetailDto SampleDetail => new() { GuildId = 100_000_001, GuildName = "X", LeaderName = "L", LeaderViewerId = 7, Activity = 1, JoinCondition = 1, MemberNum = 1, GuildEmblemId = 100_000_000L, Description = "", }; [Test] public void GuildUpdate_response_serializes_with_flat_guild_detail() { // GuildUpdateTask.Parse() reads data["guild"] as GuildDetailInfo directly — no "detail" wrapper. var resp = new GuildUpdateResponse { Guild = SampleDetail }; var json = JsonSerializer.Serialize(resp, Opts); using var doc = JsonDocument.Parse(json); var guild = doc.RootElement.GetProperty("guild"); // guild_id must be DIRECTLY under "guild" Assert.That(guild.TryGetProperty("guild_id", out var gid), Is.True, "guild_id must be directly under guild"); Assert.That(gid.GetString(), Is.EqualTo("100000001")); // No nested "detail" wrapper Assert.That(guild.TryGetProperty("detail", out _), Is.False, "no detail wrapper for /guild/update"); } [Test] public void GuildUpdateEmblem_response_serializes_with_nested_detail() { // GuildEmblemUpdateTask.Parse() reads data["guild"]["detail"] — wrapper is required. var resp = new GuildUpdateEmblemResponse { Guild = new GuildDetailSubTree { Detail = SampleDetail } }; var json = JsonSerializer.Serialize(resp, Opts); using var doc = JsonDocument.Parse(json); var guildNode = doc.RootElement.GetProperty("guild"); Assert.That(guildNode.TryGetProperty("detail", out var detail), Is.True, "detail wrapper must exist for /guild/update_emblem"); Assert.That(detail.GetProperty("guild_id").GetString(), Is.EqualTo("100000001")); // guild_id must NOT be directly under "guild" Assert.That(guildNode.TryGetProperty("guild_id", out _), Is.False, "guild_id must be inside detail, not at guild level"); } [Test] public void GuildSearchGuild_response_serializes_with_flat_list_entries() { var resp = new GuildSearchGuildResponse { List = new() { new GuildDetailDto { GuildId = 100_000_001, GuildName = "Alpha", LeaderName = "Lead", LeaderViewerId = 7, Activity = 1, JoinCondition = 1, MemberNum = 5, GuildEmblemId = 100000000, Description = "" } } }; var json = JsonSerializer.Serialize(resp, Opts); using var doc = JsonDocument.Parse(json); var arr = doc.RootElement.GetProperty("list"); Assert.That(arr.ValueKind, Is.EqualTo(JsonValueKind.Array)); Assert.That(arr[0].GetProperty("guild_id").GetString(), Is.EqualTo("100000001")); Assert.That(arr[0].TryGetProperty("detail", out _), Is.False, "search list entries are flat, no detail wrapper"); } [Test] public void GuildInfo_non_joined_serializes_to_prod_shape() { var resp = new GuildInfoResponse { MaxMemberNum = 30, MaxSubLeaderNum = 2, GuildStatus = 0, UsableStampList = Enumerable.Range(100001, 20).Select(i => i.ToString()).ToList(), }; var json = JsonSerializer.Serialize(resp, Opts); using var doc = JsonDocument.Parse(json); var root = doc.RootElement; Assert.That(root.GetProperty("max_member_num").GetString(), Is.EqualTo("30")); Assert.That(root.GetProperty("max_sub_leader_num").GetString(), Is.EqualTo("2")); Assert.That(root.GetProperty("guild_status").GetString(), Is.EqualTo("0")); Assert.That(root.GetProperty("usable_stamp_list").EnumerateArray().Select(e => e.GetString()).First(), Is.EqualTo("100001")); // The four nullable fields MUST NOT appear when null: Assert.That(root.TryGetProperty("guild", out _), Is.False); Assert.That(root.TryGetProperty("join_request_count", out _), Is.False); Assert.That(root.TryGetProperty("invite_count", out _), Is.False); } }