diff --git a/release/SmartB2B.Enova.Contracts.dll b/release/SmartB2B.Enova.Contracts.dll index 66aa820..f89ef72 100644 Binary files a/release/SmartB2B.Enova.Contracts.dll and b/release/SmartB2B.Enova.Contracts.dll differ diff --git a/release/SmartB2B.Enova.Contracts.pdb b/release/SmartB2B.Enova.Contracts.pdb index a84183a..8da68a0 100644 Binary files a/release/SmartB2B.Enova.Contracts.pdb and b/release/SmartB2B.Enova.Contracts.pdb differ diff --git a/release/SmartB2B.Enova.Service.dll b/release/SmartB2B.Enova.Service.dll index f63c4e0..3165265 100644 Binary files a/release/SmartB2B.Enova.Service.dll and b/release/SmartB2B.Enova.Service.dll differ diff --git a/release/SmartB2B.Enova.Service.exe b/release/SmartB2B.Enova.Service.exe index 91d406c..b455cce 100644 Binary files a/release/SmartB2B.Enova.Service.exe and b/release/SmartB2B.Enova.Service.exe differ diff --git a/release/SmartB2B.Enova.Service.pdb b/release/SmartB2B.Enova.Service.pdb index 1348071..7de2902 100644 Binary files a/release/SmartB2B.Enova.Service.pdb and b/release/SmartB2B.Enova.Service.pdb differ diff --git a/release/adapters/SmartB2B.Enova.Adapter.dll b/release/adapters/SmartB2B.Enova.Adapter.dll index 4cfd969..e96d647 100644 Binary files a/release/adapters/SmartB2B.Enova.Adapter.dll and b/release/adapters/SmartB2B.Enova.Adapter.dll differ diff --git a/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs b/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs index 9f80dab..5a0e4d7 100644 --- a/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs +++ b/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs @@ -1,4 +1,5 @@ using System.Reflection; +using Microsoft.Data.SqlClient; using SmartB2B.Enova.Contracts; using Soneta.Business; using Soneta.Business.App; @@ -253,18 +254,50 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter application.Remove(existing, save: false); } - var database = new MsSqlDatabase - { - Name = connection.DatabaseName, - Active = true, - UseConnectionString = true, - ConnectionString = connection.SqlConnectionString - }; + var database = CreateDatabase(connection); application.Add(database, save: false); return database; } + private static MsSqlDatabase CreateDatabase(EnovaConnectionOptions connection) + { + var sqlConnection = ParseSqlConnectionString(connection.SqlConnectionString); + return new MsSqlDatabase + { + Name = connection.DatabaseName, + Active = true, + Server = sqlConnection.DataSource, + DatabaseName = sqlConnection.InitialCatalog, + User = sqlConnection.UserID, + Password = sqlConnection.Password, + Trusted = sqlConnection.IntegratedSecurity, + TrustServerCertificate = sqlConnection.TrustServerCertificate, + UseConnectionString = true, + ConnectionString = connection.SqlConnectionString + }; + } + + private static SqlConnectionSettings ParseSqlConnectionString(string connectionString) + { + var builder = new SqlConnectionStringBuilder(connectionString); + return new SqlConnectionSettings( + builder.DataSource, + builder.InitialCatalog, + builder.UserID, + builder.Password, + builder.IntegratedSecurity, + builder.TrustServerCertificate); + } + + private sealed record SqlConnectionSettings( + string DataSource, + string InitialCatalog, + string UserID, + string Password, + bool IntegratedSecurity, + bool TrustServerCertificate); + private static void ValidateConfiguration(EnovaAdapterConfiguration configuration) { var errors = new List(); diff --git a/src/SmartB2B.Enova.Adapter/SmartB2B.Enova.Adapter.csproj b/src/SmartB2B.Enova.Adapter/SmartB2B.Enova.Adapter.csproj index 6d725db..8b94de3 100644 --- a/src/SmartB2B.Enova.Adapter/SmartB2B.Enova.Adapter.csproj +++ b/src/SmartB2B.Enova.Adapter/SmartB2B.Enova.Adapter.csproj @@ -7,6 +7,7 @@ + diff --git a/tests/SmartB2B.Enova.Tests/Program.cs b/tests/SmartB2B.Enova.Tests/Program.cs index 886b447..b75d5d1 100644 --- a/tests/SmartB2B.Enova.Tests/Program.cs +++ b/tests/SmartB2B.Enova.Tests/Program.cs @@ -1,5 +1,6 @@ using System.Data.Common; using System.Reflection; +using System.Runtime.Loader; using SmartB2B.Enova.Contracts; using SmartB2B.Enova.Service; using SmartB2B.Enova.Service.Configuration; @@ -36,6 +37,7 @@ var tests = new (string Name, Func Run)[] ("Parametr /debug włącza szczegółowe logowanie", DebugSwitchEnablesVerboseLogging), ("Parametr /verbose można wyłączyć", VerboseSwitchCanBeDisabled), ("Tryb szczegółowy jest przekazywany do adaptera", VerboseModeReachesAdapter), + ("Rejestracja bazy przenosi parametry connection stringa", DatabaseRegistrationUsesConnectionString), ("Provider SQL działa na bieżącej platformie", SqlProviderIsSupported) }; @@ -79,6 +81,69 @@ static Task SqlProviderIsSupported() return Task.CompletedTask; } +static Task DatabaseRegistrationUsesConnectionString() +{ + var directory = new DirectoryInfo(AppContext.BaseDirectory); + string? installationPath = null; + while (directory is not null) + { + var candidate = Path.Combine(directory.FullName, "enova365 2604.4.4"); + if (File.Exists(Path.Combine(candidate, "Soneta.Business.dll"))) + { + installationPath = candidate; + break; + } + + directory = directory.Parent; + } + + if (installationPath is null) + { + throw new InvalidOperationException("Nie znaleziono lokalnej instalacji enova365 do testu adaptera."); + } + + Assembly? ResolveSonetaAssembly(AssemblyLoadContext context, AssemblyName name) + { + var candidate = Path.Combine(installationPath, $"{name.Name}.dll"); + return File.Exists(candidate) ? context.LoadFromAssemblyPath(candidate) : null; + } + + AssemblyLoadContext.Default.Resolving += ResolveSonetaAssembly; + var adapterAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath( + Path.Combine(AppContext.BaseDirectory, "SmartB2B.Enova.Adapter.dll")); + var adapterType = adapterAssembly.GetType("SmartB2B.Enova.Adapter.EnovaOrderAdapter", throwOnError: true) + ?? throw new InvalidOperationException("Nie znaleziono typu adaptera Enovy."); + var parseConnectionString = adapterType.GetMethod( + "ParseSqlConnectionString", + BindingFlags.Static | BindingFlags.NonPublic) + ?? throw new InvalidOperationException("Nie znaleziono metody analizującej connection string Enovy."); + object settings; + try + { + settings = parseConnectionString.Invoke( + null, + ["Server=sql01;Database=Moms_Care;User ID=smartb2b;Password=haslo-sql;TrustServerCertificate=True"]) + ?? throw new InvalidOperationException("Adapter nie odczytał konfiguracji połączenia Enovy."); + } + catch (TargetInvocationException exception) when (exception.InnerException is not null) + { + throw exception.InnerException; + } + + AssertEqual("sql01", GetProperty(settings, "DataSource"), "serwer SQL"); + AssertEqual("Moms_Care", GetProperty(settings, "InitialCatalog"), "nazwa bazy SQL"); + AssertEqual("smartb2b", GetProperty(settings, "UserID"), "użytkownik SQL"); + AssertEqual("haslo-sql", GetProperty(settings, "Password"), "hasło SQL"); + AssertEqual(false, GetProperty(settings, "IntegratedSecurity"), "uwierzytelnianie zintegrowane"); + AssertEqual(true, GetProperty(settings, "TrustServerCertificate"), "zaufanie certyfikatowi SQL"); + + return Task.CompletedTask; +} + +static object? GetProperty(object instance, string name) => + instance.GetType().GetProperty(name)?.GetValue(instance) + ?? throw new InvalidOperationException($"Nie znaleziono wartości właściwości '{name}'."); + static Task ValidFractionalDiscount() { AssertNoErrors(CreateValidRequest(12.5m)); diff --git a/tests/SmartB2B.Enova.Tests/SmartB2B.Enova.Tests.csproj b/tests/SmartB2B.Enova.Tests/SmartB2B.Enova.Tests.csproj index 8a53f9f..f2f3386 100644 --- a/tests/SmartB2B.Enova.Tests/SmartB2B.Enova.Tests.csproj +++ b/tests/SmartB2B.Enova.Tests/SmartB2B.Enova.Tests.csproj @@ -6,6 +6,7 @@ enable +