feat(secrets): G-2a secret: arm on GalaxySecretRef via ISecretResolver (Task 7)
Add a secret:NAME arm to GalaxySecretRef.ResolveApiKey that resolves the Galaxy gateway API key through the shared ISecretResolver — fail-closed if the secret is absent (never falls through to the cleartext literal arm), retiring the dev:/literal in-DB path for production. Because GetAsync is async the method becomes ResolveApiKeyAsync; the await cascade threads ISecretResolver by ctor injection into GalaxyDriver + GalaxyDriverBrowser and (since GalaxyDriver is built by a static factory closure, not DI) through GalaxyDriverFactoryExtensions + DriverFactoryBootstrap (which pulls the real resolver from the service provider — registered unconditionally in Slice 1). A NullSecretResolver null-object backs the parse-only/test paths only; the runtime path always gets the real resolver (verified end-to-end). TDD: 3 new secret:-arm tests (resolve / fail-closed-on-absent / no-literal-warning) RED without the arm, GREEN with it; 338 Galaxy tests pass; no sync-over-async.
This commit is contained in:
+12
-1
@@ -1,5 +1,6 @@
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.Secrets.Abstractions;
|
||||
|
||||
namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.Tests;
|
||||
|
||||
@@ -14,7 +15,17 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.Tests;
|
||||
[Trait("Category", "Unit")]
|
||||
public sealed class GalaxyDriverBrowserTests
|
||||
{
|
||||
private readonly GalaxyDriverBrowser _sut = new();
|
||||
// These unit tests exercise only the pre-connect validation paths (empty endpoint,
|
||||
// blank client name) that throw BEFORE the API-key secret: arm is resolved, so a
|
||||
// null-returning stub resolver suffices — it is never consulted.
|
||||
private readonly GalaxyDriverBrowser _sut = new(new StubSecretResolver());
|
||||
|
||||
/// <summary>A no-op resolver: every name resolves to null. Never consulted by these tests.</summary>
|
||||
private sealed class StubSecretResolver : ISecretResolver
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task<string?> GetAsync(SecretName name, CancellationToken ct) => Task.FromResult<string?>(null);
|
||||
}
|
||||
|
||||
/// <summary>The DriverType key must match the AdminUI's persisted "GalaxyMxGateway" value
|
||||
/// so the factory wire-up picks the right browser implementation.</summary>
|
||||
|
||||
Reference in New Issue
Block a user