opnsense-portal/cmd/vpnportal/main_test.go
Carsten Abele 7237aee744 fix(cli): Test las die Konfiguration des Hosts statt einer Attrappe
TestRunNoArgsDefaultsToServe rief run(nil) auf und griff damit auf den
Default-Pfad /etc/vpnportal/config.yaml zu. Auf einem Entwicklungsrechner
existiert der nicht, der Test war dort gruen. Auf einem Zielhost mit
installierter Konfiguration las er dagegen die Produktivkonfiguration und
loeste echte Verbindungsversuche zu Firewall und Domain Controllern aus.

Die Kommandoauswahl ist jetzt als reine Funktion commandFor testbar. Kein
Test ruft serve oder check mehr ohne expliziten --config-Pfad auf.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBHF4R9EAejDJUMdwr6C68
2026-08-14 13:22:35 +02:00

87 lines
2.8 KiB
Go

package main
import (
"bytes"
"path/filepath"
"strings"
"testing"
)
func TestRunVersion(t *testing.T) {
var out, errOut bytes.Buffer
code := run([]string{"version"}, &out, &errOut)
if code != 0 {
t.Fatalf("exit code = %d, want 0 (stderr: %s)", code, errOut.String())
}
got := out.String()
for _, want := range []string{"vpnportal", "commit", "built"} {
if !strings.Contains(got, want) {
t.Errorf("output %q missing %q", got, want)
}
}
}
func TestRunUnknownCommand(t *testing.T) {
var out, errOut bytes.Buffer
if code := run([]string{"frobnicate"}, &out, &errOut); code != 2 {
t.Fatalf("exit code = %d, want 2", code)
}
if !strings.Contains(errOut.String(), "frobnicate") {
t.Errorf("stderr should name the unknown command, got %q", errOut.String())
}
}
// commandFor wird bewusst ohne Seiteneffekte getestet. Ein Test, der run(nil)
// aufruft, wuerde den Default-Konfigpfad /etc/vpnportal/config.yaml lesen —
// auf einem Zielhost also die Produktivkonfiguration, samt Verbindungsversuch
// zu Firewall und Domain Controllern.
func TestCommandForDispatch(t *testing.T) {
cases := []struct {
name string
args []string
wantCmd string
wantRest []string
}{
{"ohne Argumente", nil, "serve", nil},
{"leere Liste", []string{}, "serve", []string{}},
{"nur Flag", []string{"--config", "/x.yaml"}, "serve", []string{"--config", "/x.yaml"}},
{"kurzes Flag", []string{"-h"}, "serve", []string{"-h"}},
{"version", []string{"version"}, "version", []string{}},
{"serve mit Flag", []string{"serve", "--config", "/x"}, "serve", []string{"--config", "/x"}},
{"check mit Flag", []string{"check", "--test-auth", "u"}, "check", []string{"--test-auth", "u"}},
{"unbekannt", []string{"frobnicate"}, "frobnicate", []string{}},
{"leeres Argument", []string{""}, "serve", []string{""}},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
cmd, rest := commandFor(tc.args)
if cmd != tc.wantCmd {
t.Errorf("cmd = %q, want %q", cmd, tc.wantCmd)
}
if len(rest) != len(tc.wantRest) {
t.Fatalf("rest = %q, want %q", rest, tc.wantRest)
}
for i := range rest {
if rest[i] != tc.wantRest[i] {
t.Errorf("rest[%d] = %q, want %q", i, rest[i], tc.wantRest[i])
}
}
})
}
}
func TestRunServeReportsMissingConfigPath(t *testing.T) {
// Expliziter Pfad: der Test darf niemals die Konfiguration des Hosts lesen.
missing := filepath.Join(t.TempDir(), "gibtsnicht.yaml")
var out, errOut bytes.Buffer
code := run([]string{"--config", missing}, &out, &errOut)
if code == 2 {
t.Fatal("ein fuehrendes Flag muss auf serve abgebildet werden, nicht auf unknown-command")
}
if code == 0 {
t.Fatal("fehlende Konfiguration muss zum Abbruch fuehren")
}
if !strings.Contains(errOut.String(), missing) {
t.Errorf("stderr muss den Pfad nennen, got %q", errOut.String())
}
}