using System; using System.IO; using System.Linq; using PolyTrader.Core.Configuration; using PolyTraderSharp.Models; using Xunit; namespace PolyTrader.Tests { /// /// Fortschreiben der server_settings.xml zur Laufzeit (#560). Der Kern ist, was NICHT passieren darf: /// dass eine unlesbare Datei still durch Vorgaben ersetzt wird und gespeicherte Schlüssel verschwinden. /// public sealed class ServerSettingsFileTests : IDisposable { private readonly string _dir = Path.Combine(Path.GetTempPath(), "polytrader-settings-" + Guid.NewGuid().ToString("N")); private string SettingsPath => Path.Combine(_dir, "server_settings.xml"); public ServerSettingsFileTests() => Directory.CreateDirectory(_dir); public void Dispose() { try { Directory.Delete(_dir, recursive: true); } catch { } } [Fact] public void Fehlende_Datei_liefert_Vorgaben_und_wird_beim_Schreiben_angelegt() { var file = new ServerSettingsFile(SettingsPath); Assert.Empty(file.Read().DisabledModules); file.Update(s => s.DisabledModules.Add("Supervisor")); Assert.Equal(new[] { "Supervisor" }, ServerSettings.Load(SettingsPath).DisabledModules); } [Fact] public void Update_aendert_nur_das_eine_Feld() { new ServerSettings { LicenseKey = "enc:v1:L", WatchdogToken = "enc:v1:W", MullvadAccount = "1234", VpnLocation = "cz" } .Save(SettingsPath); new ServerSettingsFile(SettingsPath).Update(s => s.VpnLocation = "se"); var written = ServerSettings.Load(SettingsPath); Assert.Equal("se", written.VpnLocation); Assert.Equal("enc:v1:L", written.LicenseKey); Assert.Equal("enc:v1:W", written.WatchdogToken); Assert.Equal("1234", written.MullvadAccount); } [Fact] public void Unlesbare_Datei_wird_nicht_ueberschrieben() { const string kaputt = "enc:v1:L(() => file.Read()); var ex = Assert.Throws(() => file.Update(s => s.VpnLocation = "se")); Assert.Contains("nicht lesbar", ex.Message); Assert.Equal(kaputt, File.ReadAllText(SettingsPath)); // Zum Vergleich das Verhalten, vor dem das schützt: Load liefert still Vorgaben. Assert.Equal(string.Empty, ServerSettings.Load(SettingsPath).LicenseKey); } [Fact] public void Kein_Rest_einer_Zwischendatei_bleibt_liegen() { var file = new ServerSettingsFile(SettingsPath); file.Update(s => s.VpnLocation = "se"); file.Update(s => s.VpnLocation = "de"); Assert.Equal(new[] { "server_settings.xml" }, Directory.GetFiles(_dir).Select(Path.GetFileName).ToArray()); } [Fact] public void Dateirechte_bleiben_unter_Linux_erhalten() { if (OperatingSystem.IsWindows()) return; // NTFS-Rechte vererben sich, dort ist nichts zu tun new ServerSettings().Save(SettingsPath); File.SetUnixFileMode(SettingsPath, UnixFileMode.UserRead | UnixFileMode.UserWrite); new ServerSettingsFile(SettingsPath).Update(s => s.VpnLocation = "se"); Assert.Equal(UnixFileMode.UserRead | UnixFileMode.UserWrite, File.GetUnixFileMode(SettingsPath)); } } }