aboutsummaryrefslogtreecommitdiff
path: root/internal/cli/cmd_main_test.go
diff options
context:
space:
mode:
authortsne <tsne.dev@outlook.com>2026-07-06 16:52:20 +0200
committertsne <tsne.dev@outlook.com>2026-07-06 19:21:15 +0200
commit2c41acab4c97f584e8e199b31dc456194b8d7e6c (patch)
tree42381deb6c4f6da0f32945432207a31b4d86664e /internal/cli/cmd_main_test.go
downloadhopper-2c41acab4c97f584e8e199b31dc456194b8d7e6c.tar.gz
initial
Diffstat (limited to 'internal/cli/cmd_main_test.go')
-rw-r--r--internal/cli/cmd_main_test.go126
1 files changed, 126 insertions, 0 deletions
diff --git a/internal/cli/cmd_main_test.go b/internal/cli/cmd_main_test.go
new file mode 100644
index 0000000..d383970
--- /dev/null
+++ b/internal/cli/cmd_main_test.go
@@ -0,0 +1,126 @@
+package cli
+
+import (
+ "context"
+ "errors"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+// clearGlobalEnv neutralizes the BUNNY_ env fallbacks so a test controls
+// resolution entirely through flags.
+func clearGlobalEnv(t *testing.T) {
+ t.Helper()
+ for _, k := range []string{"BUNNY_ZONE", "BUNNY_ENDPOINT", "BUNNY_ACCESS_KEY_FILE", "BUNNY_ACCESS_KEY"} {
+ t.Setenv(k, "")
+ }
+}
+
+func writeKeyFile(t *testing.T) string {
+ t.Helper()
+ p := filepath.Join(t.TempDir(), "key")
+ if err := os.WriteFile(p, []byte("secret\n"), 0o600); err != nil {
+ t.Fatal(err)
+ }
+ return p
+}
+
+func runMain(args []string) error {
+ return newMainCommand().Run(context.Background(), args)
+}
+
+func TestMainMissingSubcommand(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+
+ var ue usageError
+ if err := runMain(nil); !errors.As(err, &ue) {
+ t.Fatalf("expected usageError, got %v", err)
+ }
+}
+
+func TestMainMissingZone(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+
+ var ue usageError
+ err := runMain([]string{"push"})
+ if !errors.As(err, &ue) || !strings.Contains(err.Error(), "zone") {
+ t.Fatalf("expected missing-zone usageError, got %v", err)
+ }
+}
+
+func TestMainMissingAccessKey(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+
+ var ue usageError
+ err := runMain([]string{"--zone", "z", "push"})
+ if !errors.As(err, &ue) || !strings.Contains(err.Error(), "access key") {
+ t.Fatalf("expected missing-access-key usageError, got %v", err)
+ }
+}
+
+func TestMainUnknownSubcommand(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+ kf := writeKeyFile(t)
+
+ var ue usageError
+ err := runMain([]string{"--zone", "z", "--access-key-file", kf, "frob"})
+ if !errors.As(err, &ue) || !strings.Contains(err.Error(), "unknown subcommand") {
+ t.Fatalf("expected unknown-subcommand usageError, got %v", err)
+ }
+}
+
+func TestMainDispatchesToPrune(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+ kf := writeKeyFile(t)
+
+ // A fully-resolved global set reaches dispatch; the missing archive surfaces a
+ // plain (non-usage) error, proving parse + validation + dispatch worked.
+ err := runMain([]string{"--zone", "z", "--access-key-file", kf, "prune", "no-such.tgz"})
+ if err == nil || !strings.Contains(err.Error(), "open archive") {
+ t.Fatalf("expected prune dispatch error, got %v", err)
+ }
+}
+
+func TestMainAccessKeyFromEnv(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+ t.Setenv("BUNNY_ACCESS_KEY", "literalkey")
+
+ // With no --access-key-file, the literal BUNNY_ACCESS_KEY resolves the key
+ // and resolution reaches prune.
+ err := runMain([]string{"--zone", "z", "prune", "no-such.tgz"})
+ if err == nil || !strings.Contains(err.Error(), "open archive") {
+ t.Fatalf("expected prune dispatch error (env access key resolved), got %v", err)
+ }
+}
+
+func TestMainZoneFromEnv(t *testing.T) {
+ clearGlobalEnv(t)
+ captureLogs(t)
+ t.Setenv("BUNNY_ZONE", "envzone")
+ kf := writeKeyFile(t)
+
+ // With zone supplied via env, resolution succeeds and reaches prune.
+ err := runMain([]string{"--access-key-file", kf, "prune", "no-such.tgz"})
+ if err == nil || !strings.Contains(err.Error(), "open archive") {
+ t.Fatalf("expected prune dispatch error (env zone resolved), got %v", err)
+ }
+}
+
+func TestLookupEnv(t *testing.T) {
+ t.Setenv("BUNNY_TEST_LOOKUP", "value")
+ if got := lookupEnv("BUNNY_TEST_LOOKUP", "fallback"); got != "value" {
+ t.Fatalf("set env: got %q", got)
+ }
+ t.Setenv("BUNNY_TEST_LOOKUP", "")
+ if got := lookupEnv("BUNNY_TEST_LOOKUP", "fallback"); got != "fallback" {
+ t.Fatalf("empty env should fall back: got %q", got)
+ }
+}