Add verbose Enova diagnostics and reliable Sentry reporting

This commit is contained in:
2026-08-31 21:13:46 +00:00
parent ee62a6253d
commit af6466e2dc
20 changed files with 276 additions and 37 deletions

View File

@@ -1,6 +1,7 @@
using System.Data.Common;
using System.Reflection;
using SmartB2B.Enova.Contracts;
using SmartB2B.Enova.Service;
using SmartB2B.Enova.Service.Configuration;
using SmartB2B.Enova.Service.Orders;
using SmartB2B.Enova.Service.Rpc;
@@ -27,10 +28,14 @@ var tests = new (string Name, Func<Task> Run)[]
("Warstwa WAMP wysyła wynik jako kwargs", WampKeywordWireResult),
("Brak waluty zwraca stabilny błąd", MissingCurrency),
("Waluta inna niż PLN jest odrzucana", UnsupportedCurrency),
("Błąd adaptera jest wypisywany na stderr", AdapterErrorIsWrittenToStderr),
("Brak katalogu Enovy jest wykrywany", MissingEnovaDirectory),
("Sekrety są odczytywane z pliku konfiguracji", SecretsComeFromConfigurationFile),
("Brak danych operatora wyłącza place_order", MissingCredentialsDisablePlaceOrder),
("Częściowe dane operatora wyłączają place_order", PartialCredentialsDisablePlaceOrder),
("Parametr /debug włącza szczegółowe logowanie", DebugSwitchEnablesVerboseLogging),
("Parametr /verbose można wyłączyć", VerboseSwitchCanBeDisabled),
("Tryb szczegółowy jest przekazywany do adaptera", VerboseModeReachesAdapter),
("Provider SQL działa na bieżącej platformie", SqlProviderIsSupported)
};
@@ -195,6 +200,29 @@ static async Task UnsupportedCurrency()
"eu.smartb2b.erp.currency_not_supported");
}
static async Task AdapterErrorIsWrittenToStderr()
{
var previousError = Console.Error;
using var error = new StringWriter();
try
{
Console.SetError(error);
var handler = new PlaceOrderHandler(new FailingAdapter(), CreateConfiguration());
await AssertWampError(
handler.HandleAsync(CreateInvocation(), CancellationToken.None),
"eu.smartb2b.company_not_found");
}
finally
{
Console.SetError(previousError);
}
if (!error.ToString().Contains("Nie znaleziono kontrahenta", StringComparison.Ordinal))
{
throw new InvalidOperationException($"Brak komunikatu błędu na stderr: {error}");
}
}
static Task MissingEnovaDirectory()
{
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
@@ -281,7 +309,30 @@ static Task PartialCredentialsDisablePlaceOrder()
return Task.CompletedTask;
}
static RuntimeSettings LoadRuntimeSettings(string credentialsJson)
static Task DebugSwitchEnablesVerboseLogging()
{
var options = CommandLineOptions.Parse(["/debug"]);
AssertEqual(true, options.VerboseLogging, "tryb szczegółowy");
return Task.CompletedTask;
}
static Task VerboseSwitchCanBeDisabled()
{
var options = CommandLineOptions.Parse(["/verbose", "/noverbose"]);
AssertEqual(false, options.VerboseLogging, "wyłączony tryb szczegółowy");
return Task.CompletedTask;
}
static Task VerboseModeReachesAdapter()
{
var runtime = LoadRuntimeSettings(
"\"operator\": \"Administrator\", \"password\": \"haslo\",",
verboseLogging: true);
AssertEqual(true, runtime.EnovaConfiguration?.VerboseLogging, "tryb adaptera");
return Task.CompletedTask;
}
static RuntimeSettings LoadRuntimeSettings(string credentialsJson, bool verboseLogging = false)
{
var path = Path.Combine(Path.GetTempPath(), $"enova-settings-{Guid.NewGuid():N}.json");
try
@@ -300,7 +351,7 @@ static RuntimeSettings LoadRuntimeSettings(string credentialsJson)
}
""");
return ServiceSettings.Load(path).ResolveRuntimeSettings();
return ServiceSettings.Load(path).ResolveRuntimeSettings(verboseLogging);
}
finally
{
@@ -423,6 +474,17 @@ file sealed class FakeAdapter : IEnovaOrderAdapter
}
}
file sealed class FailingAdapter : IEnovaOrderAdapter
{
public EnovaAdapterInfo Initialize(EnovaAdapterConfiguration configuration) =>
new("1.0.0", "2604.4.4.0", "2604.4.4.0", configuration.Connection.DatabaseName);
public OrderResult CreateOrder(OrderRequest request) =>
throw new EnovaOperationException(
"eu.smartb2b.company_not_found",
$"Nie znaleziono kontrahenta o kodzie '{request.CustomerCode}'.");
}
file sealed class FakeRouterCallback : IWampRawRpcOperationRouterCallback
{
public long RequestId => 1;