mcp-framework/cli/resolve_lookup_test.go

146 lines
3.4 KiB
Go
Raw Permalink Normal View History

package cli
import (
"errors"
"testing"
2026-05-05 10:23:14 +00:00
"forge.lclr.dev/AI/mcp-framework/secretstore"
)
type testSecretStore struct {
values map[string]string
errs map[string]error
}
func (s testSecretStore) SetSecret(name, label, secret string) error {
return nil
}
func (s testSecretStore) GetSecret(name string) (string, error) {
if err, ok := s.errs[name]; ok {
return "", err
}
value, ok := s.values[name]
if !ok {
return "", secretstore.ErrNotFound
}
return value, nil
}
func (s testSecretStore) DeleteSecret(name string) error {
return nil
}
func TestResolveLookupWithStandardProviders(t *testing.T) {
t.Setenv("MCP_PASSWORD", "")
lookup := ResolveLookup(ResolveLookupOptions{
Flag: MapLookup(map[string]string{"host": "https://flag.example.com"}),
Env: EnvLookup(nil),
Config: ConfigMap(map[string]string{"username": "config-user"}),
Secret: SecretStore(testSecretStore{
values: map[string]string{"smtp-password": "secret-password"},
}),
})
resolution, err := ResolveFields(ResolveOptions{
Fields: []FieldSpec{
{
Name: "host",
Required: true,
FlagKey: "host",
},
{
Name: "username",
Required: true,
EnvKey: "MCP_USERNAME",
ConfigKey: "username",
},
{
Name: "password",
Required: true,
EnvKey: "MCP_PASSWORD",
SecretKey: "smtp-password",
},
},
Lookup: lookup,
})
if err != nil {
t.Fatalf("ResolveFields returned error: %v", err)
}
host, _ := resolution.Get("host")
if host.Source != SourceFlag || host.Value != "https://flag.example.com" {
t.Fatalf("host = %+v", host)
}
username, _ := resolution.Get("username")
if username.Source != SourceConfig || username.Value != "config-user" {
t.Fatalf("username = %+v", username)
}
password, _ := resolution.Get("password")
if password.Source != SourceSecret || password.Value != "secret-password" {
t.Fatalf("password = %+v", password)
}
}
func TestSecretStoreProviderTreatsErrNotFoundAsMissing(t *testing.T) {
lookup := ResolveLookup(ResolveLookupOptions{
Secret: SecretStore(testSecretStore{
errs: map[string]error{"smtp-password": secretstore.ErrNotFound},
}),
})
resolution, err := ResolveFields(ResolveOptions{
Fields: []FieldSpec{
{
Name: "password",
Required: true,
SecretKey: "smtp-password",
DefaultValue: "fallback-password",
},
},
Lookup: lookup,
})
if err != nil {
t.Fatalf("ResolveFields returned error: %v", err)
}
password, _ := resolution.Get("password")
if password.Source != SourceDefault || password.Value != "fallback-password" {
t.Fatalf("password = %+v", password)
}
}
func TestSecretStoreProviderPropagatesBackendErrors(t *testing.T) {
backendErr := errors.New("backend unavailable")
lookup := ResolveLookup(ResolveLookupOptions{
Secret: SecretStore(testSecretStore{
errs: map[string]error{"smtp-password": backendErr},
}),
})
_, err := ResolveFields(ResolveOptions{
Fields: []FieldSpec{
{
Name: "password",
Required: true,
SecretKey: "smtp-password",
},
},
Lookup: lookup,
})
var sourceErr *SourceLookupError
if !errors.As(err, &sourceErr) {
t.Fatalf("ResolveFields error = %v, want SourceLookupError", err)
}
if sourceErr.Source != SourceSecret {
t.Fatalf("sourceErr.Source = %q, want %q", sourceErr.Source, SourceSecret)
}
if !errors.Is(err, backendErr) {
t.Fatalf("ResolveFields error should wrap backend error")
}
}