Initial commit: dial — interactive SSH host picker
A fast, read-only ~/.ssh/config picker that exec's the system ssh client. Includes: static high-contrast picker with recency/frequency/name sort and tag grouping, `dial keygen` (native ed25519/RSA + optional config entry), and an optional offline YubiKey launch gate with one-time recovery codes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// withHome points UserHomeDir at a temp dir for the duration of a test.
|
||||
func withHome(t *testing.T) string {
|
||||
t.Helper()
|
||||
home := t.TempDir()
|
||||
t.Setenv("HOME", home)
|
||||
// Ensure ~/.ssh exists as the store nests under it.
|
||||
if err := os.MkdirAll(filepath.Join(home, ".ssh"), 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return home
|
||||
}
|
||||
|
||||
func TestSettingsRoundTrip(t *testing.T) {
|
||||
withHome(t)
|
||||
s := DefaultSettings()
|
||||
s.YubiKeyEnabled = true
|
||||
s.Sort = SortFrequent
|
||||
if err := SaveSettings(s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := LoadSettings()
|
||||
if !got.YubiKeyEnabled || got.Sort != SortFrequent {
|
||||
t.Errorf("round trip mismatch: %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadCorruptFallsBackToDefaults(t *testing.T) {
|
||||
withHome(t)
|
||||
d, _ := Dir()
|
||||
// Simulate a mid-Syncthing partial write.
|
||||
if err := os.WriteFile(filepath.Join(d, "settings.json"), []byte(`{"yubikey_enabled": tr`), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := LoadSettings()
|
||||
def := DefaultSettings()
|
||||
if got != def {
|
||||
t.Errorf("corrupt settings should yield defaults, got %+v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordAndSort(t *testing.T) {
|
||||
withHome(t)
|
||||
if err := Record("web1"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := Record("web1"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := Record("db"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d := LoadData()
|
||||
if d.Stats["web1"].Count != 2 {
|
||||
t.Errorf("web1 count = %d, want 2", d.Stats["web1"].Count)
|
||||
}
|
||||
if d.Stats["db"].Count != 1 {
|
||||
t.Errorf("db count = %d, want 1", d.Stats["db"].Count)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToggleFavorite(t *testing.T) {
|
||||
withHome(t)
|
||||
on, err := ToggleFavorite("web1")
|
||||
if err != nil || !on {
|
||||
t.Fatalf("expected favorite on, got %v %v", on, err)
|
||||
}
|
||||
off, err := ToggleFavorite("web1")
|
||||
if err != nil || off {
|
||||
t.Fatalf("expected favorite off, got %v %v", off, err)
|
||||
}
|
||||
if len(LoadData().Favorites) != 0 {
|
||||
t.Error("favorites should be empty after toggle off")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user