@shopify/shop-minis-react 0.3.4 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/dist/_virtual/index3.js +2 -5
  2. package/dist/_virtual/index3.js.map +1 -1
  3. package/dist/_virtual/index4.js +5 -2
  4. package/dist/_virtual/index4.js.map +1 -1
  5. package/dist/components/MinisContainer.js +11 -10
  6. package/dist/components/MinisContainer.js.map +1 -1
  7. package/dist/hooks/content/useContent.js +12 -18
  8. package/dist/hooks/content/useContent.js.map +1 -1
  9. package/dist/hooks/product/useCuratedProducts.js +9 -11
  10. package/dist/hooks/product/useCuratedProducts.js.map +1 -1
  11. package/dist/hooks/product/usePopularProducts.js +9 -11
  12. package/dist/hooks/product/usePopularProducts.js.map +1 -1
  13. package/dist/hooks/product/useProduct.js +11 -17
  14. package/dist/hooks/product/useProduct.js.map +1 -1
  15. package/dist/hooks/product/useProductList.js +10 -21
  16. package/dist/hooks/product/useProductList.js.map +1 -1
  17. package/dist/hooks/product/useProductLists.js +11 -13
  18. package/dist/hooks/product/useProductLists.js.map +1 -1
  19. package/dist/hooks/product/useProductMedia.js +12 -18
  20. package/dist/hooks/product/useProductMedia.js.map +1 -1
  21. package/dist/hooks/product/useProductSearch.js +34 -27
  22. package/dist/hooks/product/useProductSearch.js.map +1 -1
  23. package/dist/hooks/product/useProductVariants.js +11 -14
  24. package/dist/hooks/product/useProductVariants.js.map +1 -1
  25. package/dist/hooks/product/useProducts.js +12 -11
  26. package/dist/hooks/product/useProducts.js.map +1 -1
  27. package/dist/hooks/product/useRecommendedProducts.js +11 -13
  28. package/dist/hooks/product/useRecommendedProducts.js.map +1 -1
  29. package/dist/hooks/shop/useRecommendedShops.js +11 -13
  30. package/dist/hooks/shop/useRecommendedShops.js.map +1 -1
  31. package/dist/hooks/shop/useShop.js +12 -11
  32. package/dist/hooks/shop/useShop.js.map +1 -1
  33. package/dist/hooks/user/useBuyerAttributes.js +8 -10
  34. package/dist/hooks/user/useBuyerAttributes.js.map +1 -1
  35. package/dist/hooks/user/useCurrentUser.js +7 -9
  36. package/dist/hooks/user/useCurrentUser.js.map +1 -1
  37. package/dist/hooks/user/useFollowedShops.js +11 -14
  38. package/dist/hooks/user/useFollowedShops.js.map +1 -1
  39. package/dist/hooks/user/useOrders.js +7 -9
  40. package/dist/hooks/user/useOrders.js.map +1 -1
  41. package/dist/hooks/user/useRecentProducts.js +11 -13
  42. package/dist/hooks/user/useRecentProducts.js.map +1 -1
  43. package/dist/hooks/user/useRecentShops.js +10 -13
  44. package/dist/hooks/user/useRecentShops.js.map +1 -1
  45. package/dist/hooks/user/useSavedProducts.js +10 -13
  46. package/dist/hooks/user/useSavedProducts.js.map +1 -1
  47. package/dist/hooks/util/useImagePicker.js +13 -6
  48. package/dist/hooks/util/useImagePicker.js.map +1 -1
  49. package/dist/internal/reactQuery/MinisQueryProvider.js +11 -0
  50. package/dist/internal/reactQuery/MinisQueryProvider.js.map +1 -0
  51. package/dist/internal/reactQuery/queryClient.js +33 -0
  52. package/dist/internal/reactQuery/queryClient.js.map +1 -0
  53. package/dist/internal/reactQuery/useShopActionInfiniteQuery.js +52 -0
  54. package/dist/internal/reactQuery/useShopActionInfiniteQuery.js.map +1 -0
  55. package/dist/internal/reactQuery/useShopActionQuery.js +37 -0
  56. package/dist/internal/reactQuery/useShopActionQuery.js.map +1 -0
  57. package/dist/internal/utils/resizeImage.js +61 -0
  58. package/dist/internal/utils/resizeImage.js.map +1 -0
  59. package/dist/providers/ImagePickerProvider.js +123 -102
  60. package/dist/providers/ImagePickerProvider.js.map +1 -1
  61. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js +45 -0
  62. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/focusManager.js.map +1 -0
  63. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js +89 -0
  64. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryBehavior.js.map +1 -0
  65. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js +55 -0
  66. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/infiniteQueryObserver.js.map +1 -0
  67. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutation.js +198 -0
  68. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutation.js.map +1 -0
  69. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutationCache.js +99 -0
  70. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/mutationCache.js.map +1 -0
  71. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/notifyManager.js +67 -0
  72. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/notifyManager.js.map +1 -0
  73. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/onlineManager.js +39 -0
  74. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/onlineManager.js.map +1 -0
  75. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/query.js +299 -0
  76. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/query.js.map +1 -0
  77. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryCache.js +80 -0
  78. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryCache.js.map +1 -0
  79. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryClient.js +215 -0
  80. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryClient.js.map +1 -0
  81. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryObserver.js +300 -0
  82. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/queryObserver.js.map +1 -0
  83. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/removable.js +25 -0
  84. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/removable.js.map +1 -0
  85. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/retryer.js +76 -0
  86. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/retryer.js.map +1 -0
  87. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/subscribable.js +21 -0
  88. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/subscribable.js.map +1 -0
  89. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/thenable.js +26 -0
  90. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/thenable.js.map +1 -0
  91. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/utils.js +176 -0
  92. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_query-core@5.86.0/node_modules/@tanstack/query-core/build/modern/utils.js.map +1 -0
  93. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/IsRestoringProvider.js +7 -0
  94. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/IsRestoringProvider.js.map +1 -0
  95. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js +17 -0
  96. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryClientProvider.js.map +1 -0
  97. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryErrorResetBoundary.js +19 -0
  98. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/QueryErrorResetBoundary.js.map +1 -0
  99. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js +21 -0
  100. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/errorBoundaryUtils.js.map +1 -0
  101. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/suspense.js +18 -0
  102. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/suspense.js.map +1 -0
  103. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js +64 -0
  104. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useBaseQuery.js.map +1 -0
  105. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js +13 -0
  106. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useInfiniteQuery.js.map +1 -0
  107. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useQuery.js +9 -0
  108. package/dist/shop-minis-react/node_modules/.pnpm/@tanstack_react-query@5.86.0_react@19.1.0/node_modules/@tanstack/react-query/build/modern/useQuery.js.map +1 -0
  109. package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
  110. package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
  111. package/package.json +2 -7
  112. package/src/components/MinisContainer.tsx +6 -3
  113. package/src/hooks/content/useContent.ts +6 -17
  114. package/src/hooks/product/useCuratedProducts.ts +4 -6
  115. package/src/hooks/product/usePopularProducts.ts +4 -6
  116. package/src/hooks/product/useProduct.ts +6 -17
  117. package/src/hooks/product/useProductList.ts +4 -19
  118. package/src/hooks/product/useProductLists.ts +4 -6
  119. package/src/hooks/product/useProductMedia.ts +6 -17
  120. package/src/hooks/product/useProductSearch.ts +19 -15
  121. package/src/hooks/product/useProductVariants.ts +5 -13
  122. package/src/hooks/product/useProducts.ts +8 -12
  123. package/src/hooks/product/useRecommendedProducts.ts +4 -6
  124. package/src/hooks/shop/useRecommendedShops.ts +4 -6
  125. package/src/hooks/shop/useShop.ts +8 -12
  126. package/src/hooks/user/useBuyerAttributes.ts +4 -6
  127. package/src/hooks/user/useCurrentUser.ts +4 -6
  128. package/src/hooks/user/useFollowedShops.ts +5 -13
  129. package/src/hooks/user/useOrders.ts +4 -6
  130. package/src/hooks/user/useRecentProducts.ts +4 -6
  131. package/src/hooks/user/useRecentShops.ts +5 -13
  132. package/src/hooks/user/useSavedProducts.ts +5 -13
  133. package/src/hooks/util/useImagePicker.test.tsx +193 -0
  134. package/src/hooks/util/useImagePicker.ts +24 -5
  135. package/src/internal/reactQuery/MinisQueryProvider.test.tsx +38 -0
  136. package/src/internal/reactQuery/MinisQueryProvider.tsx +16 -0
  137. package/src/internal/reactQuery/index.ts +8 -0
  138. package/src/internal/reactQuery/queryClient.test.tsx +91 -0
  139. package/src/internal/reactQuery/queryClient.ts +43 -0
  140. package/src/internal/reactQuery/useShopActionInfiniteQuery.test.tsx +357 -0
  141. package/src/internal/reactQuery/useShopActionInfiniteQuery.ts +129 -0
  142. package/src/internal/reactQuery/useShopActionQuery.test.tsx +184 -0
  143. package/src/internal/reactQuery/useShopActionQuery.ts +74 -0
  144. package/src/internal/utils/resizeImage.test.ts +314 -0
  145. package/src/internal/utils/resizeImage.ts +108 -0
  146. package/src/providers/ImagePickerProvider.test.tsx +32 -1
  147. package/src/providers/ImagePickerProvider.tsx +108 -65
  148. package/dist/internal/useShopActionsDataFetching.js +0 -79
  149. package/dist/internal/useShopActionsDataFetching.js.map +0 -1
  150. package/dist/internal/useShopActionsPaginatedDataFetching.js +0 -96
  151. package/dist/internal/useShopActionsPaginatedDataFetching.js.map +0 -1
  152. package/src/hooks/product/useProductSearch.test.ts +0 -470
  153. package/src/internal/useShopActionsDataFetching.test.ts +0 -465
  154. package/src/internal/useShopActionsDataFetching.ts +0 -150
  155. package/src/internal/useShopActionsPaginatedDataFetching.ts +0 -188
  156. package/src/stories/Accordion.stories.tsx +0 -124
  157. package/src/stories/AddToCart.stories.tsx +0 -251
  158. package/src/stories/Alert.stories.tsx +0 -38
  159. package/src/stories/AlertDialog.stories.tsx +0 -48
  160. package/src/stories/Avatar.stories.tsx +0 -29
  161. package/src/stories/Badge.stories.tsx +0 -46
  162. package/src/stories/Button.stories.tsx +0 -81
  163. package/src/stories/Card.stories.tsx +0 -40
  164. package/src/stories/Checkbox.stories.tsx +0 -44
  165. package/src/stories/FavoriteButton.stories.tsx +0 -58
  166. package/src/stories/IconButton.stories.tsx +0 -68
  167. package/src/stories/ImageContentWrapper.stories.tsx +0 -65
  168. package/src/stories/Input.stories.tsx +0 -44
  169. package/src/stories/Label.stories.tsx +0 -19
  170. package/src/stories/List.stories.tsx +0 -64
  171. package/src/stories/MerchantCard.stories.tsx +0 -127
  172. package/src/stories/ProductCard.stories.tsx +0 -92
  173. package/src/stories/ProductLink.stories.tsx +0 -46
  174. package/src/stories/ProductVariantPrice.stories.tsx +0 -70
  175. package/src/stories/Progress.stories.tsx +0 -30
  176. package/src/stories/PullToRefreshList.stories.tsx +0 -122
  177. package/src/stories/QuantitySelector.stories.tsx +0 -78
  178. package/src/stories/RadioGroup.stories.tsx +0 -51
  179. package/src/stories/Search.stories.tsx +0 -37
  180. package/src/stories/Select.stories.tsx +0 -85
  181. package/src/stories/Skeleton.stories.tsx +0 -19
  182. package/src/stories/TextInput.stories.tsx +0 -26
  183. package/src/stories/Toaster.stories.tsx +0 -46
  184. package/src/stories/Touchable.stories.tsx +0 -40
  185. package/src/stories/VideoPlayer.stories.tsx +0 -129
@@ -1,470 +0,0 @@
1
- import {renderHook, act, waitFor} from '@testing-library/react'
2
- import {describe, expect, it, vi, beforeEach} from 'vitest'
3
-
4
- import {useShopActions} from '../../internal/useShopActions'
5
- import {useShopActionsPaginatedDataFetching} from '../../internal/useShopActionsPaginatedDataFetching'
6
- import {mockProducts} from '../../test-utils'
7
-
8
- import {useProductSearch} from './useProductSearch'
9
-
10
- // Mock lodash debounce to make tests predictable
11
- vi.mock('lodash/debounce', () => ({
12
- default: (fn: any) => {
13
- const debounced = (...args: any[]) => fn(...args)
14
- debounced.cancel = vi.fn()
15
- return debounced
16
- },
17
- }))
18
-
19
- // Mock dependencies
20
- vi.mock('../../internal/useShopActions', () => ({
21
- useShopActions: vi.fn(() => ({
22
- getProductSearch: vi.fn(),
23
- })),
24
- }))
25
-
26
- vi.mock('../../internal/useShopActionsPaginatedDataFetching', () => ({
27
- useShopActionsPaginatedDataFetching: vi.fn(),
28
- }))
29
-
30
- describe('useProductSearch', () => {
31
- let mockGetProductSearch: ReturnType<typeof vi.fn>
32
- let mockPaginatedDataFetching: any
33
-
34
- beforeEach(() => {
35
- vi.clearAllMocks()
36
-
37
- mockGetProductSearch = vi.fn()
38
-
39
- // Default mock for paginated data fetching
40
- mockPaginatedDataFetching = {
41
- data: mockProducts(3),
42
- loading: false,
43
- error: null,
44
- hasNextPage: false,
45
- fetchMore: vi.fn(),
46
- refetch: vi.fn(),
47
- }
48
- ;(useShopActions as any).mockReturnValue({
49
- getProductSearch: mockGetProductSearch,
50
- })
51
- ;(useShopActionsPaginatedDataFetching as any).mockReturnValue(
52
- mockPaginatedDataFetching
53
- )
54
- })
55
-
56
- describe('Basic Search', () => {
57
- it('returns products when query is provided', () => {
58
- const {result} = renderHook(() =>
59
- useProductSearch({
60
- query: 'test query',
61
- })
62
- )
63
-
64
- expect(result.current.products).toEqual(mockProducts(3))
65
- expect(result.current.loading).toBe(false)
66
- expect(result.current.error).toBe(null)
67
- })
68
-
69
- it('returns null products when query is empty', () => {
70
- const {result} = renderHook(() =>
71
- useProductSearch({
72
- query: '',
73
- })
74
- )
75
-
76
- expect(result.current.products).toBe(null)
77
- })
78
-
79
- it('returns null products when query contains only whitespace', () => {
80
- const {result} = renderHook(() =>
81
- useProductSearch({
82
- query: ' ',
83
- })
84
- )
85
-
86
- expect(result.current.products).toBe(null)
87
- })
88
-
89
- it('passes search parameters correctly', () => {
90
- renderHook(() =>
91
- useProductSearch({
92
- query: 'test',
93
- filters: {} as any, // Empty filters object for testing
94
- sortBy: 'RELEVANCE' as any,
95
- includeSensitive: true,
96
- })
97
- )
98
-
99
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
100
- mockGetProductSearch,
101
- expect.objectContaining({
102
- query: 'test',
103
- filters: {},
104
- sortBy: 'RELEVANCE',
105
- includeSensitive: true,
106
- }),
107
- expect.objectContaining({
108
- skip: false,
109
- hook: 'useProductSearch',
110
- })
111
- )
112
- })
113
-
114
- it('handles skip parameter', () => {
115
- renderHook(() =>
116
- useProductSearch({
117
- query: 'test',
118
- skip: true,
119
- })
120
- )
121
-
122
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
123
- expect.any(Function),
124
- expect.any(Object),
125
- expect.objectContaining({
126
- skip: true,
127
- })
128
- )
129
- })
130
- })
131
-
132
- describe('Debouncing', () => {
133
- it('debounces query changes', async () => {
134
- // Create a custom mock for debounce that we can control
135
- let debouncedCallback: any = null
136
- const mockDebounce = vi.fn((fn: any, _delay: number) => {
137
- const debounced = (...args: any[]) => {
138
- debouncedCallback = () => fn(...args)
139
- }
140
- debounced.cancel = vi.fn()
141
- return debounced
142
- })
143
-
144
- // Mock lodash/debounce with our custom implementation
145
- vi.doMock('lodash/debounce', () => ({
146
- default: mockDebounce,
147
- }))
148
-
149
- // Clear module cache and reimport with mocked debounce
150
- vi.resetModules()
151
- const {useProductSearch: mockedUseProductSearch} = await import(
152
- './useProductSearch'
153
- )
154
-
155
- const {result, rerender} = renderHook(
156
- ({query}) => mockedUseProductSearch({query}),
157
- {
158
- initialProps: {query: 'initial'},
159
- }
160
- )
161
-
162
- // Initially not typing
163
- expect(result.current.isTyping).toBe(false)
164
-
165
- // Change query
166
- rerender({query: 'updated'})
167
-
168
- // isTyping should be true immediately after query change
169
- expect(result.current.isTyping).toBe(true)
170
-
171
- // Simulate debounce callback execution
172
- await act(async () => {
173
- if (debouncedCallback) {
174
- debouncedCallback()
175
- }
176
- })
177
-
178
- // After debounce executes, isTyping should be false
179
- await waitFor(() => {
180
- expect(result.current.isTyping).toBe(false)
181
- })
182
-
183
- // Restore original mock
184
- vi.doMock('lodash/debounce', () => ({
185
- default: (fn: any) => {
186
- const debounced = (...args: any[]) => fn(...args)
187
- debounced.cancel = vi.fn()
188
- return debounced
189
- },
190
- }))
191
- })
192
-
193
- it('cancels debounced function on unmount', async () => {
194
- const cancelSpy = vi.fn()
195
-
196
- // Mock debounce with cancel spy
197
- vi.doMock('lodash/debounce', () => ({
198
- default: (fn: any) => {
199
- const debounced = (...args: any[]) => fn(...args)
200
- debounced.cancel = cancelSpy
201
- return debounced
202
- },
203
- }))
204
-
205
- // Clear module cache and reimport with mocked debounce
206
- vi.resetModules()
207
- const {useProductSearch: mockedUseProductSearch} = await import(
208
- './useProductSearch'
209
- )
210
-
211
- const {unmount} = renderHook(() =>
212
- mockedUseProductSearch({
213
- query: 'test',
214
- })
215
- )
216
-
217
- unmount()
218
-
219
- expect(cancelSpy).toHaveBeenCalled()
220
-
221
- // Restore original mock
222
- vi.doMock('lodash/debounce', () => ({
223
- default: (fn: any) => {
224
- const debounced = (...args: any[]) => fn(...args)
225
- debounced.cancel = vi.fn()
226
- return debounced
227
- },
228
- }))
229
- })
230
- })
231
-
232
- describe('isTyping State', () => {
233
- it('returns isTyping as false when debounced query matches current query', () => {
234
- const {result} = renderHook(() =>
235
- useProductSearch({
236
- query: 'test',
237
- })
238
- )
239
-
240
- expect(result.current.isTyping).toBe(false)
241
- })
242
-
243
- it('returns isTyping as true when queries differ', async () => {
244
- // Create a custom mock for debounce that we can control
245
- let debouncedCallback: any = null
246
- const mockDebounce = vi.fn((fn: any, _delay: number) => {
247
- const debounced = (...args: any[]) => {
248
- debouncedCallback = () => fn(...args)
249
- }
250
- debounced.cancel = vi.fn()
251
- return debounced
252
- })
253
-
254
- // Mock lodash/debounce with our custom implementation
255
- vi.doMock('lodash/debounce', () => ({
256
- default: mockDebounce,
257
- }))
258
-
259
- // Clear module cache and reimport with mocked debounce
260
- vi.resetModules()
261
- const {useProductSearch: mockedUseProductSearch} = await import(
262
- './useProductSearch'
263
- )
264
-
265
- const {result, rerender} = renderHook(
266
- ({query}) => mockedUseProductSearch({query}),
267
- {
268
- initialProps: {query: 'initial'},
269
- }
270
- )
271
-
272
- // Initially not typing
273
- expect(result.current.isTyping).toBe(false)
274
-
275
- // Update query
276
- rerender({query: 'new query'})
277
-
278
- // Should be typing now
279
- expect(result.current.isTyping).toBe(true)
280
-
281
- // Simulate debounce callback execution
282
- await act(async () => {
283
- if (debouncedCallback) {
284
- debouncedCallback()
285
- }
286
- })
287
-
288
- // Should no longer be typing after debounce executes
289
- await waitFor(() => {
290
- expect(result.current.isTyping).toBe(false)
291
- })
292
-
293
- // Restore original mock
294
- vi.doMock('lodash/debounce', () => ({
295
- default: (fn: any) => {
296
- const debounced = (...args: any[]) => fn(...args)
297
- debounced.cancel = vi.fn()
298
- return debounced
299
- },
300
- }))
301
- })
302
- })
303
-
304
- describe('Pagination', () => {
305
- it('exposes pagination methods from underlying hook', () => {
306
- const mockFetchMore = vi.fn()
307
- const mockRefetch = vi.fn()
308
-
309
- ;(useShopActionsPaginatedDataFetching as any).mockReturnValue({
310
- data: mockProducts(3),
311
- loading: false,
312
- error: null,
313
- hasNextPage: true,
314
- fetchMore: mockFetchMore,
315
- refetch: mockRefetch,
316
- })
317
-
318
- const {result} = renderHook(() =>
319
- useProductSearch({
320
- query: 'test',
321
- })
322
- )
323
-
324
- expect(result.current.hasNextPage).toBe(true)
325
- expect(result.current.fetchMore).toBe(mockFetchMore)
326
- expect(result.current.refetch).toBe(mockRefetch)
327
-
328
- // Call the methods to ensure they're properly exposed
329
- result.current.fetchMore()
330
- result.current.refetch()
331
-
332
- expect(mockFetchMore).toHaveBeenCalledTimes(1)
333
- expect(mockRefetch).toHaveBeenCalledTimes(1)
334
- })
335
- })
336
-
337
- describe('Loading and Error States', () => {
338
- it('passes through loading state', () => {
339
- ;(useShopActionsPaginatedDataFetching as any).mockReturnValue({
340
- data: null,
341
- loading: true,
342
- error: null,
343
- hasNextPage: false,
344
- fetchMore: vi.fn(),
345
- refetch: vi.fn(),
346
- })
347
-
348
- const {result} = renderHook(() =>
349
- useProductSearch({
350
- query: 'test',
351
- })
352
- )
353
-
354
- expect(result.current.loading).toBe(true)
355
- expect(result.current.products).toBe(null)
356
- })
357
-
358
- it('passes through error state', () => {
359
- const testError = new Error('Search failed')
360
-
361
- ;(useShopActionsPaginatedDataFetching as any).mockReturnValue({
362
- data: null,
363
- loading: false,
364
- error: testError,
365
- hasNextPage: false,
366
- fetchMore: vi.fn(),
367
- refetch: vi.fn(),
368
- })
369
-
370
- const {result} = renderHook(() =>
371
- useProductSearch({
372
- query: 'test',
373
- })
374
- )
375
-
376
- expect(result.current.error).toBe(testError)
377
- expect(result.current.products).toBe(null)
378
- })
379
- })
380
-
381
- describe('Filters and Sorting', () => {
382
- it('passes filters to underlying hook', () => {
383
- const filters = {} as any // Mock filters object
384
-
385
- renderHook(() =>
386
- useProductSearch({
387
- query: 'test',
388
- filters,
389
- })
390
- )
391
-
392
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
393
- expect.any(Function),
394
- expect.objectContaining({
395
- filters,
396
- }),
397
- expect.any(Object)
398
- )
399
- })
400
-
401
- it('passes sortBy to underlying hook', () => {
402
- renderHook(() =>
403
- useProductSearch({
404
- query: 'test',
405
- sortBy: 'RELEVANCE',
406
- })
407
- )
408
-
409
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
410
- expect.any(Function),
411
- expect.objectContaining({
412
- sortBy: 'RELEVANCE',
413
- }),
414
- expect.any(Object)
415
- )
416
- })
417
-
418
- it('uses default value for includeSensitive', () => {
419
- renderHook(() =>
420
- useProductSearch({
421
- query: 'test',
422
- })
423
- )
424
-
425
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
426
- expect.any(Function),
427
- expect.objectContaining({
428
- includeSensitive: false,
429
- }),
430
- expect.any(Object)
431
- )
432
- })
433
- })
434
-
435
- describe('Hook Options', () => {
436
- it('passes pagination parameters', () => {
437
- renderHook(
438
- () =>
439
- useProductSearch({
440
- query: 'test',
441
- first: 20,
442
- } as any) // Type assertion to avoid type error
443
- )
444
-
445
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
446
- expect.any(Function),
447
- expect.objectContaining({
448
- first: 20,
449
- }),
450
- expect.any(Object)
451
- )
452
- })
453
-
454
- it('provides hook name for error tracking', () => {
455
- renderHook(() =>
456
- useProductSearch({
457
- query: 'test',
458
- })
459
- )
460
-
461
- expect(useShopActionsPaginatedDataFetching).toHaveBeenCalledWith(
462
- expect.any(Function),
463
- expect.any(Object),
464
- expect.objectContaining({
465
- hook: 'useProductSearch',
466
- })
467
- )
468
- })
469
- })
470
- })