Skip to content

Commit 358f1cc

Browse files
authored
fix: open the list of apps if no known apps are found for "app settings" command (#314)
1 parent 8321475 commit 358f1cc

2 files changed

Lines changed: 88 additions & 6 deletions

File tree

cmd/app/settings.go

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func NewSettingsCommand(clients *shared.ClientFactory) *cobra.Command {
4545
}, "\n"),
4646
Example: style.ExampleCommandsf([]style.ExampleCommand{
4747
{
48-
Meaning: "Open app settings for a prompted app",
48+
Meaning: "Open app settings dashboard",
4949
Command: "app settings",
5050
},
5151
{
@@ -65,11 +65,12 @@ func NewSettingsCommand(clients *shared.ClientFactory) *cobra.Command {
6565
}
6666

6767
// appSettingsCommandPreRunE determines if the command can be run in a project
68+
// or if the command is run outside of a project
6869
func appSettingsCommandPreRunE(clients *shared.ClientFactory, cmd *cobra.Command, args []string) error {
6970
ctx := cmd.Context()
7071
err := cmdutil.IsValidProjectDirectory(clients)
7172
if err != nil {
72-
return err
73+
return nil
7374
}
7475
// Allow the force flag to ignore hosted apps and try to open app settings
7576
if clients.Config.ForceFlag {
@@ -98,6 +99,28 @@ func appSettingsCommandRunE(clients *shared.ClientFactory, cmd *cobra.Command, a
9899

99100
app, err := settingsAppSelectPromptFunc(ctx, clients, prompts.ShowAllEnvironments, prompts.ShowInstalledAndUninstalledApps)
100101
if err != nil {
102+
// If no apps exist, open the list of all apps known to the developer
103+
if slackerror.Is(err, slackerror.ErrInstallationRequired) {
104+
host := clients.API().Host()
105+
parsed, err := url.Parse(host)
106+
if err != nil {
107+
return err
108+
}
109+
parsed.Host = "api." + parsed.Host
110+
settingsURL := fmt.Sprintf("%s/apps", parsed.String())
111+
112+
clients.IO.PrintInfo(ctx, false, "\n%s", style.Sectionf(style.TextSection{
113+
Emoji: "house",
114+
Text: "App Settings",
115+
Secondary: []string{
116+
settingsURL,
117+
},
118+
}))
119+
clients.Browser().OpenURL(settingsURL)
120+
121+
clients.IO.PrintTrace(ctx, slacktrace.AppSettingsSuccess, settingsURL)
122+
return nil
123+
}
101124
return err
102125
}
103126
host := clients.API().Host()

cmd/app/settings_test.go

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,28 @@ import (
3232

3333
func Test_App_SettingsCommand(t *testing.T) {
3434
testutil.TableTestCommand(t, testutil.CommandTests{
35-
"requires a valid project directory": {
36-
ExpectedError: slackerror.New(slackerror.ErrInvalidAppDirectory),
35+
"opens app listing page when not in a project directory": {
36+
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
37+
appSelectMock := prompts.NewAppSelectMock()
38+
appSelectMock.On(
39+
"AppSelectPrompt",
40+
mock.Anything,
41+
mock.Anything,
42+
prompts.ShowAllEnvironments,
43+
prompts.ShowInstalledAndUninstalledApps,
44+
).Return(
45+
prompts.SelectedApp{},
46+
slackerror.New(slackerror.ErrInstallationRequired),
47+
)
48+
settingsAppSelectPromptFunc = appSelectMock.AppSelectPrompt
49+
cm.API.On("Host").Return("https://slack.com")
50+
},
51+
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
52+
expectedURL := "https://api.slack.com/apps"
53+
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
54+
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsStart, mock.Anything)
55+
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsSuccess, []string{expectedURL})
56+
},
3757
},
3858
"errors for rosi applications": {
3959
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
@@ -113,7 +133,40 @@ func Test_App_SettingsCommand(t *testing.T) {
113133
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsSuccess, []string{expectedURL})
114134
},
115135
},
116-
"requires an existing application": {
136+
"opens app listing page when no apps exist": {
137+
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
138+
cf.SDKConfig.WorkingDirectory = "."
139+
projectConfigMock := config.NewProjectConfigMock()
140+
projectConfigMock.On(
141+
"GetManifestSource",
142+
mock.Anything,
143+
).Return(
144+
config.ManifestSourceRemote,
145+
nil,
146+
)
147+
cm.Config.ProjectConfig = projectConfigMock
148+
appSelectMock := prompts.NewAppSelectMock()
149+
appSelectMock.On(
150+
"AppSelectPrompt",
151+
mock.Anything,
152+
mock.Anything,
153+
prompts.ShowAllEnvironments,
154+
prompts.ShowInstalledAndUninstalledApps,
155+
).Return(
156+
prompts.SelectedApp{},
157+
slackerror.New(slackerror.ErrInstallationRequired),
158+
)
159+
settingsAppSelectPromptFunc = appSelectMock.AppSelectPrompt
160+
cm.API.On("Host").Return("https://slack.com")
161+
},
162+
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
163+
expectedURL := "https://api.slack.com/apps"
164+
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
165+
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsStart, mock.Anything)
166+
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsSuccess, []string{expectedURL})
167+
},
168+
},
169+
"opens app listing page for development environment when no apps exist": {
117170
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
118171
cf.SDKConfig.WorkingDirectory = "."
119172
projectConfigMock := config.NewProjectConfigMock()
@@ -137,8 +190,14 @@ func Test_App_SettingsCommand(t *testing.T) {
137190
slackerror.New(slackerror.ErrInstallationRequired),
138191
)
139192
settingsAppSelectPromptFunc = appSelectMock.AppSelectPrompt
193+
cm.API.On("Host").Return("https://dev1234.slack.com")
194+
},
195+
ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) {
196+
expectedURL := "https://api.dev1234.slack.com/apps"
197+
cm.Browser.AssertCalled(t, "OpenURL", expectedURL)
198+
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsStart, mock.Anything)
199+
cm.IO.AssertCalled(t, "PrintTrace", mock.Anything, slacktrace.AppSettingsSuccess, []string{expectedURL})
140200
},
141-
ExpectedError: slackerror.New(slackerror.ErrInstallationRequired),
142201
},
143202
"opens the url to app settings of an app in production": {
144203
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {

0 commit comments

Comments
 (0)