Skip to content

Commit fe01118

Browse files
committed
Route new users from setup to signup wizard
fizzy setup now asks "Do you have a Fizzy account?" before proceeding. Users without an account are routed into the existing signup flow, so the README's "fizzy setup" instruction works for everyone.
1 parent cca24e1 commit fe01118

2 files changed

Lines changed: 72 additions & 2 deletions

File tree

internal/commands/setup.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Board struct {
2828
var setupCmd = &cobra.Command{
2929
Use: "setup",
3030
Short: "Interactive setup wizard",
31-
Long: "Configure Fizzy CLI with your API token, account, and default board.",
31+
Long: "Configure Fizzy CLI with your API token, account, and default board.\nNew users without an account will be guided through signup.",
3232
RunE: runSetup,
3333
}
3434

@@ -45,6 +45,26 @@ func runSetup(cmd *cobra.Command, args []string) error {
4545
fmt.Println("Welcome to Fizzy CLI setup!")
4646
fmt.Println()
4747

48+
// Ask if user has an account before checking existing config
49+
var hasAccount string
50+
err := huh.NewSelect[string]().
51+
Title("Do you have a Fizzy account?").
52+
Options(
53+
huh.NewOption("Yes, I have an account", "yes"),
54+
huh.NewOption("No, I'd like to sign up", "no"),
55+
).
56+
Value(&hasAccount).
57+
Run()
58+
59+
if err != nil {
60+
fmt.Println("Setup cancelled.")
61+
return nil //nolint:nilerr // user cancelled prompt
62+
}
63+
64+
if hasAccount == "no" {
65+
return runSignup(cmd, args)
66+
}
67+
4868
// Check for existing config
4969
globalExists := config.Exists()
5070
localPath := config.LocalConfigPath()
@@ -74,7 +94,7 @@ func runSetup(cmd *cobra.Command, args []string) error {
7494

7595
// Ask hosted vs self-hosted
7696
var hostingType string
77-
err := huh.NewSelect[string]().
97+
err = huh.NewSelect[string]().
7898
Title("Are you using the hosted or self-hosted version?").
7999
Options(
80100
huh.NewOption("Hosted (app.fizzy.do)", "hosted"),

internal/commands/setup_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,62 @@ package commands
33
import (
44
"os"
55
"path/filepath"
6+
"strings"
67
"testing"
78

89
"github.com/basecamp/fizzy-cli/internal/config"
910
"gopkg.in/yaml.v3"
1011
)
1112

13+
func TestSetupCommandDescription(t *testing.T) {
14+
t.Run("long description mentions signup for new users", func(t *testing.T) {
15+
if !strings.Contains(setupCmd.Long, "signup") {
16+
t.Error("expected setup command long description to mention signup")
17+
}
18+
})
19+
}
20+
21+
func TestSetupRejectsMachineOutput(t *testing.T) {
22+
t.Run("rejects agent mode", func(t *testing.T) {
23+
defer ResetTestMode()
24+
ResetTestMode()
25+
cfgAgent = true
26+
err := runSetup(setupCmd, nil)
27+
if err == nil {
28+
t.Fatal("expected error when running setup with --agent")
29+
}
30+
if !strings.Contains(err.Error(), "interactive terminal") {
31+
t.Errorf("unexpected error: %v", err)
32+
}
33+
})
34+
35+
t.Run("rejects JSON mode", func(t *testing.T) {
36+
defer ResetTestMode()
37+
ResetTestMode()
38+
cfgJSON = true
39+
err := runSetup(setupCmd, nil)
40+
if err == nil {
41+
t.Fatal("expected error when running setup with --json")
42+
}
43+
if !strings.Contains(err.Error(), "interactive terminal") {
44+
t.Errorf("unexpected error: %v", err)
45+
}
46+
})
47+
48+
t.Run("rejects quiet mode", func(t *testing.T) {
49+
defer ResetTestMode()
50+
ResetTestMode()
51+
cfgQuiet = true
52+
err := runSetup(setupCmd, nil)
53+
if err == nil {
54+
t.Fatal("expected error when running setup with --quiet")
55+
}
56+
if !strings.Contains(err.Error(), "interactive terminal") {
57+
t.Errorf("unexpected error: %v", err)
58+
}
59+
})
60+
}
61+
1262
func TestParseAccounts(t *testing.T) {
1363
t.Run("parses accounts from identity response", func(t *testing.T) {
1464
data := map[string]any{

0 commit comments

Comments
 (0)