From 7f245b50d6e5a2cfe0e26b46af4434476229bca3 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Sat, 27 Jun 2026 11:07:54 -0400 Subject: [PATCH] feat(guild): add GuildConfig with ShippedDefaults --- SVSim.Database/Models/Config/GuildConfig.cs | 26 ++++++++++++++++ .../Config/GuildConfigDefaultsTests.cs | 31 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 SVSim.Database/Models/Config/GuildConfig.cs create mode 100644 SVSim.UnitTests/Config/GuildConfigDefaultsTests.cs diff --git a/SVSim.Database/Models/Config/GuildConfig.cs b/SVSim.Database/Models/Config/GuildConfig.cs new file mode 100644 index 00000000..bfb5d670 --- /dev/null +++ b/SVSim.Database/Models/Config/GuildConfig.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Linq; + +namespace SVSim.Database.Models.Config; + +/// +/// Guild-feature configuration: membership caps, search caps, stamp palette, +/// and chat-polling intervals. All collection defaults live in +/// (not property initializers) to survive the +/// GameConfigService tier-merge correctly. +/// +[ConfigSection("Guild")] +public sealed class GuildConfig +{ + public int MaxMemberNum { get; init; } = 30; + public int MaxSubLeaderNum { get; init; } = 2; + public int SearchResultCap { get; init; } = 50; + public int ChatPollIdleSeconds { get; init; } = 10; + public int ChatPollActiveSeconds { get; init; } = 3; + public List UsableStampList { get; init; } = new(); + + public static GuildConfig ShippedDefaults() => new() + { + UsableStampList = Enumerable.Range(100001, 20).ToList(), + }; +} diff --git a/SVSim.UnitTests/Config/GuildConfigDefaultsTests.cs b/SVSim.UnitTests/Config/GuildConfigDefaultsTests.cs new file mode 100644 index 00000000..65fef399 --- /dev/null +++ b/SVSim.UnitTests/Config/GuildConfigDefaultsTests.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; +using SVSim.Database.Models.Config; +using System.Linq; + +namespace SVSim.UnitTests.Config; + +[TestFixture] +public class GuildConfigDefaultsTests +{ + [Test] + public void ShippedDefaults_carry_capture_matching_stamps_and_caps() + { + var c = GuildConfig.ShippedDefaults(); + + Assert.That(c.MaxMemberNum, Is.EqualTo(30)); + Assert.That(c.MaxSubLeaderNum, Is.EqualTo(2)); + Assert.That(c.SearchResultCap, Is.EqualTo(50)); + Assert.That(c.UsableStampList, Is.EqualTo(Enumerable.Range(100001, 20).ToList())); + } + + [Test] + public void Property_initializers_alone_leave_stamp_list_empty() + { + // Defensive check: if someone moves UsableStampList default off ShippedDefaults + // and into a property initializer, the config-section tier merge will silently + // empty it. See feedback_config_defaults.md. + var c = new GuildConfig(); + Assert.That(c.UsableStampList, Is.Empty, + "UsableStampList must default empty on property init; populated only by ShippedDefaults()."); + } +}