Skip to content

Commit 9bca83a

Browse files
committed
cleanup and update unit tests
1 parent 16958ae commit 9bca83a

File tree

8 files changed

+123
-87
lines changed

8 files changed

+123
-87
lines changed

packages/template-retail-react-app/app/components/product-view/index.jsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ const ProductView = forwardRef(
119119
!isProductLoading && variant?.orderable && quantity > 0 && quantity <= stockLevel,
120120
showImageGallery = true,
121121
setSelectedBundleQuantity = () => {},
122-
selectedBundleParentQuantity = 1,
123-
selectedStore
122+
selectedBundleParentQuantity = 1
124123
},
125124
ref
126125
) => {
@@ -600,10 +599,7 @@ const ProductView = forwardRef(
600599
/>
601600
</VStack>
602601
)}
603-
<StoreAvailabilityText
604-
selectedStore={selectedStore}
605-
productInventories={product?.inventories}
606-
/>
602+
<StoreAvailabilityText productInventories={product?.inventories} />
607603
<Box ref={errorContainerRef}>
608604
{!showLoading && showOptionsMessage && (
609605
<Fade in={true}>
@@ -704,8 +700,7 @@ ProductView.propTypes = {
704700
validateOrderability: PropTypes.func,
705701
showImageGallery: PropTypes.bool,
706702
setSelectedBundleQuantity: PropTypes.func,
707-
selectedBundleParentQuantity: PropTypes.number,
708-
selectedStore: PropTypes.object
703+
selectedBundleParentQuantity: PropTypes.number
709704
}
710705

711706
export default ProductView

packages/template-retail-react-app/app/components/store-availability-text/index.jsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44
* SPDX-License-Identifier: BSD-3-Clause
55
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
66
*/
7-
import React from 'react'
7+
import React, {useContext} from 'react'
88
import PropTypes from 'prop-types'
99
import {FormattedMessage} from 'react-intl'
1010

1111
// Components
1212
import {Box, Link} from '@salesforce/retail-react-app/app/components/shared/ui'
1313

14-
const StoreAvailabilityText = ({selectedStore, productInventories}) => {
14+
// Others
15+
import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal'
16+
17+
const StoreAvailabilityText = ({productInventories}) => {
18+
const {selectedStore} = useContext(StoreLocatorContext)
1519
const inStock = productInventories?.find(
1620
(inventory) => inventory.id === selectedStore.inventoryId && inventory.orderable
1721
)
@@ -44,7 +48,6 @@ const StoreAvailabilityText = ({selectedStore, productInventories}) => {
4448
}
4549

4650
StoreAvailabilityText.propTypes = {
47-
selectedStore: PropTypes.object,
4851
productInventories: PropTypes.arrayOf(PropTypes.object)
4952
}
5053

packages/template-retail-react-app/app/components/store-availability-text/index.test.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {screen} from '@testing-library/react'
99

1010
import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
1111
import StoreAvailabilityText from '@salesforce/retail-react-app/app/components/store-availability-text'
12+
import {StoreLocatorContext} from '@salesforce/retail-react-app/app/components/store-locator-modal'
1213

1314
const selectedStore = {
1415
name: 'Test Store',
@@ -18,48 +19,64 @@ const selectedStore = {
1819

1920
describe('Store Name Rendering', () => {
2021
test('renders "Select Store" if selectedStore does not contain a name field', () => {
21-
renderWithProviders(<StoreAvailabilityText selectedStore={{}} />)
22+
renderWithProviders(
23+
<StoreLocatorContext.Provider value={{selectedStore: {}}}>
24+
<StoreAvailabilityText />
25+
</StoreLocatorContext.Provider>
26+
)
2227
expect(screen.getByText(/Select Store/i)).toBeInTheDocument()
2328
})
2429

2530
test('renders store name if selectedStore contains a name field', () => {
26-
renderWithProviders(<StoreAvailabilityText selectedStore={selectedStore} />)
31+
renderWithProviders(
32+
<StoreLocatorContext.Provider value={{selectedStore}}>
33+
<StoreAvailabilityText />
34+
</StoreLocatorContext.Provider>
35+
)
2736
expect(screen.getByText(selectedStore.name)).toBeInTheDocument()
2837
})
2938
})
3039

3140
describe('Stock Availability Rendering', () => {
3241
test('renders "In Stock" when productInventories is undefined', () => {
33-
renderWithProviders(<StoreAvailabilityText selectedStore={selectedStore} />)
42+
renderWithProviders(
43+
<StoreLocatorContext.Provider value={{selectedStore}}>
44+
<StoreAvailabilityText />
45+
</StoreLocatorContext.Provider>
46+
)
3447
expect(screen.getByText(/In Stock at/i)).toBeInTheDocument()
3548
})
49+
test
3650

3751
test('renders "In Stock" if orderable is true', () => {
3852
renderWithProviders(
39-
<StoreAvailabilityText
40-
selectedStore={selectedStore}
41-
productInventories={[{id: 'inventory_1', orderable: true}]}
42-
/>
53+
<StoreLocatorContext.Provider value={{selectedStore}}>
54+
<StoreAvailabilityText
55+
productInventories={[{id: 'inventory_1', orderable: true}]}
56+
/>
57+
</StoreLocatorContext.Provider>
4358
)
4459
expect(screen.getByText(/In Stock at/i)).toBeInTheDocument()
4560
})
4661

4762
test('renders "Out of Stock" if orderable is false', () => {
4863
renderWithProviders(
49-
<StoreAvailabilityText
50-
selectedStore={selectedStore}
51-
productInventories={[{id: 'inventory_1', orderable: false}]}
52-
/>
64+
<StoreLocatorContext.Provider value={{selectedStore}}>
65+
<StoreAvailabilityText
66+
productInventories={[{id: 'inventory_1', orderable: false}]}
67+
/>
68+
</StoreLocatorContext.Provider>
5369
)
5470
expect(screen.getByText(/Out of Stock at/i)).toBeInTheDocument()
5571
})
5672

5773
test('renders "Out of Stock" if selectedStore inventoryId is not in productInventories', () => {
5874
renderWithProviders(
59-
<StoreAvailabilityText
60-
selectedStore={selectedStore}
61-
productInventories={[{id: 'inventory_99', orderable: true}]}
62-
/>
75+
<StoreLocatorContext.Provider value={{selectedStore}}>
76+
<StoreAvailabilityText
77+
productInventories={[{id: 'inventory_99', orderable: true}]}
78+
/>
79+
</StoreLocatorContext.Provider>
6380
)
6481
expect(screen.getByText(/Out of Stock at/i)).toBeInTheDocument()
6582
})

packages/template-retail-react-app/app/components/store-locator-modal/index.test.jsx

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@
66
*/
77

88
import React from 'react'
9-
import StoreLocatorModal from '@salesforce/retail-react-app/app/components/store-locator-modal/index'
9+
import PropTypes from 'prop-types'
10+
import StoreLocatorModal, {
11+
useStoreLocator
12+
} from '@salesforce/retail-react-app/app/components/store-locator-modal/index'
1013
import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils'
14+
import {act, fireEvent, screen} from '@testing-library/react'
1115
import {rest} from 'msw'
16+
import mockConfig from '@salesforce/retail-react-app/config/mocks/default'
1217

1318
const mockStoresData = [
1419
{
@@ -199,14 +204,82 @@ const mockStores = {
199204
}
200205

201206
describe('StoreLocatorModal', () => {
202-
test('renders without crashing', () => {
207+
beforeEach(() => {
203208
global.server.use(
204209
rest.get('*/shopper-stores/v1/organizations/*', (req, res, ctx) => {
205210
return res(ctx.delay(0), ctx.status(200), ctx.json(mockStores))
206211
})
207212
)
208-
expect(() => {
209-
renderWithProviders(<StoreLocatorModal />)
210-
}).not.toThrow()
213+
})
214+
215+
test('does not render when isOpen is false', () => {
216+
renderWithProviders(<StoreLocatorModal isOpen={false} />)
217+
expect(screen.queryByText(/Find a Store/i)).not.toBeInTheDocument()
218+
})
219+
220+
test('renders when isOpen is true', async () => {
221+
renderWithProviders(<StoreLocatorModal isOpen={true} />)
222+
expect(screen.getByText(/Find a Store/i)).toBeInTheDocument()
223+
224+
await act(async () => {
225+
// Select the country
226+
const countrySelect = screen.getByRole('combobox')
227+
fireEvent.change(countrySelect, {target: {value: 'US'}})
228+
229+
// Enter a postal code
230+
const postalCodeInput = screen.getByPlaceholderText(/enter postal code/i)
231+
fireEvent.change(postalCodeInput, {target: {value: '12345'}})
232+
233+
// Click the "Find" button
234+
const findButton = screen.getByRole('button', {name: /find/i})
235+
fireEvent.click(findButton)
236+
})
237+
238+
mockStoresData.forEach((store) => {
239+
expect(screen.getByText(store.name)).toBeInTheDocument()
240+
expect(screen.getByText(store.address1)).toBeInTheDocument()
241+
})
242+
})
243+
})
244+
245+
describe('useStoreLocator', () => {
246+
const MockComponent = ({store} = {}) => {
247+
const {selectedStore, setStore, isStoreSelected} = useStoreLocator()
248+
249+
return (
250+
<>
251+
<div data-testid="selected-store">{JSON.stringify(selectedStore)}</div>
252+
<div data-testid="is-store-selected">{isStoreSelected.toString()}</div>
253+
<button data-testid="set-store" onClick={() => setStore(store)} />
254+
</>
255+
)
256+
}
257+
MockComponent.propTypes = {
258+
store: PropTypes.object
259+
}
260+
261+
test('no store selected', () => {
262+
renderWithProviders(<MockComponent />)
263+
expect(screen.getByTestId('selected-store')).toHaveTextContent(/{}/i)
264+
expect(screen.getByTestId('is-store-selected')).toHaveTextContent(/false/i)
265+
})
266+
267+
test('store selected', () => {
268+
const store = {
269+
id: 'test-store',
270+
name: 'Test Store',
271+
inventoryId: 'inventory'
272+
}
273+
274+
const expectedStoreData = JSON.stringify(store)
275+
276+
renderWithProviders(<MockComponent store={store} />)
277+
fireEvent.click(screen.getByTestId('set-store'))
278+
279+
expect(screen.getByTestId('selected-store')).toHaveTextContent(expectedStoreData)
280+
expect(screen.getByTestId('is-store-selected')).toHaveTextContent(/true/i)
281+
expect(localStorage.getItem(`store_${mockConfig.app.defaultSite}`)).toEqual(
282+
expectedStoreData
283+
)
211284
})
212285
})

packages/template-retail-react-app/app/hooks/use-select-store.test.js

Lines changed: 0 additions & 51 deletions
This file was deleted.

packages/template-retail-react-app/app/pages/product-detail/index.jsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,6 @@ const ProductDetail = () => {
479479
validateOrderability={handleChildProductValidation}
480480
childProductOrderability={childProductOrderability}
481481
setSelectedBundleQuantity={setSelectedBundleQuantity}
482-
selectedStore={selectedStore}
483482
/>
484483

485484
<hr />
@@ -505,7 +504,6 @@ const ProductDetail = () => {
505504
isProductPartOfBundle={isProductABundle}
506505
childOfBundleQuantity={childQuantity}
507506
selectedBundleParentQuantity={selectedBundleQuantity}
508-
selectedStore={selectedStore}
509507
addToCart={
510508
isProductASet
511509
? (variant, quantity) =>
@@ -568,7 +566,6 @@ const ProductDetail = () => {
568566
isProductLoading={isProductLoading}
569567
isBasketLoading={isBasketLoading}
570568
isWishlistLoading={isWishlistLoading}
571-
selectedStore={selectedStore}
572569
/>
573570
<InformationAccordion product={product} />
574571
</Fragment>

packages/template-retail-react-app/app/pages/store-locator/index.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import Seo from '@salesforce/retail-react-app/app/components/seo'
1313
import StoreLocatorContent from '@salesforce/retail-react-app/app/components/store-locator-modal/store-locator-content'
1414

1515
const StoreLocator = () => {
16-
1716
return (
1817
<Box data-testid="store-locator-page" bg="gray.50" py={[8, 16]}>
1918
<Seo title="Store Locator" description="Find a Store" />

packages/template-retail-react-app/app/utils/test-utils.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import fallbackMessages from '@salesforce/retail-react-app/app/static/translatio
2121
import mockConfig from '@salesforce/retail-react-app/config/mocks/default'
2222
// Contexts
2323
import {CurrencyProvider, MultiSiteProvider} from '@salesforce/retail-react-app/app/contexts'
24+
import {StoreLocatorProvider} from '@salesforce/retail-react-app/app/components/store-locator-modal'
2425

2526
import {createUrlTemplate} from '@salesforce/retail-react-app/app/utils/url'
2627
import {getSiteByReference} from '@salesforce/retail-react-app/app/utils/site-utils'
@@ -137,7 +138,9 @@ export const TestProviders = ({
137138
<CurrencyProvider currency={DEFAULT_CURRENCY}>
138139
<Router>
139140
<ChakraProvider theme={theme}>
140-
<AddToCartModalProvider>{children}</AddToCartModalProvider>
141+
<AddToCartModalProvider>
142+
<StoreLocatorProvider>{children}</StoreLocatorProvider>
143+
</AddToCartModalProvider>
141144
</ChakraProvider>
142145
</Router>
143146
</CurrencyProvider>

0 commit comments

Comments
 (0)