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));
}
}
}