11import ThemeCommand from './theme-command.js'
2+ import { ensureThemeStore } from './theme-store.js'
23import { describe , vi , expect , test , beforeEach } from 'vitest'
34import { Config , Flags } from '@oclif/core'
45import { AdminSession , ensureAuthenticatedThemes } from '@shopify/cli-kit/node/session'
@@ -9,6 +10,7 @@ import type {Writable} from 'stream'
910vi . mock ( '@shopify/cli-kit/node/session' )
1011vi . mock ( '@shopify/cli-kit/node/environments' )
1112vi . mock ( '@shopify/cli-kit/node/ui' )
13+ vi . mock ( './theme-store.js' )
1214
1315const CommandConfig = new Config ( { root : __dirname } )
1416
@@ -45,6 +47,17 @@ class TestThemeCommand extends ThemeCommand {
4547 }
4648}
4749
50+ class TestThemeCommandWithForce extends TestThemeCommand {
51+ static flags = {
52+ ...TestThemeCommand . flags ,
53+ force : Flags . boolean ( {
54+ char : 'f' ,
55+ description : 'Skip confirmation' ,
56+ env : 'SHOPIFY_FLAG_FORCE' ,
57+ } ) ,
58+ }
59+ }
60+
4861describe ( 'ThemeCommand' , ( ) => {
4962 let mockSession : AdminSession
5063
@@ -53,6 +66,7 @@ describe('ThemeCommand', () => {
5366 token : 'test-token' ,
5467 storeFqdn : 'test-store.myshopify.com' ,
5568 }
69+ vi . mocked ( ensureThemeStore ) . mockReturnValue ( 'test-store.myshopify.com' )
5670 vi . mocked ( ensureAuthenticatedThemes ) . mockResolvedValue ( mockSession )
5771 } )
5872
@@ -61,7 +75,6 @@ describe('ThemeCommand', () => {
6175 // Given
6276 await CommandConfig . load ( )
6377 const command = new TestThemeCommand ( [ ] , CommandConfig )
64-
6578 // When
6679 await command . run ( )
6780
@@ -136,6 +149,103 @@ describe('ThemeCommand', () => {
136149 } )
137150
138151 describe ( 'multi environment' , ( ) => {
152+ test ( 'commands with --force flag should not prompt for confirmation' , async ( ) => {
153+ // Given
154+ const environmentConfig = { store : 'store.myshopify.com' }
155+ vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
156+ vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
157+ vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
158+
159+ await CommandConfig . load ( )
160+ const command = new TestThemeCommandWithForce (
161+ [ '--environment' , 'development' , '--environment' , 'staging' , '--force' ] ,
162+ CommandConfig ,
163+ )
164+
165+ // When
166+ await command . run ( )
167+
168+ // Then
169+ expect ( renderConfirmationPrompt ) . not . toHaveBeenCalled ( )
170+ expect ( renderConcurrent ) . toHaveBeenCalledOnce ( )
171+ expect ( renderConcurrent ) . toHaveBeenCalledWith (
172+ expect . objectContaining ( {
173+ processes : expect . arrayContaining ( [
174+ expect . objectContaining ( { prefix : 'development' } ) ,
175+ expect . objectContaining ( { prefix : 'staging' } ) ,
176+ ] ) ,
177+ showTimestamps : true ,
178+ } ) ,
179+ )
180+ } )
181+
182+ test ( 'commands that do not allow --force flag should not prompt for confirmation' , async ( ) => {
183+ // Given
184+ const environmentConfig = { store : 'store.myshopify.com' }
185+ vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
186+ vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
187+ vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
188+
189+ await CommandConfig . load ( )
190+ const command = new TestThemeCommand ( [ '--environment' , 'development' , '--environment' , 'staging' ] , CommandConfig )
191+
192+ // When
193+ await command . run ( )
194+
195+ // Then
196+ expect ( renderConfirmationPrompt ) . not . toHaveBeenCalled ( )
197+ expect ( renderConcurrent ) . toHaveBeenCalledOnce ( )
198+ } )
199+
200+ test ( 'commands without --force flag that allow it should prompt for confirmation' , async ( ) => {
201+ // Given
202+ const environmentConfig = { store : 'store.myshopify.com' }
203+ vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
204+ vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
205+ vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
206+
207+ await CommandConfig . load ( )
208+ const command = new TestThemeCommandWithForce (
209+ [ '--environment' , 'development' , '--environment' , 'staging' ] ,
210+ CommandConfig ,
211+ )
212+
213+ // When
214+ await command . run ( )
215+
216+ // Then
217+ expect ( renderConfirmationPrompt ) . toHaveBeenCalledOnce ( )
218+ expect ( renderConfirmationPrompt ) . toHaveBeenCalledWith (
219+ expect . objectContaining ( {
220+ message : expect . any ( Array ) ,
221+ confirmationMessage : 'Yes, proceed' ,
222+ cancellationMessage : 'Cancel' ,
223+ } ) ,
224+ )
225+ expect ( renderConcurrent ) . toHaveBeenCalledOnce ( )
226+ } )
227+
228+ test ( 'should not execute command if confirmation is cancelled' , async ( ) => {
229+ // Given
230+ const environmentConfig = { store : 'store.myshopify.com' }
231+ vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
232+ vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( false )
233+ vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
234+
235+ await CommandConfig . load ( )
236+ const command = new TestThemeCommandWithForce (
237+ [ '--environment' , 'development' , '--environment' , 'staging' ] ,
238+ CommandConfig ,
239+ )
240+
241+ // When
242+ await command . run ( )
243+
244+ // Then
245+ expect ( renderConfirmationPrompt ) . toHaveBeenCalledOnce ( )
246+ expect ( renderConcurrent ) . not . toHaveBeenCalled ( )
247+ } )
248+
139249 test ( 'should not execute commands in environments that are missing required flags' , async ( ) => {
140250 // Given
141251 vi . mocked ( loadEnvironment )
0 commit comments