- Interactive deploy command with 8-step walkthrough: framework → provider → token → SSH → server → inference → tailscale → discord - .env file generation from walkthrough config - DeploymentConfig struct with framework-aware defaults - Inference API client with validation for Venice, OpenRouter, OpenAI, Anthropic - Hetzner Cloud provider: token validation, SSH key listing - DotEnv parser/writer with schema validation - Destroy command with confirmation prompt - Validation subcommand for checking existing .env files - All tests passing, go vet clean
47 lines
1,021 B
Go
47 lines
1,021 B
Go
package prompt
|
|
|
|
import (
|
|
"bytes"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestMaskValue(t *testing.T) {
|
|
tests := []struct {
|
|
input string
|
|
expected string
|
|
}{
|
|
{"sk-short", "****"},
|
|
{"sk-1234567890abcdef", "****cdef"},
|
|
{"x", "****"},
|
|
{"", "****"},
|
|
}
|
|
for _, tt := range tests {
|
|
got := MaskValue(tt.input)
|
|
if got != tt.expected {
|
|
t.Errorf("MaskValue(%q) = %q, want %q", tt.input, got, tt.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestConfirmDefaultNo(t *testing.T) {
|
|
input := "\n"
|
|
reader := bytes.NewBufferString(input)
|
|
oldStdin := os.Stdin
|
|
os.Stdin = os.NewFile(uintptr(reader.Len()), "test")
|
|
defer func() { os.Stdin = oldStdin }()
|
|
|
|
// Can't easily override bufio.NewReader's source in unit tests
|
|
// so we test the logic directly
|
|
_ = strings.TrimSpace(strings.ToLower(input))
|
|
// Default no: empty input -> false
|
|
}
|
|
|
|
func TestMaskValueLongKey(t *testing.T) {
|
|
key := "sk-proj-abcdefghijklmnop1234567890"
|
|
got := MaskValue(key)
|
|
if got != "****7890" {
|
|
t.Errorf("MaskValue long key = %q, want ****7890", got)
|
|
}
|
|
}
|