From c60da3200421377a672944ce2e4f72aee20c2106 Mon Sep 17 00:00:00 2001 From: StuartFerguson Date: Mon, 3 Aug 2026 13:09:37 +0100 Subject: [PATCH] test: verify merchant worker service graph --- .../MerchantRuntimeFactoryTests.cs | 93 +++++++++++++++++++ ...sactionProcessing.MerchantPos.Tests.csproj | 19 ++++ TransactionProcessing.MerchantPos/Program.cs | 18 ++++ 3 files changed, 130 insertions(+) create mode 100644 TransactionProcessing.MerchantPos.Tests/MerchantRuntimeFactoryTests.cs create mode 100644 TransactionProcessing.MerchantPos.Tests/TransactionProcessing.MerchantPos.Tests.csproj diff --git a/TransactionProcessing.MerchantPos.Tests/MerchantRuntimeFactoryTests.cs b/TransactionProcessing.MerchantPos.Tests/MerchantRuntimeFactoryTests.cs new file mode 100644 index 0000000..57a7d76 --- /dev/null +++ b/TransactionProcessing.MerchantPos.Tests/MerchantRuntimeFactoryTests.cs @@ -0,0 +1,93 @@ +using ClientProxyBase; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; +using MerchantPos.EF.Persistence; +using SecurityService.Client; +using Shared.Serialisation; +using TransactionProcessing.MerchantPos.Persistence; +using TransactionProcessing.MerchantPos.Runtime; +using TransactionProcessor.Client; +using Xunit; + +namespace TransactionProcessing.MerchantPos.Tests; + +public sealed class MerchantRuntimeFactoryTests +{ + [Fact] + public void Create_resolves_a_merchant_runtime_from_the_application_service_graph() + { + using var provider = BuildServiceProvider(); + var factory = provider.GetRequiredService(); + + var runtime = factory.Create(new MerchantConfig + { + MerchantId = Guid.NewGuid(), + MerchantName = "Test Merchant", + Enabled = true, + Username = "user", + Password = "password", + DeviceIdentifier = "device", + ApplicationVersion = "1.0.0" + }); + + Assert.NotNull(runtime); + } + + private static ServiceProvider BuildServiceProvider() + { + var services = new ServiceCollection(); + + var configuration = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary + { + ["ConnectionStrings:MerchantDb"] = "Data Source=:memory:", + ["ConnectionStrings:SettingsDb"] = "Data Source=:memory:", + ["WorkerSettings:ClientId"] = "client-id", + ["WorkerSettings:ClientSecret"] = "client-secret", + ["WorkerSettings:ServiceClientId"] = "service-client-id", + ["WorkerSettings:ServiceClientSecret"] = "service-client-secret", + ["ApiConfiguration:SecurityService"] = "https://security.example", + ["ApiConfiguration:TransactionProcessorACL"] = "https://processor-acl.example", + ["ApiConfiguration:TransactionProcessorApi"] = "https://processor-api.example", + ["ApiConfiguration:TestHost"] = "https://test-host.example" + }) + .Build(); + + services.AddSingleton(configuration); + services.AddSingleton(SystemTextJsonSerializer.GetDefaultJsonSerializerOptions()); + services.AddSingleton(); + services.AddSingleton>(_ => value => StringSerialiser.Serialise(value)); + services.AddSingleton>(_ => (json, type) => StringSerialiser.DeserializeObject(json, type)); + services.AddHttpContextAccessor(); + services.AddSingleton>(sp => + { + var apiConfiguration = sp.GetRequiredService().GetSection("ApiConfiguration"); + + return configSetting => + { + if (string.IsNullOrWhiteSpace(configSetting)) + { + return string.Empty; + } + + var child = apiConfiguration.GetChildren() + .FirstOrDefault(c => string.Equals(c.Key, configSetting, StringComparison.OrdinalIgnoreCase)); + + return child?.Value ?? string.Empty; + }; + }); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddDbContext(options => options.UseSqlite("Data Source=:memory:")); + services.AddScoped(); + services.AddScoped(); + services.RegisterHttpClient(); + services.RegisterHttpClient(); + services.RegisterHttpClient(); + + return services.BuildServiceProvider(); + } +} diff --git a/TransactionProcessing.MerchantPos.Tests/TransactionProcessing.MerchantPos.Tests.csproj b/TransactionProcessing.MerchantPos.Tests/TransactionProcessing.MerchantPos.Tests.csproj new file mode 100644 index 0000000..f48d68d --- /dev/null +++ b/TransactionProcessing.MerchantPos.Tests/TransactionProcessing.MerchantPos.Tests.csproj @@ -0,0 +1,19 @@ + + + net10.0 + enable + enable + false + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + diff --git a/TransactionProcessing.MerchantPos/Program.cs b/TransactionProcessing.MerchantPos/Program.cs index c0f9531..dbf2323 100644 --- a/TransactionProcessing.MerchantPos/Program.cs +++ b/TransactionProcessing.MerchantPos/Program.cs @@ -56,6 +56,24 @@ builder.Services.AddSingleton(SystemTextJsonSerializer.GetDefaultJsonSerializerOptions()); builder.Services.AddScoped(); builder.Services.AddRazorPages(); + builder.Services.AddHttpContextAccessor(); + builder.Services.AddSingleton>(sp => + { + var apiConfiguration = sp.GetRequiredService().GetSection("ApiConfiguration"); + + return configSetting => + { + if (string.IsNullOrWhiteSpace(configSetting)) + { + return string.Empty; + } + + var child = apiConfiguration.GetChildren() + .FirstOrDefault(c => string.Equals(c.Key, configSetting, StringComparison.OrdinalIgnoreCase)); + + return child?.Value ?? string.Empty; + }; + }); builder.Services.RegisterHttpClient(); builder.Services.RegisterHttpClient();