@@ -135,8 +135,9 @@ describe('ThemeCommand', () => {
135135
136136 test ( 'multiple environments provided - uses renderConcurrent for parallel execution' , async ( ) => {
137137 // Given
138- const environmentConfig = { store : 'store.myshopify.com' }
139- vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
138+ vi . mocked ( loadEnvironment )
139+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
140+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'staging' } )
140141 vi . mocked ( ensureAuthenticatedThemes ) . mockResolvedValue ( mockSession )
141142
142143 vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
@@ -150,7 +151,6 @@ describe('ThemeCommand', () => {
150151 // Then
151152 expect ( loadEnvironment ) . toHaveBeenCalledWith ( 'development' , 'shopify.theme.toml' , { from : undefined , silent : true } )
152153 expect ( loadEnvironment ) . toHaveBeenCalledWith ( 'staging' , 'shopify.theme.toml' , { from : undefined , silent : true } )
153- expect ( ensureAuthenticatedThemes ) . toHaveBeenCalledTimes ( 2 )
154154
155155 expect ( renderConcurrent ) . toHaveBeenCalledOnce ( )
156156 expect ( renderConcurrent ) . toHaveBeenCalledWith (
@@ -166,10 +166,40 @@ describe('ThemeCommand', () => {
166166 } )
167167
168168 describe ( 'multi environment' , ( ) => {
169+ test ( 'commands that act on the same store are run in groups to prevent conflicts' , async ( ) => {
170+ // Given
171+ vi . mocked ( loadEnvironment )
172+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , theme : 'wow a theme' } )
173+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
174+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'another theme' } )
175+
176+ vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
177+ vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
178+
179+ await CommandConfig . load ( )
180+ const command = new TestThemeCommandWithUnionFlags (
181+ [ '--environment' , 'store1-theme' , '--environment' , 'store1-development' , '--environment' , 'store2-theme' ] ,
182+ CommandConfig ,
183+ )
184+
185+ // When
186+ await command . run ( )
187+
188+ // Then
189+ const runGroupOneProcesses = vi . mocked ( renderConcurrent ) . mock . calls [ 0 ] ?. [ 0 ] ?. processes
190+ expect ( runGroupOneProcesses ) . toHaveLength ( 2 )
191+ expect ( runGroupOneProcesses ?. map ( ( process ) => process . prefix ) ) . toEqual ( [ 'store1-theme' , 'store2-theme' ] )
192+
193+ const runGroupTwoProcesses = vi . mocked ( renderConcurrent ) . mock . calls [ 1 ] ?. [ 0 ] ?. processes
194+ expect ( runGroupTwoProcesses ) . toHaveLength ( 1 )
195+ expect ( runGroupTwoProcesses ?. map ( ( process ) => process . prefix ) ) . toEqual ( [ 'store1-development' ] )
196+ } )
197+
169198 test ( 'commands with --force flag should not prompt for confirmation' , async ( ) => {
170199 // Given
171- const environmentConfig = { store : 'store.myshopify.com' }
172- vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
200+ vi . mocked ( loadEnvironment )
201+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
202+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'staging' } )
173203 vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
174204 vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
175205
@@ -198,8 +228,9 @@ describe('ThemeCommand', () => {
198228
199229 test ( 'commands that do not allow --force flag should not prompt for confirmation' , async ( ) => {
200230 // Given
201- const environmentConfig = { store : 'store.myshopify.com' }
202- vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
231+ vi . mocked ( loadEnvironment )
232+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
233+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'staging' } )
203234 vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
204235 vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
205236
@@ -216,8 +247,9 @@ describe('ThemeCommand', () => {
216247
217248 test ( 'commands without --force flag that allow it should prompt for confirmation' , async ( ) => {
218249 // Given
219- const environmentConfig = { store : 'store.myshopify.com' }
220- vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
250+ vi . mocked ( loadEnvironment )
251+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
252+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'staging' } )
221253 vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
222254 vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
223255
@@ -244,8 +276,9 @@ describe('ThemeCommand', () => {
244276
245277 test ( 'should not execute command if confirmation is cancelled' , async ( ) => {
246278 // Given
247- const environmentConfig = { store : 'store.myshopify.com' }
248- vi . mocked ( loadEnvironment ) . mockResolvedValue ( environmentConfig )
279+ vi . mocked ( loadEnvironment )
280+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
281+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'staging' } )
249282 vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( false )
250283 vi . mocked ( renderConcurrent ) . mockResolvedValue ( undefined )
251284
@@ -340,8 +373,10 @@ describe('ThemeCommand', () => {
340373
341374 test ( 'commands error gracefully and continue with other environments' , async ( ) => {
342375 // Given
343- vi . mocked ( loadEnvironment ) . mockResolvedValue ( { store : 'store.myshopify.com' } )
344-
376+ vi . mocked ( loadEnvironment )
377+ . mockResolvedValueOnce ( { store : 'store1.myshopify.com' , development : true } )
378+ . mockResolvedValueOnce ( { store : 'store2.myshopify.com' , theme : 'staging' } )
379+ . mockResolvedValueOnce ( { store : 'store3.myshopify.com' , live : true } )
345380 vi . mocked ( renderConfirmationPrompt ) . mockResolvedValue ( true )
346381 vi . mocked ( renderConcurrent ) . mockImplementation ( async ( { processes} ) => {
347382 for ( const process of processes ) {
0 commit comments