diff --git a/packages/template-retail-react-app/app/hooks/use-derived-product.test.js b/packages/template-retail-react-app/app/hooks/use-derived-product.test.js index 8feeddbd9a..012fd41db2 100644 --- a/packages/template-retail-react-app/app/hooks/use-derived-product.test.js +++ b/packages/template-retail-react-app/app/hooks/use-derived-product.test.js @@ -9,10 +9,15 @@ import React from 'react' import PropTypes from 'prop-types' import {screen} from '@testing-library/react' -import {createMemoryHistory} from 'history' import {useDerivedProduct} from '@salesforce/retail-react-app/app/hooks/use-derived-product' import mockProductDetail from '@salesforce/retail-react-app/app/mocks/variant-750518699578M' import {renderWithProviders} from '@salesforce/retail-react-app/app/utils/test-utils' +import {useVariant} from '@salesforce/retail-react-app/app/hooks/use-variant' + +// Mock the useVariant hook +jest.mock('@salesforce/retail-react-app/app/hooks/use-variant', () => ({ + useVariant: jest.fn() +})) const MockComponent = ({product}) => { const {inventoryMessage, quantity, variationParams, variant} = useDerivedProduct(product) @@ -32,9 +37,19 @@ MockComponent.propTypes = { } describe('useDerivedProduct hook', () => { - test('runs properly', () => { - const history = createMemoryHistory() - history.push('/test/path?test') + beforeEach(() => { + // Reset mock before each test + jest.clearAllMocks() + }) + + test('should not show out of stock message when stockLevel is greater then 0 and greater then asked quantity', () => { + // Mock useVariant to return a valid variant + useVariant.mockReturnValue({ + orderable: true, + price: 299.99, + productId: '750518699578M', + variationValues: {color: 'BLACKFB', size: '038', width: 'V'} + }) renderWithProviders() @@ -46,9 +61,14 @@ describe('useDerivedProduct hook', () => { ).toBeInTheDocument() }) - test('has out of stock message', () => { - const history = createMemoryHistory() - history.push('/test/path') + test('should show out of stock message when stockLevel is 0', () => { + // Mock useVariant to return a valid variant + useVariant.mockReturnValue({ + orderable: true, + price: 299.99, + productId: '750518699578M', + variationValues: {color: 'BLACKFB', size: '038', width: 'V'} + }) const mockData = { ...mockProductDetail, @@ -66,4 +86,81 @@ describe('useDerivedProduct hook', () => { expect(screen.getByText(/Out of stock/)).toBeInTheDocument() }) + + test('should show unfulfillable messsage when stockLevel is less then asked quantity', () => { + // Mock useVariant to return a valid variant + useVariant.mockReturnValue({ + orderable: true, + price: 299.99, + productId: '750518699578M', + variationValues: {color: 'BLACKFB', size: '038', width: 'V'} + }) + + const mockData = { + ...mockProductDetail, + quantity: 10, + inventory: { + ats: 0, + backorderable: false, + id: 'inventory_m', + orderable: false, + preorderable: false, + stockLevel: 5 + } + } + + renderWithProviders() + + expect(screen.getByText(/Only 5 left!/)).toBeInTheDocument() + }) + + test('should show of stock message for bundle products', () => { + // Mock useVariant to return null for bundle products (bundles don't have variants) + useVariant.mockReturnValue(null) + + const mockBundleData = { + ...mockProductDetail, + type: { + bundle: true + }, + inventory: { + ats: 10, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 10 + } + } + + renderWithProviders() + + // Bundle products should not show out of stock message when inventory is available + expect(screen.queryByText(/Out of stock/)).not.toBeInTheDocument() + }) + + test('should show unfulfillable message for bundle products', () => { + // Mock useVariant to return null for bundle products (bundles don't have variants) + useVariant.mockReturnValue(null) + + const mockBundleData = { + ...mockProductDetail, + type: { + bundle: true + }, + quantity: 15, + inventory: { + ats: 5, + backorderable: false, + id: 'inventory_m', + orderable: true, + preorderable: false, + stockLevel: 5 + } + } + + renderWithProviders() + + expect(screen.getByText(/Only 5 left!/)).toBeInTheDocument() + }) })