pomerium/internal/zero/cmd/import_ui_test.go
2024-09-26 13:31:35 -04:00

112 lines
3 KiB
Go

package cmd_test
import (
"context"
"embed"
"fmt"
"os"
"path/filepath"
"slices"
"strings"
"testing"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/pomerium/pomerium/config"
"github.com/pomerium/pomerium/pkg/envoy/files"
"github.com/pomerium/pomerium/pkg/zero/cluster"
"github.com/pomerium/pomerium/pkg/zero/importutil"
"github.com/pomerium/protoutil/fieldmasks"
"github.com/charmbracelet/x/ansi"
"github.com/charmbracelet/x/exp/teatest"
"github.com/pomerium/pomerium/internal/zero/cmd"
"github.com/stretchr/testify/require"
)
//go:embed testdata
var testdata embed.FS
func TestImportUI(t *testing.T) {
tmp := t.TempDir()
require.NoError(t, os.CopyFS(tmp, testdata))
dir, err := os.Getwd()
require.NoError(t, err)
defer os.Chdir(dir)
os.Chdir(filepath.Join(tmp, "testdata"))
src, err := config.NewFileOrEnvironmentSource("config.yaml", files.FullVersion())
require.NoError(t, err)
cfgC := make(chan *config.Config, 1)
src.OnConfigChange(context.Background(), func(_ context.Context, cfg *config.Config) {
cfgC <- cfg
})
if cfg := src.GetConfig(); cfg != nil {
cfgC <- cfg
}
cfg := (<-cfgC).Options.ToProto()
ui := cmd.NewImportUI(cfg, &cluster.ConfigQuotas{
Certificates: 10,
Policies: 10,
Routes: 10,
})
form := ui.XForm()
form.SubmitCmd = tea.Quit
form.CancelCmd = tea.Quit
tm := teatest.NewTestModel(t, form, teatest.WithInitialTermSize(80, 80))
presentSettings := fieldmasks.Leaves(
fieldmasks.Diff(
config.NewDefaultOptions().ToProto().GetSettings().ProtoReflect(),
cfg.GetSettings().ProtoReflect(),
),
cfg.Settings.ProtoReflect().Descriptor(),
)
slices.Sort(presentSettings.Paths)
for i, setting := range presentSettings.Paths {
if i > 0 {
tm.Send(tea.KeyMsg{Type: tea.KeyDown})
}
var foundSelect bool
teatest.WaitFor(t, tm.Output(), func(bts []byte) bool {
str := ansi.Strip(string(bts))
if !foundSelect {
if strings.Contains(str, fmt.Sprintf("> [•] %s", setting)) ||
strings.Contains(str, fmt.Sprintf("> [ ] %s", setting)) {
foundSelect = true
}
return false
}
return strings.Contains(str, fmt.Sprintf("Value: %s", setting))
}, teatest.WithDuration(1*time.Second), teatest.WithCheckInterval(1*time.Millisecond))
}
tm.Send(tea.KeyMsg{Type: tea.KeyTab})
names := importutil.GenerateRouteNames(cfg.Routes)
for i, route := range cfg.Routes {
if i > 0 {
tm.Send(tea.KeyMsg{Type: tea.KeyDown})
}
var foundSelect bool
teatest.WaitFor(t, tm.Output(), func(bts []byte) bool {
str := ansi.Strip(string(bts))
if !foundSelect {
if strings.Contains(str, fmt.Sprintf("> [•] %s", names[i])) ||
strings.Contains(str, fmt.Sprintf("> [ ] %s", names[i])) {
foundSelect = true
}
return false
}
if i == 0 || cfg.Routes[i-1].From != route.From {
return strings.Contains(str, fmt.Sprintf("from: %s", route.From))
}
return true
}, teatest.WithDuration(1*time.Second), teatest.WithCheckInterval(1*time.Millisecond))
}
tm.Send(tea.KeyMsg{Type: tea.KeyEnter})
tm.WaitFinished(t)
}