@@ -46,6 +46,7 @@ func TestCreateCommand(t *testing.T) {
4646 testutil .TableTestCommand (t , testutil.CommandTests {
4747 "creates a bolt application from prompts" : {
4848 Setup : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock , cf * shared.ClientFactory ) {
49+ cm .IO .On ("IsTTY" ).Return (true )
4950 cm .IO .On ("SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything ).
5051 Return (
5152 iostreams.SelectPromptResponse {
@@ -62,6 +63,8 @@ func TestCreateCommand(t *testing.T) {
6263 },
6364 nil ,
6465 )
66+ cm .IO .On ("InputPrompt" , mock .Anything , "Name your app:" , mock .Anything ).
67+ Return ("my-app" , nil )
6568 createClientMock = new (CreateClientMock )
6669 createClientMock .On ("Create" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return ("" , nil )
6770 CreateFunc = createClientMock .Create
@@ -70,14 +73,17 @@ func TestCreateCommand(t *testing.T) {
7073 template , err := create .ResolveTemplateURL ("slack-samples/bolt-js-starter-template" )
7174 require .NoError (t , err )
7275 expected := create.CreateArgs {
76+ AppName : "my-app" ,
7377 Template : template ,
7478 }
7579 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
80+ cm .IO .AssertCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
7681 },
7782 },
7883 "creates a deno application from flags" : {
7984 CmdArgs : []string {"--template" , "slack-samples/deno-starter-template" },
8085 Setup : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock , cf * shared.ClientFactory ) {
86+ cm .IO .On ("IsTTY" ).Return (true )
8187 cm .IO .On ("SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything ).
8288 Return (
8389 iostreams.SelectPromptResponse {
@@ -94,6 +100,8 @@ func TestCreateCommand(t *testing.T) {
94100 },
95101 nil ,
96102 )
103+ cm .IO .On ("InputPrompt" , mock .Anything , "Name your app:" , mock .Anything ).
104+ Return ("my-deno-app" , nil )
97105 createClientMock = new (CreateClientMock )
98106 createClientMock .On ("Create" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return ("" , nil )
99107 CreateFunc = createClientMock .Create
@@ -102,14 +110,17 @@ func TestCreateCommand(t *testing.T) {
102110 template , err := create .ResolveTemplateURL ("slack-samples/deno-starter-template" )
103111 require .NoError (t , err )
104112 expected := create.CreateArgs {
113+ AppName : "my-deno-app" ,
105114 Template : template ,
106115 }
107116 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
117+ cm .IO .AssertCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
108118 },
109119 },
110120 "creates an agent app using agent argument shortcut" : {
111121 CmdArgs : []string {"agent" },
112122 Setup : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock , cf * shared.ClientFactory ) {
123+ cm .IO .On ("IsTTY" ).Return (true )
113124 // Should skip category prompt and go directly to language selection
114125 cm .IO .On ("SelectPrompt" , mock .Anything , "Select a language:" , mock .Anything , mock .Anything ).
115126 Return (
@@ -119,6 +130,8 @@ func TestCreateCommand(t *testing.T) {
119130 },
120131 nil ,
121132 )
133+ cm .IO .On ("InputPrompt" , mock .Anything , "Name your app:" , mock .Anything ).
134+ Return ("my-agent" , nil )
122135 createClientMock = new (CreateClientMock )
123136 createClientMock .On ("Create" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return ("" , nil )
124137 CreateFunc = createClientMock .Create
@@ -127,11 +140,13 @@ func TestCreateCommand(t *testing.T) {
127140 template , err := create .ResolveTemplateURL ("slack-samples/bolt-js-assistant-template" )
128141 require .NoError (t , err )
129142 expected := create.CreateArgs {
143+ AppName : "my-agent" ,
130144 Template : template ,
131145 }
132146 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
133147 // Verify that category prompt was NOT called
134148 cm .IO .AssertNotCalled (t , "SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything )
149+ cm .IO .AssertCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
135150 },
136151 },
137152 "creates an agent app with app name using agent argument" : {
@@ -160,6 +175,8 @@ func TestCreateCommand(t *testing.T) {
160175 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
161176 // Verify that category prompt was NOT called
162177 cm .IO .AssertNotCalled (t , "SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything )
178+ // Verify that name prompt was NOT called since name was provided as arg
179+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
163180 },
164181 },
165182 "creates an app named agent when template flag is provided" : {
@@ -193,6 +210,8 @@ func TestCreateCommand(t *testing.T) {
193210 Template : template ,
194211 }
195212 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
213+ // Verify that name prompt was NOT called since name was provided as arg
214+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
196215 },
197216 },
198217 "creates an app named agent using name flag without triggering shortcut" : {
@@ -229,6 +248,8 @@ func TestCreateCommand(t *testing.T) {
229248 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
230249 // Verify that category prompt WAS called (shortcut was not triggered)
231250 cm .IO .AssertCalled (t , "SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything )
251+ // Verify that name prompt was NOT called since --name flag was provided
252+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
232253 },
233254 },
234255 "creates an agent app with name flag overriding positional arg" : {
@@ -290,6 +311,8 @@ func TestCreateCommand(t *testing.T) {
290311 Template : template ,
291312 }
292313 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
314+ // Verify that name prompt was NOT called since --name flag was provided
315+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
293316 },
294317 },
295318 "name flag overrides positional app name argument with agent shortcut" : {
@@ -318,6 +341,110 @@ func TestCreateCommand(t *testing.T) {
318341 createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
319342 // Verify that category prompt was NOT called (agent shortcut was triggered)
320343 cm .IO .AssertNotCalled (t , "SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything )
344+ // Verify that name prompt was NOT called since --name flag was provided
345+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
346+ },
347+ },
348+ "user accepts default name from prompt" : {
349+ Setup : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock , cf * shared.ClientFactory ) {
350+ cm .IO .On ("IsTTY" ).Return (true )
351+ cm .IO .On ("SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything ).
352+ Return (
353+ iostreams.SelectPromptResponse {
354+ Prompt : true ,
355+ Index : 0 ,
356+ },
357+ nil ,
358+ )
359+ cm .IO .On ("SelectPrompt" , mock .Anything , "Select a language:" , mock .Anything , mock .Anything ).
360+ Return (
361+ iostreams.SelectPromptResponse {
362+ Prompt : true ,
363+ Index : 0 ,
364+ },
365+ nil ,
366+ )
367+ // Return empty string to simulate pressing Enter (accepting default)
368+ cm .IO .On ("InputPrompt" , mock .Anything , "Name your app:" , mock .Anything ).
369+ Return ("" , nil )
370+ createClientMock = new (CreateClientMock )
371+ createClientMock .On ("Create" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return ("" , nil )
372+ CreateFunc = createClientMock .Create
373+ },
374+ ExpectedAsserts : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock ) {
375+ cm .IO .AssertCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
376+ // When the user accepts the default (empty return), the generated name is used
377+ createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , mock .MatchedBy (func (args create.CreateArgs ) bool {
378+ return args .AppName != ""
379+ }))
380+ },
381+ },
382+ "non-TTY without name falls back to generated name" : {
383+ CmdArgs : []string {"--template" , "slack-samples/bolt-js-starter-template" },
384+ Setup : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock , cf * shared.ClientFactory ) {
385+ // IsTTY defaults to false via AddDefaultMocks, simulating piped output
386+ cm .IO .On ("SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything ).
387+ Return (
388+ iostreams.SelectPromptResponse {
389+ Flag : true ,
390+ Option : "slack-samples/bolt-js-starter-template" ,
391+ },
392+ nil ,
393+ )
394+ cm .IO .On ("SelectPrompt" , mock .Anything , "Select a language:" , mock .Anything , mock .Anything ).
395+ Return (
396+ iostreams.SelectPromptResponse {
397+ Flag : true ,
398+ Option : "slack-samples/bolt-js-starter-template" ,
399+ },
400+ nil ,
401+ )
402+ createClientMock = new (CreateClientMock )
403+ createClientMock .On ("Create" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return ("" , nil )
404+ CreateFunc = createClientMock .Create
405+ },
406+ ExpectedAsserts : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock ) {
407+ // Should NOT prompt for name since not a TTY
408+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
409+ // Should still call Create with a non-empty generated name
410+ createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , mock .MatchedBy (func (args create.CreateArgs ) bool {
411+ return args .AppName != ""
412+ }))
413+ },
414+ },
415+ "positional arg skips name prompt" : {
416+ CmdArgs : []string {"my-project" },
417+ Setup : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock , cf * shared.ClientFactory ) {
418+ cm .IO .On ("SelectPrompt" , mock .Anything , "Select an app:" , mock .Anything , mock .Anything ).
419+ Return (
420+ iostreams.SelectPromptResponse {
421+ Prompt : true ,
422+ Index : 0 ,
423+ },
424+ nil ,
425+ )
426+ cm .IO .On ("SelectPrompt" , mock .Anything , "Select a language:" , mock .Anything , mock .Anything ).
427+ Return (
428+ iostreams.SelectPromptResponse {
429+ Prompt : true ,
430+ Index : 0 ,
431+ },
432+ nil ,
433+ )
434+ createClientMock = new (CreateClientMock )
435+ createClientMock .On ("Create" , mock .Anything , mock .Anything , mock .Anything , mock .Anything ).Return ("" , nil )
436+ CreateFunc = createClientMock .Create
437+ },
438+ ExpectedAsserts : func (t * testing.T , ctx context.Context , cm * shared.ClientsMock ) {
439+ template , err := create .ResolveTemplateURL ("slack-samples/bolt-js-starter-template" )
440+ require .NoError (t , err )
441+ expected := create.CreateArgs {
442+ AppName : "my-project" ,
443+ Template : template ,
444+ }
445+ createClientMock .AssertCalled (t , "Create" , mock .Anything , mock .Anything , mock .Anything , expected )
446+ // Verify that name prompt was NOT called since name was provided as positional arg
447+ cm .IO .AssertNotCalled (t , "InputPrompt" , mock .Anything , "Name your app:" , mock .Anything )
321448 },
322449 },
323450 "subdir without template flag returns error" : {
0 commit comments