maidn-cli/cmd/bootstrap_test.go

90 lines
3.3 KiB
Go

package cmd
import (
"errors"
"strings"
"testing"
"github.com/Pingu-Studio/MaidnCLI/internal/config"
)
func TestCreateForgejoRegistryTokenRequiresConfig(t *testing.T) {
originalConfigPath, originalCreate := bootstrapConfigPath, bootstrapCreateForgejoRegistryToken
defer func() {
bootstrapConfigPath = originalConfigPath
bootstrapCreateForgejoRegistryToken = originalCreate
}()
bootstrapConfigPath = ""
bootstrapCreateForgejoRegistryToken = true
if err := runBootstrap(nil, nil); err == nil {
t.Fatal("--create-forgejo-registry-token accepted a missing --config")
}
}
func TestPublishAppRequiresDeliveryConfigBeforeCheckout(t *testing.T) {
originalConfigPath, originalPublish := bootstrapConfigPath, bootstrapPublishAppFrom
originalLoad, originalClean := loadPublishAppConfig, ensurePublishAppCheckoutClean
t.Cleanup(func() {
bootstrapConfigPath = originalConfigPath
bootstrapPublishAppFrom = originalPublish
loadPublishAppConfig = originalLoad
ensurePublishAppCheckoutClean = originalClean
})
bootstrapConfigPath = "test-config.yaml"
bootstrapPublishAppFrom = "app-checkout"
loadPublishAppConfig = func(string) (config.Config, error) {
return config.Config{Git: config.GitConfig{BaseURL: "https://git.example.test"}, Delivery: config.DeliveryConfig{AppName: "legacy-app"}}, nil
}
ensurePublishAppCheckoutClean = func(string) error {
t.Fatal("publish inspected the checkout before validating delivery config")
return nil
}
err := runBootstrap(nil, nil)
if err == nil || !strings.Contains(err.Error(), "delivery appName") {
t.Fatalf("runBootstrap() error = %v, want incomplete delivery error", err)
}
}
func TestSeedForgejoOperationalCredentialsUsesEncryptedUpsertBoundary(t *testing.T) {
original := upsertOperationalSecret
t.Cleanup(func() { upsertOperationalSecret = original })
cfg := config.Config{
Git: config.GitConfig{Username: "webhook-bot", Token: "test-pat"},
SOPS: config.SOPSConfig{OperationalSecretsPath: "secrets.sops.yaml", AgeKeyPath: "age-key.txt"},
}
type call struct{ path, key, value string }
var calls []call
upsertOperationalSecret = func(secretsPath, ageKeyPath, path, key, value string) error {
if secretsPath != cfg.SOPS.OperationalSecretsPath || ageKeyPath != cfg.SOPS.AgeKeyPath {
t.Fatal("credential upsert used unexpected secret paths")
}
calls = append(calls, call{path, key, value})
return nil
}
if err := seedForgejoOperationalCredentials(cfg); err != nil {
t.Fatal(err)
}
if len(calls) != 2 || calls[0] != (call{"cicd/forgejo", "username", cfg.Git.Username}) || calls[1] != (call{"cicd/forgejo", "token", cfg.Git.Token}) {
t.Fatal("configured Forgejo credentials were not passed only to the encrypted upsert boundary")
}
}
func TestSeedForgejoOperationalCredentialsHidesTokenOnUpsertFailure(t *testing.T) {
original := upsertOperationalSecret
t.Cleanup(func() { upsertOperationalSecret = original })
cfg := config.Config{Git: config.GitConfig{Username: "webhook-bot", Token: "test-pat"}}
upsertOperationalSecret = func(_, _, _, key, _ string) error {
if key == "token" {
return errors.New("unavailable")
}
return nil
}
err := seedForgejoOperationalCredentials(cfg)
if err == nil || !strings.Contains(err.Error(), "save Forgejo token for webhook registration") || strings.Contains(err.Error(), cfg.Git.Token) {
t.Fatal("credential upsert failure was not clear and token-safe")
}
}