using System.IO; using System.Text.Json; using OneClickRun.Models; using OneClickRun.Services; using Xunit; namespace OneClickRun.Tests; public class ConfigServiceTests { private static string NewTempDir() => Path.Combine(Path.GetTempPath(), "OneClickRunTests", Guid.NewGuid().ToString("N")); [Fact] public void SaveAndLoadRoundTrip() { var dir = NewTempDir(); try { var service = new ConfigService(dir); service.Load(); // 首次运行生成默认配置 Assert.True(service.WasFirstRun); Assert.Equal(4, service.Current.Items.Count); service.Current.General.Theme = ThemeMode.Dark; service.Current.General.TriggerMode = TriggerMode.Hold; service.Current.General.SelectionMode = SelectionMode.Swipe; service.Current.General.Hotkey = new HotkeyBinding { Modifiers = { "Ctrl", "Shift" }, Key = "F9" }; service.Current.Items[0].Name = "改名后的指令"; service.Save(); var reloaded = new ConfigService(dir); reloaded.Load(); Assert.False(reloaded.WasFirstRun); Assert.Equal(ThemeMode.Dark, reloaded.Current.General.Theme); Assert.Equal(TriggerMode.Hold, reloaded.Current.General.TriggerMode); Assert.Equal(SelectionMode.Swipe, reloaded.Current.General.SelectionMode); Assert.Equal("Ctrl+Shift+F9", reloaded.Current.General.HotkeyText); Assert.Equal("改名后的指令", reloaded.Current.Items[0].Name); Assert.Equal(service.Current.Items.Count, reloaded.Current.Items.Count); } finally { try { Directory.Delete(dir, recursive: true); } catch { } } } [Fact] public void CorruptConfigIsBackedUpAndRebuilt() { var dir = NewTempDir(); try { Directory.CreateDirectory(dir); var path = Path.Combine(dir, "config.json"); File.WriteAllText(path, "{ 这不是合法的 JSON"); var service = new ConfigService(dir); service.Load(); Assert.True(File.Exists(path)); Assert.Contains("\"General\"", File.ReadAllText(path)); Assert.Single(Directory.GetFiles(dir, "config.broken-*.json")); Assert.True(service.WasFirstRun); Assert.NotNull(service.Current.General); Assert.NotNull(service.Current.Items); } finally { try { Directory.Delete(dir, recursive: true); } catch { } } } [Fact] public void MissingFieldsAreRepaired() { var dir = NewTempDir(); try { Directory.CreateDirectory(dir); // General 缺失、Items 缺失、item 内字段缺失 var json = JsonSerializer.Serialize(new { version = 1 }); File.WriteAllText(Path.Combine(dir, "config.json"), json); var service = new ConfigService(dir); service.Load(); Assert.False(service.WasFirstRun); Assert.NotNull(service.Current.General); Assert.NotNull(service.Current.General.Hotkey); Assert.Empty(service.Current.Items); } finally { try { Directory.Delete(dir, recursive: true); } catch { } } } [Fact] public void EnumValuesAreSerializedAsStrings() { var service = new ConfigService(NewTempDir()); service.Load(); service.Current.General.Theme = ThemeMode.System; service.Current.Items.Add(new WheelItem { Type = WheelItemType.Script, Name = "测试", Path = "a.ps1" }); service.Save(); var json = File.ReadAllText(service.ConfigPath); Assert.Contains("\"System\"", json); Assert.Contains("\"Script\"", json); try { Directory.Delete(service.ConfigDirectory, recursive: true); } catch { } } }