Files

235 lines
5.9 KiB
Go

package main
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
"github.com/spf13/viper"
)
func TestGenerateConfigCmd_Flags(t *testing.T) {
cmd := generateConfigCmd()
flags := cmd.Flags()
lang, err := flags.GetString("lang")
if err != nil {
t.Fatalf("failed to get --lang flag: %v", err)
}
if lang != "en" {
t.Errorf("--lang default = %q, want %q", lang, "en")
}
output, err := flags.GetString("output")
if err != nil {
t.Fatalf("failed to get --output flag: %v", err)
}
if output != "" {
t.Errorf("--output default = %q, want empty string", output)
}
}
func TestGenerateConfig_LangEn(t *testing.T) {
cmd := generateConfigCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
if err := cmd.Flags().Set("lang", "en"); err != nil {
t.Fatalf("Set flag failed: %v", err)
}
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute failed: %v", err)
}
out := buf.String()
if !strings.Contains(out, "pg:") {
t.Errorf("output missing pg section")
}
if !strings.Contains(out, "host") {
t.Errorf("output missing host key")
}
if !strings.Contains(out, "PostgreSQL") {
t.Errorf("output missing English comment")
}
}
func TestGenerateConfig_LangRu(t *testing.T) {
cmd := generateConfigCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
if err := cmd.Flags().Set("lang", "ru"); err != nil {
t.Fatalf("Set flag failed: %v", err)
}
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute failed: %v", err)
}
out := buf.String()
if !strings.Contains(out, "pg:") {
t.Errorf("output missing pg section")
}
if !strings.Contains(out, "хост") {
t.Errorf("output missing Russian comment (хост)")
}
}
func TestGenerateConfig_OutputFile(t *testing.T) {
tempDir := t.TempDir()
outputPath := filepath.Join(tempDir, "config.yaml")
cmd := generateConfigCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
if err := cmd.Flags().Set("output", outputPath); err != nil {
t.Fatalf("Set flag failed: %v", err)
}
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute failed: %v", err)
}
data, err := os.ReadFile(outputPath)
if err != nil {
t.Fatalf("failed to read output file: %v", err)
}
if len(data) == 0 {
t.Errorf("output file is empty")
}
if buf.Len() != 0 {
t.Errorf("stdout not empty when --output set: %q", buf.String())
}
}
func TestGenerateConfig_Stdout(t *testing.T) {
cmd := generateConfigCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute failed: %v", err)
}
out := buf.String()
if out == "" {
t.Errorf("stdout empty when no --output")
}
if !strings.Contains(out, "pg:") {
t.Errorf("stdout missing pg section")
}
}
func TestGenerateConfig_AllKeys(t *testing.T) {
cmd := generateConfigCmd()
var buf bytes.Buffer
cmd.SetOut(&buf)
cmd.SetErr(&buf)
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute failed: %v", err)
}
out := buf.String()
requiredKeys := []string{
"host", "port", "user", "password", "database", "sslmode", "exclude_tables",
"dir", "retention_days", "cron",
"pq_scheme", "classical_scheme",
"pq_public_key_path", "classical_public_key_path",
"healthz", "log",
}
for _, key := range requiredKeys {
if !strings.Contains(out, key) {
t.Errorf("output missing key %q", key)
}
}
}
func TestGenerateConfig_RoundTrip(t *testing.T) {
tempDir := t.TempDir()
outputPath := filepath.Join(tempDir, "config.yaml")
cmd := generateConfigCmd()
if err := cmd.Flags().Set("output", outputPath); err != nil {
t.Fatalf("Set flag failed: %v", err)
}
if err := cmd.Execute(); err != nil {
t.Fatalf("Execute failed: %v", err)
}
v := viper.New()
v.SetConfigFile(outputPath)
if err := v.ReadInConfig(); err != nil {
t.Fatalf("viper read generated config failed: %v", err)
}
var cfg struct {
PG struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
Database string `mapstructure:"database"`
SSLMode string `mapstructure:"sslmode"`
ExcludeTables []string `mapstructure:"exclude_tables"`
} `mapstructure:"pg"`
Backup struct {
Dir string `mapstructure:"dir"`
RetentionDays int `mapstructure:"retention_days"`
Cron string `mapstructure:"cron"`
} `mapstructure:"backup"`
PQScheme uint16 `mapstructure:"pq_scheme"`
ClassicalScheme uint16 `mapstructure:"classical_scheme"`
PQPublicKeyPath string `mapstructure:"pq_public_key_path"`
ClassicalPublicKeyPath string `mapstructure:"classical_public_key_path"`
Healthz struct {
Port int `mapstructure:"port"`
} `mapstructure:"healthz"`
Log struct {
Level string `mapstructure:"level"`
} `mapstructure:"log"`
}
if err := v.Unmarshal(&cfg); err != nil {
t.Fatalf("viper unmarshal generated config failed: %v", err)
}
if cfg.PG.Port != 5432 {
t.Errorf("PG.Port = %d, want 5432", cfg.PG.Port)
}
if cfg.PG.SSLMode != "prefer" {
t.Errorf("PG.SSLMode = %q, want prefer", cfg.PG.SSLMode)
}
if len(cfg.PG.ExcludeTables) != 1 || cfg.PG.ExcludeTables[0] != "e2e_one_time_keys_json" {
t.Errorf("PG.ExcludeTables = %v, want [e2e_one_time_keys_json]", cfg.PG.ExcludeTables)
}
if cfg.Backup.RetentionDays != 180 {
t.Errorf("Backup.RetentionDays = %d, want 180", cfg.Backup.RetentionDays)
}
if cfg.Backup.Cron != "0 0 3 * * *" {
t.Errorf("Backup.Cron = %q, want 0 0 3 * * *", cfg.Backup.Cron)
}
if cfg.PQScheme != 0x0006 {
t.Errorf("PQScheme = 0x%04x, want 0x%04x", cfg.PQScheme, 0x0006)
}
if cfg.ClassicalScheme != 0x0007 {
t.Errorf("ClassicalScheme = 0x%04x, want 0x%04x", cfg.ClassicalScheme, 0x0007)
}
if cfg.Healthz.Port != 8080 {
t.Errorf("Healthz.Port = %d, want 8080", cfg.Healthz.Port)
}
if cfg.Log.Level != "info" {
t.Errorf("Log.Level = %q, want info", cfg.Log.Level)
}
}