Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion pkg/cmd/application/selectapp/select.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type SelectOptions struct {
IO *iostreams.IOStreams
Config config.IConfig

AppID string
AppName string

NewDashboardClient func(clientID string) *dashboard.Client
Expand Down Expand Up @@ -49,6 +50,9 @@ func NewSelectCmd(f *cmdutil.Factory) *cobra.Command {

# Select by name (non-interactive)
$ algolia application select --app-name "My App"

# Select by application ID (non-interactive)
$ algolia application select --app-id "ABCDEF1234"
`),
Aliases: []string{"use"},
Args: validators.NoArgs(),
Expand All @@ -61,8 +65,11 @@ func NewSelectCmd(f *cmdutil.Factory) *cobra.Command {
},
}

cmd.Flags().
StringVar(&opts.AppID, "app-id", "", "Select application by ID (non-interactive)")
cmd.Flags().
StringVar(&opts.AppName, "app-name", "", "Select application by name (non-interactive)")
cmd.MarkFlagsMutuallyExclusive("app-id", "app-name")

return cmd
}
Expand Down Expand Up @@ -143,6 +150,15 @@ func pickApplication(
opts *SelectOptions,
apps []dashboard.Application,
) (*dashboard.Application, error) {
if opts.AppID != "" {
for i := range apps {
if apps[i].ID == opts.AppID {
return &apps[i], nil
}
}
return nil, fmt.Errorf("application with ID %q not found", opts.AppID)
}

if opts.AppName != "" {
for i := range apps {
if apps[i].Name == opts.AppName {
Expand All @@ -153,7 +169,7 @@ func pickApplication(
}

if !opts.IO.CanPrompt() {
return nil, fmt.Errorf("--app-name is required in non-interactive mode")
return nil, fmt.Errorf("--app-id or --app-name is required in non-interactive mode")
}

cs := opts.IO.ColorScheme()
Expand Down
69 changes: 65 additions & 4 deletions pkg/cmd/application/selectapp/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,33 @@ func selectServer(t *testing.T, createHit *bool) *httptest.Server {
}

func newSelectOpts(t *testing.T, srv *httptest.Server, cfg *test.ConfigStub) *SelectOptions {
t.Helper()
// --app-name bypasses the interactive picker.
return newSelectOptsWithSelector(t, srv, cfg, func(opts *SelectOptions) {
opts.AppName = "My App"
})
}

func newSelectOptsWithSelector(
t *testing.T,
srv *httptest.Server,
cfg *test.ConfigStub,
selector func(*SelectOptions),
) *SelectOptions {
t.Helper()
seedToken(t)
io, _, _, _ := iostreams.Test()
return &SelectOptions{
IO: io,
Config: cfg,
AppName: "My App", // bypasses the interactive picker
opts := &SelectOptions{
IO: io,
Config: cfg,
NewDashboardClient: func(string) *dashboard.Client {
c := dashboard.NewClientWithHTTPClient("test", srv.Client())
c.APIURL = srv.URL
return c
},
}
selector(opts)
return opts
}

func Test_runSelectCmd_RegeneratesKeyWhenNoUUID(t *testing.T) {
Expand Down Expand Up @@ -122,3 +136,50 @@ func Test_runSelectCmd_ReusesKeyWhenUUIDPresent(t *testing.T) {
assert.False(t, createHit, "expected no new key when a UUID is already stored")
assert.Equal(t, "existing-uuid", cfg.SavedApps["APP1"].APIKeyUUID)
}

func Test_runSelectCmd_SelectsByAppID(t *testing.T) {
createHit := false
srv := selectServer(t, &createHit)
defer srv.Close()

cfg := &test.ConfigStub{}
opts := newSelectOptsWithSelector(t, srv, cfg, func(o *SelectOptions) {
o.AppID = "APP1"
})

app, err := runSelectCmd(opts)
require.NoError(t, err)
require.NotNil(t, app)

assert.Equal(t, "APP1", app.ID)
assert.Equal(t, "My App", app.Name)
assert.Equal(t, "new-key", cfg.SavedApps["APP1"].APIKey)
}

func Test_runSelectCmd_UnknownAppID(t *testing.T) {
createHit := false
srv := selectServer(t, &createHit)
defer srv.Close()

opts := newSelectOptsWithSelector(t, srv, &test.ConfigStub{}, func(o *SelectOptions) {
o.AppID = "NOPE"
})

_, err := runSelectCmd(opts)
require.Error(t, err)
assert.Equal(t, `application with ID "NOPE" not found`, err.Error())
assert.False(t, createHit)
}

func Test_runSelectCmd_RequiresSelectorWhenNonInteractive(t *testing.T) {
createHit := false
srv := selectServer(t, &createHit)
defer srv.Close()

// iostreams.Test() is not a TTY, so the picker is unavailable.
opts := newSelectOptsWithSelector(t, srv, &test.ConfigStub{}, func(*SelectOptions) {})

_, err := runSelectCmd(opts)
require.Error(t, err)
assert.Equal(t, "--app-id or --app-name is required in non-interactive mode", err.Error())
}
Loading