@@ -10,8 +10,11 @@ import {
1010 testOrganizationStore ,
1111} from '../models/app/app.test-data.js'
1212import metadata from '../metadata.js'
13+ import { appHiddenConfigPath , AppLinkedInterface } from '../models/app/app.js'
1314import { vi , describe , test , expect } from 'vitest'
1415import { hashString } from '@shopify/cli-kit/node/crypto'
16+ import { inTemporaryDirectory , mkdir , readFile , writeFile } from '@shopify/cli-kit/node/fs'
17+ import { joinPath } from '@shopify/cli-kit/node/path'
1518
1619vi . mock ( './dev/fetch' )
1720vi . mock ( './dev/select-store' )
@@ -38,80 +41,95 @@ describe('storeContext', () => {
3841 }
3942
4043 test ( 'uses explicitly provided storeFqdn' , async ( ) => {
41- vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
42-
43- const result = await storeContext ( {
44- appContextResult,
45- storeFqdn : 'explicit-store.myshopify.com' ,
46- forceReselectStore : false ,
44+ await inTemporaryDirectory ( async ( dir ) => {
45+ vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
46+ await prepareAppFolder ( mockApp , dir )
47+
48+ const result = await storeContext ( {
49+ appContextResult,
50+ storeFqdn : 'explicit-store.myshopify.com' ,
51+ forceReselectStore : false ,
52+ } )
53+
54+ expect ( fetchStore ) . toHaveBeenCalledWith (
55+ mockOrganization ,
56+ 'explicit-store.myshopify.com' ,
57+ mockDeveloperPlatformClient ,
58+ )
59+ expect ( convertToTransferDisabledStoreIfNeeded ) . toHaveBeenCalledWith (
60+ mockStore ,
61+ mockOrganization . id ,
62+ mockDeveloperPlatformClient ,
63+ 'never' ,
64+ )
65+ expect ( result ) . toEqual ( mockStore )
4766 } )
48-
49- expect ( fetchStore ) . toHaveBeenCalledWith (
50- mockOrganization ,
51- 'explicit-store.myshopify.com' ,
52- mockDeveloperPlatformClient ,
53- )
54- expect ( convertToTransferDisabledStoreIfNeeded ) . toHaveBeenCalledWith (
55- mockStore ,
56- mockOrganization . id ,
57- mockDeveloperPlatformClient ,
58- 'never' ,
59- )
60- expect ( result ) . toEqual ( mockStore )
6167 } )
6268
6369 test ( 'uses cached dev_store_url when no explicit storeFqdn is provided' , async ( ) => {
64- vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
65-
66- const result = await storeContext ( {
67- appContextResult,
68- forceReselectStore : false ,
70+ await inTemporaryDirectory ( async ( dir ) => {
71+ vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
72+ await prepareAppFolder ( mockApp , dir )
73+
74+ const result = await storeContext ( {
75+ appContextResult,
76+ forceReselectStore : false ,
77+ } )
78+
79+ expect ( fetchStore ) . toHaveBeenCalledWith (
80+ mockOrganization ,
81+ 'cached-store.myshopify.com' ,
82+ mockDeveloperPlatformClient ,
83+ )
84+ expect ( result ) . toEqual ( mockStore )
6985 } )
70-
71- expect ( fetchStore ) . toHaveBeenCalledWith ( mockOrganization , 'cached-store.myshopify.com' , mockDeveloperPlatformClient )
72- expect ( result ) . toEqual ( mockStore )
7386 } )
7487
7588 test ( 'fetches and selects store when no storeFqdn or cached value is available' , async ( ) => {
76- const appWithoutCachedStore = testAppLinked ( )
77- const allStores = [ mockStore , { ...mockStore , shopId : 'store2' , shopDomain : 'another-store.myshopify.com' } ]
78-
79- vi . mocked ( mockDeveloperPlatformClient . devStoresForOrg ) . mockResolvedValue ( { stores : allStores , hasMorePages : false } )
80- vi . mocked ( selectStore ) . mockResolvedValue ( mockStore )
81-
82- const updatedAppContextResult = { ...appContextResult , app : appWithoutCachedStore }
83- const result = await storeContext ( {
84- appContextResult : updatedAppContextResult ,
85- forceReselectStore : false ,
89+ await inTemporaryDirectory ( async ( dir ) => {
90+ const appWithoutCachedStore = testAppLinked ( )
91+ await prepareAppFolder ( appWithoutCachedStore , dir )
92+ const allStores = [ mockStore , { ...mockStore , shopId : 'store2' , shopDomain : 'another-store.myshopify.com' } ]
93+
94+ vi . mocked ( mockDeveloperPlatformClient . devStoresForOrg ) . mockResolvedValue ( { stores : allStores , hasMorePages : false } )
95+ vi . mocked ( selectStore ) . mockResolvedValue ( mockStore )
96+
97+ const updatedAppContextResult = { ...appContextResult , app : appWithoutCachedStore }
98+ const result = await storeContext ( {
99+ appContextResult : updatedAppContextResult ,
100+ forceReselectStore : false ,
101+ } )
102+
103+ expect ( mockDeveloperPlatformClient . devStoresForOrg ) . toHaveBeenCalledWith ( mockOrganization . id )
104+ expect ( selectStore ) . toHaveBeenCalledWith (
105+ { stores : allStores , hasMorePages : false } ,
106+ mockOrganization ,
107+ mockDeveloperPlatformClient ,
108+ )
109+ expect ( result ) . toEqual ( mockStore )
86110 } )
87-
88- expect ( mockDeveloperPlatformClient . devStoresForOrg ) . toHaveBeenCalledWith ( mockOrganization . id )
89- expect ( selectStore ) . toHaveBeenCalledWith (
90- { stores : allStores , hasMorePages : false } ,
91- mockOrganization ,
92- mockDeveloperPlatformClient ,
93- )
94- expect ( result ) . toEqual ( mockStore )
95111 } )
96112
97113 test ( 'fetches and selects store when forceReselectStore is true' , async ( ) => {
98- const allStores = [ mockStore , { ...mockStore , shopId : 'store2' , shopDomain : 'another-store.myshopify.com' } ]
99-
100- vi . mocked ( mockDeveloperPlatformClient . devStoresForOrg ) . mockResolvedValue ( { stores : allStores , hasMorePages : false } )
101- vi . mocked ( selectStore ) . mockResolvedValue ( mockStore )
102-
103- const result = await storeContext ( {
104- appContextResult,
105- forceReselectStore : true ,
114+ await inTemporaryDirectory ( async ( dir ) => {
115+ const allStores = [ mockStore , { ...mockStore , shopId : 'store2' , shopDomain : 'another-store.myshopify.com' } ]
116+ await prepareAppFolder ( mockApp , dir )
117+ vi . mocked ( mockDeveloperPlatformClient . devStoresForOrg ) . mockResolvedValue ( { stores : allStores , hasMorePages : false } )
118+ vi . mocked ( selectStore ) . mockResolvedValue ( mockStore )
119+
120+ const result = await storeContext ( {
121+ appContextResult,
122+ forceReselectStore : true ,
123+ } )
124+
125+ expect ( mockDeveloperPlatformClient . devStoresForOrg ) . toHaveBeenCalledWith ( mockOrganization . id )
126+ expect ( selectStore ) . toHaveBeenCalledWith (
127+ { stores : allStores , hasMorePages : false } ,
128+ mockOrganization ,
129+ mockDeveloperPlatformClient ,
130+ )
131+ expect ( result ) . toEqual ( mockStore )
106132 } )
107-
108- expect ( mockDeveloperPlatformClient . devStoresForOrg ) . toHaveBeenCalledWith ( mockOrganization . id )
109- expect ( selectStore ) . toHaveBeenCalledWith (
110- { stores : allStores , hasMorePages : false } ,
111- mockOrganization ,
112- mockDeveloperPlatformClient ,
113- )
114- expect ( result ) . toEqual ( mockStore )
115133 } )
116134
117135 test ( 'throws an error when fetchStore fails' , async ( ) => {
@@ -133,25 +151,58 @@ describe('storeContext', () => {
133151 } )
134152
135153 test ( 'calls logMetadata' , async ( ) => {
136- // Given
137- vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
138-
139- // When
140- await storeContext ( { appContextResult, forceReselectStore : false } )
141-
142- // Then
143- const meta = metadata . getAllPublicMetadata ( )
144- expect ( meta ) . toEqual (
145- expect . objectContaining ( {
146- store_fqdn_hash : hashString ( mockStore . shopDomain ) ,
147- } ) ,
148- )
154+ await inTemporaryDirectory ( async ( dir ) => {
155+ vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
156+ await prepareAppFolder ( mockApp , dir )
157+
158+ // When
159+ await storeContext ( { appContextResult, forceReselectStore : false } )
160+
161+ // Then
162+ const meta = metadata . getAllPublicMetadata ( )
163+ expect ( meta ) . toEqual (
164+ expect . objectContaining ( {
165+ store_fqdn_hash : hashString ( mockStore . shopDomain ) ,
166+ } ) ,
167+ )
168+
169+ const sensitiveMeta = metadata . getAllSensitiveMetadata ( )
170+ expect ( sensitiveMeta ) . toEqual (
171+ expect . objectContaining ( {
172+ store_fqdn : mockStore . shopDomain ,
173+ } ) ,
174+ )
175+ } )
176+ } )
149177
150- const sensitiveMeta = metadata . getAllSensitiveMetadata ( )
151- expect ( sensitiveMeta ) . toEqual (
152- expect . objectContaining ( {
153- store_fqdn : mockStore . shopDomain ,
154- } ) ,
155- )
178+ test ( 'adds hidden config to gitignore if needed' , async ( ) => {
179+ await inTemporaryDirectory ( async ( dir ) => {
180+ await prepareAppFolder ( mockApp , dir )
181+ vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
182+
183+ await storeContext ( { appContextResult, forceReselectStore : false } )
184+
185+ const gitIgnoreContent = await readFile ( joinPath ( dir , '.gitignore' ) )
186+ expect ( gitIgnoreContent ) . toContain ( '.shopify' )
187+ } )
188+ } )
189+
190+ test ( 'updates hidden config' , async ( ) => {
191+ await inTemporaryDirectory ( async ( dir ) => {
192+ await prepareAppFolder ( mockApp , dir )
193+ vi . mocked ( fetchStore ) . mockResolvedValue ( mockStore )
194+
195+ await storeContext ( { appContextResult, forceReselectStore : false } )
196+
197+ const hiddenConfig = await readFile ( appHiddenConfigPath ( dir ) )
198+ expect ( hiddenConfig ) . toEqual ( '{\n "dev_store_url": "test-store.myshopify.com"\n}' )
199+ } )
156200 } )
157201} )
202+
203+ async function prepareAppFolder ( app : AppLinkedInterface , directory : string ) {
204+ app . directory = directory
205+ await mkdir ( joinPath ( directory , '.shopify' ) )
206+ await writeFile ( joinPath ( directory , '.shopify' , 'project.json' ) , '' )
207+ await writeFile ( joinPath ( directory , '.gitignore' ) , '' )
208+ }
0 commit comments