import {renderHook} from '@testing-library/react' import {describe, expect, it, vi, beforeEach} from 'vitest' import {useShopIntent} from '../../internal/useShopIntent' import {useSelectVariant} from './useSelectVariant' vi.mock('../../internal/useShopIntent', () => ({ useShopIntent: vi.fn(), })) const mockUseShopIntent = useShopIntent as unknown as ReturnType const PRODUCT_ID = 'gid://shopify/Product/123' const VARIANT_ID = 'gid://shopify/ProductVariant/456' const VARIANT = { id: VARIANT_ID, title: 'Red / S', isFavorited: false, availableForSale: true, selectedOptions: [ {name: 'Color', value: 'Red'}, {name: 'Size', value: 'S'}, ], image: {url: 'https://cdn/v.jpg'}, price: {amount: '10.00', currencyCode: 'USD'}, compareAtPrice: null, } describe('useSelectVariant', () => { beforeEach(() => { vi.clearAllMocks() }) it('invokes the select:shopify/ProductVariant intent with productId in data', async () => { const invokeQuery = vi.fn().mockResolvedValue({ code: 'ok', data: { outcome: 'selected', productVariantId: VARIANT_ID, variant: VARIANT, quantity: 1, source: 'auto', }, }) mockUseShopIntent.mockReturnValue({invokeQuery}) const {result} = renderHook(() => useSelectVariant()) await result.current.selectVariant({productId: PRODUCT_ID}) expect(invokeQuery).toHaveBeenCalledWith({ action: 'select', type: 'shopify/ProductVariant', data: {productId: PRODUCT_ID}, }) }) it('passes optional params through as the intent data payload', async () => { const invokeQuery = vi.fn().mockResolvedValue({code: 'closed'}) mockUseShopIntent.mockReturnValue({invokeQuery}) const {result} = renderHook(() => useSelectVariant()) await result.current.selectVariant({ productId: PRODUCT_ID, initialVariantId: VARIANT_ID, includedProductVariantGIDs: [VARIANT_ID], initialQuantity: 3, maxQuantity: 10, showQuantity: false, forceShow: true, }) expect(invokeQuery).toHaveBeenCalledWith({ action: 'select', type: 'shopify/ProductVariant', data: { productId: PRODUCT_ID, initialVariantId: VARIANT_ID, includedProductVariantGIDs: [VARIANT_ID], initialQuantity: 3, maxQuantity: 10, showQuantity: false, forceShow: true, }, }) }) it('returns the ok IntentResult with typed data on success', async () => { const invokeQuery = vi.fn().mockResolvedValue({ code: 'ok', data: { outcome: 'selected', productVariantId: VARIANT_ID, variant: VARIANT, quantity: 2, source: 'user', }, }) mockUseShopIntent.mockReturnValue({invokeQuery}) const {result} = renderHook(() => useSelectVariant()) const response = await result.current.selectVariant({productId: PRODUCT_ID}) expect(response).toEqual({ code: 'ok', data: { outcome: 'selected', productVariantId: VARIANT_ID, variant: VARIANT, quantity: 2, source: 'user', }, }) }) it('returns closed when the user dismisses the sheet', async () => { const invokeQuery = vi.fn().mockResolvedValue({code: 'closed'}) mockUseShopIntent.mockReturnValue({invokeQuery}) const {result} = renderHook(() => useSelectVariant()) const response = await result.current.selectVariant({productId: PRODUCT_ID}) expect(response).toEqual({code: 'closed'}) }) it('returns the error IntentResult when the host fails', async () => { const invokeQuery = vi.fn().mockResolvedValue({ code: 'error', message: 'host blew up', }) mockUseShopIntent.mockReturnValue({invokeQuery}) const {result} = renderHook(() => useSelectVariant()) const response = await result.current.selectVariant({productId: PRODUCT_ID}) expect(response).toEqual({code: 'error', message: 'host blew up'}) }) })