Files
IBKRTrader/tests/IBKRTrader.Tests/Settings/SettingsSchemaTests.cs
T
Richard f923721784
Build & Test / build (ubuntu-latest) (push) Canceled after 0s
Build & Test / build (windows-latest) (push) Canceled after 0s
feat: Web-UI als zweiter Ausgabeweg neben Avalonia-Shell (#490)
- Einheitlicher WebserverWorker in IBKRTrader.Hosting auf Kestrel-Basis
- Token-Authentifizierung (AuthService) mit zeitkonstantem Vergleich und HMAC-Session-Tokens
- OrderManager im Core fuer Bestands- und Reservierungsabgleich offener Broker-Orders
- SettingsSchema fuer reflexionsbasiertes Auslesen und sichere Aktualisierung ohne Klartext-Passwoerter
- SSE-Streaming (LogStreamService) fuer Echtzeit-Logs ueber isolierte Channels
- Statische Single-Page-Application in wwwroot (Avalonia Fluent / Polytrader Theme) fuer alle 9 Ansichten
- Unit-Tests fuer OrderManager, AuthService, SettingsSchema, LogStreamService und WebserverWorker (498 Tests gruen)
2026-09-06 19:55:40 +02:00

100 lines
3.1 KiB
C#

using FluentAssertions;
using IBKRTrader.Core.Settings;
namespace IBKRTrader.Tests.Settings;
[Trait("cat", "unit")]
public class SettingsSchemaTests
{
[Fact]
public void Build_ExtractsSectionsAndFieldsFromAppSettings()
{
var settings = new AppSettings();
var sections = SettingsSchema.Build(settings);
sections.Should().NotBeEmpty();
sections.SelectMany(s => s.Fields).Should().NotBeEmpty();
// Webserver-Abschnitt prüfen
var ws = sections.FirstOrDefault(s => s.Fields.Any(f => f.Path == "Webserver.Port"));
ws.Should().NotBeNull();
}
[Fact]
public void ToDto_MasksPasswordsAndTokens()
{
var settings = new AppSettings();
settings.Webserver.AuthToken = "super-secret-1234";
settings.Database.Password = "db-pass-secret";
var dtos = SettingsSchema.ToDto(settings);
var allFields = dtos.SelectMany(s => s.Fields).ToList();
// AuthToken prüfen
var tokenField = allFields.FirstOrDefault(f => f.Path == "Webserver.AuthToken");
tokenField.Should().NotBeNull();
tokenField!.IsPassword.Should().BeTrue();
tokenField.HasValue.Should().BeTrue();
tokenField.Value.Should().BeNull("Passwörter und Tokens dürfen niemals im Klartext im DTO stehen!");
// DB Password prüfen
var passField = allFields.FirstOrDefault(f => f.Path == "Database.Password");
passField.Should().NotBeNull();
passField!.IsPassword.Should().BeTrue();
passField.Value.Should().BeNull();
}
[Fact]
public void TrySetValue_UpdatesValueByPath()
{
var settings = new AppSettings();
settings.Webserver.Port = 5001;
var success = SettingsSchema.TrySetValue(settings, "Webserver.Port", 6002);
success.Should().BeTrue();
settings.Webserver.Port.Should().Be(6002);
}
[Fact]
public void TrySetValue_PreservesPasswordWhenEmptyPassed()
{
var settings = new AppSettings();
settings.Webserver.AuthToken = "keep-this-token";
var success = SettingsSchema.TrySetValue(settings, "Webserver.AuthToken", "");
success.Should().BeTrue();
settings.Webserver.AuthToken.Should().Be("keep-this-token");
}
[Fact]
public void TrySetValue_ReturnsFalseForUnknownPath()
{
var settings = new AppSettings();
var success = SettingsSchema.TrySetValue(settings, "NonExistent.Field", "val");
success.Should().BeFalse();
}
[Fact]
public void TrySetValue_ParsesStringRepresentationOfTypes()
{
var settings = new AppSettings();
// int als string
SettingsSchema.TrySetValue(settings, "Webserver.Port", "7001").Should().BeTrue();
settings.Webserver.Port.Should().Be(7001);
// bool als string
SettingsSchema.TrySetValue(settings, "Webserver.Enabled", "true").Should().BeTrue();
settings.Webserver.Enabled.Should().BeTrue();
// bool als false
SettingsSchema.TrySetValue(settings, "Webserver.Enabled", "false").Should().BeTrue();
settings.Webserver.Enabled.Should().BeFalse();
}
}