using System; using System.IO; using System.Text.Json; using CounterDrone.Core; using CounterDrone.Core.Algorithms; using CounterDrone.Core.Services; using Xunit; namespace CounterDrone.Core.Tests { public class ConfigServiceTests : IDisposable { private readonly string _testDir; private readonly IPathProvider _paths; private readonly ConfigService _config; private readonly SQLite.SQLiteConnection _db; public ConfigServiceTests() { _testDir = Path.Combine(Path.GetTempPath(), $"cd_cfg_{Guid.NewGuid():N}"); _paths = new TestPathProvider(_testDir); var dbm = new DatabaseManager(_paths); _db = dbm.OpenMainDb(); _config = new ConfigService(_paths, _db); } public void Dispose() { _db?.Close(); if (Directory.Exists(_testDir)) Directory.Delete(_testDir, true); } [Fact] public void GetPlannerConfigJson_ReturnsValidJson() { var json = _config.GetPlannerConfigJson(); var cfg = JsonSerializer.Deserialize(json, new JsonSerializerOptions { Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }, PropertyNameCaseInsensitive = true, }); Assert.NotNull(cfg); Assert.True(cfg.CloudOverlapRatio >= 0); } [Fact] public void SavePlannerConfig_PersistsAndReloads() { var original = _config.GetPlannerConfigJson(); var cfg = JsonSerializer.Deserialize(original, new JsonSerializerOptions { Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }, PropertyNameCaseInsensitive = true, })!; cfg.CloudOverlapRatio = 0.3f; var modifiedJson = JsonSerializer.Serialize(cfg, new JsonSerializerOptions { Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }, }); _config.SavePlannerConfig(modifiedJson); var reloaded = _config.GetPlannerConfigJson(); var reloadedCfg = JsonSerializer.Deserialize(reloaded, new JsonSerializerOptions { Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }, PropertyNameCaseInsensitive = true, })!; Assert.Equal(0.3f, reloadedCfg.CloudOverlapRatio); } [Fact] public void PlannerConfigReloaded_EventFires() { PlannerConfig? received = null; _config.PlannerConfigReloaded += cfg => received = cfg; var json = _config.GetPlannerConfigJson(); _config.SavePlannerConfig(json); Assert.NotNull(received); Assert.True(received.CloudOverlapRatio >= 0); } [Fact] public void Reload_FromDiskRefreshesConfig() { // 直接改文件 var path = Path.Combine(_testDir, "planner_config.json"); var json = File.ReadAllText(path); var cfg = JsonSerializer.Deserialize(json, new JsonSerializerOptions { Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }, PropertyNameCaseInsensitive = true, })!; cfg.ExpansionFactor = 0.8f; File.WriteAllText(path, JsonSerializer.Serialize(cfg, new JsonSerializerOptions { Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }, })); PlannerConfig? received = null; _config.PlannerConfigReloaded += cfg => received = cfg; _config.Reload(); Assert.NotNull(received); Assert.Equal(0.8f, received.ExpansionFactor); } [Fact] public void GetDefaultsJson_ReturnsValidJson() { var json = _config.GetDefaultsJson(); Assert.Contains("ammunition", json.ToLower()); } } }