@scality/data-browser-library 1.0.0-preview.11

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 (256) hide show
  1. package/dist/components/Editor.d.ts +12 -0
  2. package/dist/components/Editor.js +28 -0
  3. package/dist/components/__tests__/BucketCreate.test.d.ts +1 -0
  4. package/dist/components/__tests__/BucketCreate.test.js +408 -0
  5. package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +1 -0
  6. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +618 -0
  7. package/dist/components/__tests__/BucketLifecycleList.test.d.ts +1 -0
  8. package/dist/components/__tests__/BucketLifecycleList.test.js +325 -0
  9. package/dist/components/__tests__/BucketList.test.d.ts +1 -0
  10. package/dist/components/__tests__/BucketList.test.js +415 -0
  11. package/dist/components/__tests__/BucketNotificationCreatePage.test.d.ts +1 -0
  12. package/dist/components/__tests__/BucketNotificationCreatePage.test.js +316 -0
  13. package/dist/components/__tests__/BucketOverview.test.d.ts +1 -0
  14. package/dist/components/__tests__/BucketOverview.test.js +769 -0
  15. package/dist/components/__tests__/BucketPolicyPage.test.d.ts +1 -0
  16. package/dist/components/__tests__/BucketPolicyPage.test.js +268 -0
  17. package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +1 -0
  18. package/dist/components/__tests__/BucketReplicationFormPage.test.js +1757 -0
  19. package/dist/components/__tests__/BucketReplicationList.test.d.ts +1 -0
  20. package/dist/components/__tests__/BucketReplicationList.test.js +344 -0
  21. package/dist/components/__tests__/CreateFolderButton.test.d.ts +1 -0
  22. package/dist/components/__tests__/CreateFolderButton.test.js +147 -0
  23. package/dist/components/__tests__/DeleteBucketButton.test.d.ts +1 -0
  24. package/dist/components/__tests__/DeleteBucketButton.test.js +272 -0
  25. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.d.ts +1 -0
  26. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +196 -0
  27. package/dist/components/__tests__/DeleteObjectButton.test.d.ts +1 -0
  28. package/dist/components/__tests__/DeleteObjectButton.test.js +302 -0
  29. package/dist/components/__tests__/EmptyBucketButton.test.d.ts +1 -0
  30. package/dist/components/__tests__/EmptyBucketButton.test.js +302 -0
  31. package/dist/components/__tests__/MetadataSearch.test.d.ts +1 -0
  32. package/dist/components/__tests__/MetadataSearch.test.js +201 -0
  33. package/dist/components/__tests__/ObjectList.test.d.ts +1 -0
  34. package/dist/components/__tests__/ObjectList.test.js +283 -0
  35. package/dist/components/__tests__/UploadButton.test.d.ts +1 -0
  36. package/dist/components/__tests__/UploadButton.test.js +144 -0
  37. package/dist/components/buckets/BucketCreate.d.ts +49 -0
  38. package/dist/components/buckets/BucketCreate.js +237 -0
  39. package/dist/components/buckets/BucketDetails.d.ts +1 -0
  40. package/dist/components/buckets/BucketDetails.js +106 -0
  41. package/dist/components/buckets/BucketLifecycleFormPage.d.ts +15 -0
  42. package/dist/components/buckets/BucketLifecycleFormPage.js +1085 -0
  43. package/dist/components/buckets/BucketLifecycleList.d.ts +10 -0
  44. package/dist/components/buckets/BucketLifecycleList.js +270 -0
  45. package/dist/components/buckets/BucketList.d.ts +15 -0
  46. package/dist/components/buckets/BucketList.js +146 -0
  47. package/dist/components/buckets/BucketLocation.d.ts +3 -0
  48. package/dist/components/buckets/BucketLocation.js +16 -0
  49. package/dist/components/buckets/BucketOverview.d.ts +88 -0
  50. package/dist/components/buckets/BucketOverview.js +291 -0
  51. package/dist/components/buckets/BucketPage.d.ts +2 -0
  52. package/dist/components/buckets/BucketPage.js +47 -0
  53. package/dist/components/buckets/BucketPolicyButton.d.ts +7 -0
  54. package/dist/components/buckets/BucketPolicyButton.js +18 -0
  55. package/dist/components/buckets/BucketPolicyPage.d.ts +1 -0
  56. package/dist/components/buckets/BucketPolicyPage.js +236 -0
  57. package/dist/components/buckets/BucketReplicationFormPage.d.ts +1 -0
  58. package/dist/components/buckets/BucketReplicationFormPage.js +834 -0
  59. package/dist/components/buckets/BucketReplicationList.d.ts +11 -0
  60. package/dist/components/buckets/BucketReplicationList.js +189 -0
  61. package/dist/components/buckets/BucketVersioning.d.ts +4 -0
  62. package/dist/components/buckets/BucketVersioning.js +73 -0
  63. package/dist/components/buckets/DeleteBucketButton.d.ts +8 -0
  64. package/dist/components/buckets/DeleteBucketButton.js +78 -0
  65. package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +18 -0
  66. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +53 -0
  67. package/dist/components/buckets/EmptyBucketButton.d.ts +5 -0
  68. package/dist/components/buckets/EmptyBucketButton.js +232 -0
  69. package/dist/components/buckets/EmptyBucketSummary.d.ts +9 -0
  70. package/dist/components/buckets/EmptyBucketSummary.js +60 -0
  71. package/dist/components/buckets/EmptyBucketSummaryList.d.ts +13 -0
  72. package/dist/components/buckets/EmptyBucketSummaryList.js +140 -0
  73. package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
  74. package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
  75. package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +1 -0
  76. package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +234 -0
  77. package/dist/components/buckets/notifications/EventsSection.d.ts +1 -0
  78. package/dist/components/buckets/notifications/EventsSection.js +123 -0
  79. package/dist/components/buckets/notifications/events.d.ts +12 -0
  80. package/dist/components/buckets/notifications/events.js +27 -0
  81. package/dist/components/index.d.ts +21 -0
  82. package/dist/components/index.js +22 -0
  83. package/dist/components/layouts/ArrowNavigation.d.ts +4 -0
  84. package/dist/components/layouts/ArrowNavigation.js +16 -0
  85. package/dist/components/layouts/BrowserPageLayout.d.ts +12 -0
  86. package/dist/components/layouts/BrowserPageLayout.js +51 -0
  87. package/dist/components/objects/CreateFolderButton.d.ts +29 -0
  88. package/dist/components/objects/CreateFolderButton.js +118 -0
  89. package/dist/components/objects/DeleteObjectButton.d.ts +8 -0
  90. package/dist/components/objects/DeleteObjectButton.js +191 -0
  91. package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -0
  92. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +356 -0
  93. package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +3 -0
  94. package/dist/components/objects/ObjectDetails/ObjectSummary.js +241 -0
  95. package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +3 -0
  96. package/dist/components/objects/ObjectDetails/ObjectTags.js +272 -0
  97. package/dist/components/objects/ObjectDetails/index.d.ts +9 -0
  98. package/dist/components/objects/ObjectDetails/index.js +75 -0
  99. package/dist/components/objects/ObjectList.d.ts +40 -0
  100. package/dist/components/objects/ObjectList.js +453 -0
  101. package/dist/components/objects/ObjectLock/EditRetentionButton.d.ts +4 -0
  102. package/dist/components/objects/ObjectLock/EditRetentionButton.js +32 -0
  103. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.d.ts +3 -0
  104. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +211 -0
  105. package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +9 -0
  106. package/dist/components/objects/ObjectLock/ObjectLockSettings.js +158 -0
  107. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +8 -0
  108. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +39 -0
  109. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.d.ts +1 -0
  110. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +204 -0
  111. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.d.ts +1 -0
  112. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +374 -0
  113. package/dist/components/objects/ObjectPage.d.ts +1 -0
  114. package/dist/components/objects/ObjectPage.js +45 -0
  115. package/dist/components/objects/UploadButton.d.ts +34 -0
  116. package/dist/components/objects/UploadButton.js +229 -0
  117. package/dist/components/providers/DataBrowserProvider.d.ts +20 -0
  118. package/dist/components/providers/DataBrowserProvider.js +42 -0
  119. package/dist/components/search/MetadataSearch.d.ts +5 -0
  120. package/dist/components/search/MetadataSearch.js +162 -0
  121. package/dist/components/search/SearchHints.d.ts +8 -0
  122. package/dist/components/search/SearchHints.js +21 -0
  123. package/dist/components/ui/ArrayFieldActions.d.ts +36 -0
  124. package/dist/components/ui/ArrayFieldActions.js +43 -0
  125. package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +16 -0
  126. package/dist/components/ui/ConfirmDeleteRuleModal.js +43 -0
  127. package/dist/components/ui/DeleteObjectModalContent.d.ts +5 -0
  128. package/dist/components/ui/DeleteObjectModalContent.js +71 -0
  129. package/dist/components/ui/FilterFormSection.d.ts +44 -0
  130. package/dist/components/ui/FilterFormSection.js +159 -0
  131. package/dist/components/ui/Search.elements.d.ts +17 -0
  132. package/dist/components/ui/Search.elements.js +59 -0
  133. package/dist/components/ui/Table.elements.d.ts +36 -0
  134. package/dist/components/ui/Table.elements.js +87 -0
  135. package/dist/config/factory.d.ts +63 -0
  136. package/dist/config/factory.js +74 -0
  137. package/dist/config/types.d.ts +46 -0
  138. package/dist/config/types.js +0 -0
  139. package/dist/hooks/__tests__/useISVBucketDetection.test.d.ts +1 -0
  140. package/dist/hooks/__tests__/useISVBucketDetection.test.js +188 -0
  141. package/dist/hooks/__tests__/useIsBucketEmpty.test.d.ts +1 -0
  142. package/dist/hooks/__tests__/useIsBucketEmpty.test.js +122 -0
  143. package/dist/hooks/bucketConfiguration.d.ts +168 -0
  144. package/dist/hooks/bucketConfiguration.js +67 -0
  145. package/dist/hooks/bucketOperations.d.ts +36 -0
  146. package/dist/hooks/bucketOperations.js +12 -0
  147. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.d.ts +1 -0
  148. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +276 -0
  149. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.d.ts +1 -0
  150. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +259 -0
  151. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.d.ts +1 -0
  152. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +166 -0
  153. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.d.ts +1 -0
  154. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +200 -0
  155. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.d.ts +1 -0
  156. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +179 -0
  157. package/dist/hooks/factories/index.d.ts +18 -0
  158. package/dist/hooks/factories/index.js +5 -0
  159. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +13 -0
  160. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +76 -0
  161. package/dist/hooks/factories/useCreateS3LoginHook.d.ts +8 -0
  162. package/dist/hooks/factories/useCreateS3LoginHook.js +22 -0
  163. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +5 -0
  164. package/dist/hooks/factories/useCreateS3MutationHook.js +50 -0
  165. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +3 -0
  166. package/dist/hooks/factories/useCreateS3QueryHook.js +51 -0
  167. package/dist/hooks/index.d.ts +13 -0
  168. package/dist/hooks/index.js +13 -0
  169. package/dist/hooks/loginOperations.d.ts +21 -0
  170. package/dist/hooks/loginOperations.js +9 -0
  171. package/dist/hooks/objectOperations.d.ts +190 -0
  172. package/dist/hooks/objectOperations.js +67 -0
  173. package/dist/hooks/presignedOperations.d.ts +73 -0
  174. package/dist/hooks/presignedOperations.js +72 -0
  175. package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
  176. package/dist/hooks/useBatchObjectLegalHold.js +45 -0
  177. package/dist/hooks/useDeleteBucketConfigRule.d.ts +26 -0
  178. package/dist/hooks/useDeleteBucketConfigRule.js +46 -0
  179. package/dist/hooks/useEmptyBucket.d.ts +27 -0
  180. package/dist/hooks/useEmptyBucket.js +116 -0
  181. package/dist/hooks/useISVBucketDetection.d.ts +15 -0
  182. package/dist/hooks/useISVBucketDetection.js +27 -0
  183. package/dist/hooks/useIsBucketEmpty.d.ts +7 -0
  184. package/dist/hooks/useIsBucketEmpty.js +36 -0
  185. package/dist/hooks/useLoginMutation.d.ts +21 -0
  186. package/dist/hooks/useLoginMutation.js +9 -0
  187. package/dist/hooks/useS3Client.d.ts +1 -0
  188. package/dist/hooks/useS3Client.js +13 -0
  189. package/dist/hooks/useTableRowSelection.d.ts +9 -0
  190. package/dist/hooks/useTableRowSelection.js +45 -0
  191. package/dist/index.d.ts +6 -0
  192. package/dist/index.js +6 -0
  193. package/dist/schemas/bucketPolicySchema.json +321 -0
  194. package/dist/test/msw/handlers/deleteBucket.d.ts +1 -0
  195. package/dist/test/msw/handlers/deleteBucket.js +14 -0
  196. package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -0
  197. package/dist/test/msw/handlers/getBucketAcl.js +96 -0
  198. package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -0
  199. package/dist/test/msw/handlers/getBucketLocation.js +23 -0
  200. package/dist/test/msw/handlers/getBucketPolicy.d.ts +11 -0
  201. package/dist/test/msw/handlers/getBucketPolicy.js +72 -0
  202. package/dist/test/msw/handlers/headObject.d.ts +1 -0
  203. package/dist/test/msw/handlers/headObject.js +17 -0
  204. package/dist/test/msw/handlers/listBuckets.d.ts +1 -0
  205. package/dist/test/msw/handlers/listBuckets.js +24 -0
  206. package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -0
  207. package/dist/test/msw/handlers/listObjectVersions.js +83 -0
  208. package/dist/test/msw/handlers/listObjects.d.ts +1 -0
  209. package/dist/test/msw/handlers/listObjects.js +66 -0
  210. package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -0
  211. package/dist/test/msw/handlers/objectLegalHold.js +24 -0
  212. package/dist/test/msw/handlers/objectRetention.d.ts +1 -0
  213. package/dist/test/msw/handlers/objectRetention.js +27 -0
  214. package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -0
  215. package/dist/test/msw/handlers/putBucketAcl.js +18 -0
  216. package/dist/test/msw/handlers/putObject.d.ts +1 -0
  217. package/dist/test/msw/handlers/putObject.js +16 -0
  218. package/dist/test/msw/handlers.d.ts +4 -0
  219. package/dist/test/msw/handlers.js +109 -0
  220. package/dist/test/msw/index.d.ts +2 -0
  221. package/dist/test/msw/index.js +3 -0
  222. package/dist/test/msw/server.d.ts +4 -0
  223. package/dist/test/msw/server.js +20 -0
  224. package/dist/test/msw/utils.d.ts +2 -0
  225. package/dist/test/msw/utils.js +13 -0
  226. package/dist/test/setup.d.ts +1 -0
  227. package/dist/test/setup.js +90 -0
  228. package/dist/test/testUtils.d.ts +181 -0
  229. package/dist/test/testUtils.js +310 -0
  230. package/dist/test/utils/errorHandling.test.d.ts +1 -0
  231. package/dist/test/utils/errorHandling.test.js +423 -0
  232. package/dist/types/index.d.ts +51 -0
  233. package/dist/types/index.js +0 -0
  234. package/dist/utils/constants.d.ts +12 -0
  235. package/dist/utils/constants.js +9 -0
  236. package/dist/utils/deletion/index.d.ts +2 -0
  237. package/dist/utils/deletion/index.js +2 -0
  238. package/dist/utils/deletion/messages.d.ts +5 -0
  239. package/dist/utils/deletion/messages.js +29 -0
  240. package/dist/utils/deletion/types.d.ts +11 -0
  241. package/dist/utils/deletion/types.js +0 -0
  242. package/dist/utils/errorHandling.d.ts +63 -0
  243. package/dist/utils/errorHandling.js +84 -0
  244. package/dist/utils/hooks.d.ts +2 -0
  245. package/dist/utils/hooks.js +26 -0
  246. package/dist/utils/index.d.ts +4 -0
  247. package/dist/utils/index.js +4 -0
  248. package/dist/utils/proxyMiddleware.d.ts +18 -0
  249. package/dist/utils/proxyMiddleware.js +56 -0
  250. package/dist/utils/s3Client.d.ts +5 -0
  251. package/dist/utils/s3Client.js +36 -0
  252. package/dist/utils/s3RuleUtils.d.ts +53 -0
  253. package/dist/utils/s3RuleUtils.js +101 -0
  254. package/dist/utils/useFeatures.d.ts +1 -0
  255. package/dist/utils/useFeatures.js +7 -0
  256. package/package.json +84 -0
@@ -0,0 +1,276 @@
1
+ import { renderHook, waitFor } from "@testing-library/react";
2
+ import { useCreateS3FunctionMutationHook } from "../useCreateS3MutationHook.js";
3
+ import { useS3Client } from "../../useS3Client.js";
4
+ import { createS3OperationError } from "../../../utils/errorHandling.js";
5
+ import { createQueryWrapper, validateFactoryHook, validateHookResult } from "../../../test/testUtils.js";
6
+ jest.mock("../../useS3Client");
7
+ jest.mock("../../../utils/errorHandling");
8
+ const mockUseS3Client = useS3Client;
9
+ const mockCreateS3OperationError = createS3OperationError;
10
+ const mockS3Client = {
11
+ config: {}
12
+ };
13
+ const mockOperation = jest.fn();
14
+ describe("useCreateS3FunctionMutationHook - Factory Specific", ()=>{
15
+ beforeEach(()=>{
16
+ jest.clearAllMocks();
17
+ mockUseS3Client.mockReturnValue(mockS3Client);
18
+ mockOperation.mockReset();
19
+ });
20
+ it("should create a functioning mutation hook", ()=>{
21
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
22
+ validateFactoryHook(useMutation, "function-based mutation");
23
+ const { result } = renderHook(()=>useMutation(), {
24
+ wrapper: createQueryWrapper()
25
+ });
26
+ validateHookResult(result.current, "mutation");
27
+ });
28
+ it("should accept invalidation keys parameter", ()=>{
29
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation, [
30
+ "PresignedUrls",
31
+ "TestQuery"
32
+ ]);
33
+ validateFactoryHook(useMutation, "function-based mutation");
34
+ const { result } = renderHook(()=>useMutation(), {
35
+ wrapper: createQueryWrapper()
36
+ });
37
+ validateHookResult(result.current, "mutation");
38
+ });
39
+ it("should execute function operation successfully", async ()=>{
40
+ const mockResponse = {
41
+ Url: "https://presigned.url",
42
+ ExpiresAt: new Date(),
43
+ Bucket: "test-bucket",
44
+ Key: "test-key"
45
+ };
46
+ mockOperation.mockResolvedValue(mockResponse);
47
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
48
+ const { result } = renderHook(()=>useMutation(), {
49
+ wrapper: createQueryWrapper()
50
+ });
51
+ const inputParams = {
52
+ Bucket: "test-bucket",
53
+ Key: "test-key",
54
+ expiresIn: 3600
55
+ };
56
+ result.current.mutate(inputParams);
57
+ await waitFor(()=>{
58
+ expect(result.current.isSuccess).toBe(true);
59
+ });
60
+ expect(result.current.data).toEqual(mockResponse);
61
+ expect(mockOperation).toHaveBeenCalledWith(mockS3Client, inputParams);
62
+ expect(mockOperation).toHaveBeenCalledTimes(1);
63
+ });
64
+ it("should handle function operation errors", async ()=>{
65
+ const mockError = new Error("Presigned URL generation failed");
66
+ mockOperation.mockRejectedValue(mockError);
67
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
68
+ const { result } = renderHook(()=>useMutation(), {
69
+ wrapper: createQueryWrapper()
70
+ });
71
+ result.current.mutate({
72
+ Bucket: "test-bucket",
73
+ Key: "test-key"
74
+ });
75
+ await waitFor(()=>{
76
+ expect(result.current.isError).toBe(true);
77
+ });
78
+ expect(result.current.error).toBe(mockError);
79
+ expect(mockOperation).toHaveBeenCalledWith(mockS3Client, {
80
+ Bucket: "test-bucket",
81
+ Key: "test-key"
82
+ });
83
+ expect(mockCreateS3OperationError).not.toHaveBeenCalled();
84
+ });
85
+ it("should handle function operation with internal error wrapping", async ()=>{
86
+ const mockInternalError = new Error("Internal operation error");
87
+ const mockWrappedError = new Error("Wrapped operation error");
88
+ const mockOperationWithErrorHandling = jest.fn().mockImplementation(async ()=>{
89
+ try {
90
+ throw mockInternalError;
91
+ } catch (error) {
92
+ const wrappedError = mockWrappedError;
93
+ throw wrappedError;
94
+ }
95
+ });
96
+ const useMutation = useCreateS3FunctionMutationHook(mockOperationWithErrorHandling);
97
+ const { result } = renderHook(()=>useMutation(), {
98
+ wrapper: createQueryWrapper()
99
+ });
100
+ result.current.mutate({
101
+ Bucket: "test-bucket",
102
+ Key: "test-key"
103
+ });
104
+ await waitFor(()=>{
105
+ expect(result.current.isError).toBe(true);
106
+ });
107
+ expect(result.current.error).toBe(mockWrappedError);
108
+ expect(mockOperationWithErrorHandling).toHaveBeenCalledWith(mockS3Client, {
109
+ Bucket: "test-bucket",
110
+ Key: "test-key"
111
+ });
112
+ });
113
+ it("should handle mutation callbacks correctly", async ()=>{
114
+ const mockResponse = {
115
+ Url: "https://presigned.url",
116
+ ExpiresAt: new Date()
117
+ };
118
+ const onSuccess = jest.fn();
119
+ const onError = jest.fn();
120
+ const onSettled = jest.fn();
121
+ mockOperation.mockResolvedValue(mockResponse);
122
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
123
+ const { result } = renderHook(()=>useMutation({
124
+ onSuccess,
125
+ onError,
126
+ onSettled
127
+ }), {
128
+ wrapper: createQueryWrapper()
129
+ });
130
+ const variables = {
131
+ Bucket: "test-bucket",
132
+ Key: "test-key"
133
+ };
134
+ result.current.mutate(variables);
135
+ await waitFor(()=>{
136
+ expect(result.current.isSuccess).toBe(true);
137
+ });
138
+ expect(onSuccess).toHaveBeenCalledWith(mockResponse, variables, void 0, expect.any(Object));
139
+ expect(onError).not.toHaveBeenCalled();
140
+ expect(onSettled).toHaveBeenCalledWith(mockResponse, null, variables, void 0, expect.any(Object));
141
+ });
142
+ it("should handle function operation with invalidation keys", async ()=>{
143
+ const mockResponse = {
144
+ success: true
145
+ };
146
+ mockOperation.mockResolvedValue(mockResponse);
147
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation, [
148
+ "PresignedUrls",
149
+ "ObjectList"
150
+ ]);
151
+ const { result } = renderHook(()=>useMutation(), {
152
+ wrapper: createQueryWrapper()
153
+ });
154
+ result.current.mutate({
155
+ Bucket: "test-bucket",
156
+ Key: "test-key"
157
+ });
158
+ await waitFor(()=>{
159
+ expect(result.current.isSuccess).toBe(true);
160
+ });
161
+ expect(result.current.data).toEqual(mockResponse);
162
+ expect(mockOperation).toHaveBeenCalledWith(mockS3Client, {
163
+ Bucket: "test-bucket",
164
+ Key: "test-key"
165
+ });
166
+ });
167
+ it("should handle concurrent function operations correctly", async ()=>{
168
+ const mockResponse1 = {
169
+ Url: "https://presigned1.url",
170
+ ExpiresAt: new Date()
171
+ };
172
+ const mockResponse2 = {
173
+ Url: "https://presigned2.url",
174
+ ExpiresAt: new Date()
175
+ };
176
+ let callCount = 0;
177
+ mockOperation.mockImplementation(()=>{
178
+ callCount++;
179
+ return Promise.resolve(1 === callCount ? mockResponse1 : mockResponse2);
180
+ });
181
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
182
+ const { result: result1 } = renderHook(()=>useMutation(), {
183
+ wrapper: createQueryWrapper()
184
+ });
185
+ const { result: result2 } = renderHook(()=>useMutation(), {
186
+ wrapper: createQueryWrapper()
187
+ });
188
+ result1.current.mutate({
189
+ Bucket: "test-bucket",
190
+ Key: "file1.txt"
191
+ });
192
+ result2.current.mutate({
193
+ Bucket: "test-bucket",
194
+ Key: "file2.txt"
195
+ });
196
+ await waitFor(()=>{
197
+ expect(result1.current.isSuccess).toBe(true);
198
+ expect(result2.current.isSuccess).toBe(true);
199
+ });
200
+ expect(result1.current.data).toEqual(mockResponse1);
201
+ expect(result2.current.data).toEqual(mockResponse2);
202
+ expect(mockOperation).toHaveBeenCalledTimes(2);
203
+ });
204
+ it("should pass correct parameters to function operation", async ()=>{
205
+ const mockResponse = {
206
+ success: true
207
+ };
208
+ let capturedClient;
209
+ let capturedParams;
210
+ mockOperation.mockImplementation((client, params)=>{
211
+ capturedClient = client;
212
+ capturedParams = params;
213
+ return Promise.resolve(mockResponse);
214
+ });
215
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
216
+ const { result } = renderHook(()=>useMutation(), {
217
+ wrapper: createQueryWrapper()
218
+ });
219
+ const inputParams = {
220
+ Bucket: "test-bucket",
221
+ Key: "test-key",
222
+ ContentType: "text/plain",
223
+ expiresIn: 1800
224
+ };
225
+ result.current.mutate(inputParams);
226
+ await waitFor(()=>{
227
+ expect(result.current.isSuccess).toBe(true);
228
+ });
229
+ expect(capturedClient).toBe(mockS3Client);
230
+ expect(capturedParams).toEqual(inputParams);
231
+ });
232
+ it("should handle complex function operations with metadata", async ()=>{
233
+ const mockResponse = {
234
+ Url: "https://complex-presigned.url",
235
+ ExpiresAt: new Date("2024-01-01T12:00:00Z"),
236
+ Bucket: "complex-bucket",
237
+ Key: "complex/path/file.txt",
238
+ VersionId: "version123"
239
+ };
240
+ mockOperation.mockResolvedValue(mockResponse);
241
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
242
+ const { result } = renderHook(()=>useMutation(), {
243
+ wrapper: createQueryWrapper()
244
+ });
245
+ const complexParams = {
246
+ Bucket: "complex-bucket",
247
+ Key: "complex/path/file.txt",
248
+ VersionId: "version123",
249
+ ResponseContentType: "application/json",
250
+ ResponseContentDisposition: "attachment; filename=data.json",
251
+ expiresIn: 7200
252
+ };
253
+ result.current.mutate(complexParams);
254
+ await waitFor(()=>{
255
+ expect(result.current.isSuccess).toBe(true);
256
+ });
257
+ expect(result.current.data).toEqual(mockResponse);
258
+ expect(mockOperation).toHaveBeenCalledWith(mockS3Client, complexParams);
259
+ });
260
+ it("should handle function operations without parameters", async ()=>{
261
+ const mockResponse = {
262
+ status: "operation completed"
263
+ };
264
+ mockOperation.mockResolvedValue(mockResponse);
265
+ const useMutation = useCreateS3FunctionMutationHook(mockOperation);
266
+ const { result } = renderHook(()=>useMutation(), {
267
+ wrapper: createQueryWrapper()
268
+ });
269
+ result.current.mutate(void 0);
270
+ await waitFor(()=>{
271
+ expect(result.current.isSuccess).toBe(true);
272
+ });
273
+ expect(result.current.data).toEqual(mockResponse);
274
+ expect(mockOperation).toHaveBeenCalledWith(mockS3Client, void 0);
275
+ });
276
+ });
@@ -0,0 +1,259 @@
1
+ import { renderHook, waitFor } from "@testing-library/react";
2
+ import { useCreateS3InfiniteQueryHook } from "../useCreateS3InfiniteQueryHook.js";
3
+ import { useS3Client } from "../../useS3Client.js";
4
+ import { createS3OperationError } from "../../../utils/errorHandling.js";
5
+ import { createQueryWrapper, validateFactoryHook, validateHookResult } from "../../../test/testUtils.js";
6
+ jest.mock("../../useS3Client");
7
+ jest.mock("../../../utils/errorHandling");
8
+ const mockUseS3Client = useS3Client;
9
+ const mockCreateS3OperationError = createS3OperationError;
10
+ class MockCommand {
11
+ input;
12
+ constructor(input){
13
+ this.input = input;
14
+ }
15
+ }
16
+ const mockS3Client = {
17
+ send: jest.fn()
18
+ };
19
+ describe("useCreateS3InfiniteQueryHook - Pagination Logic", ()=>{
20
+ beforeEach(()=>{
21
+ jest.clearAllMocks();
22
+ mockUseS3Client.mockReturnValue(mockS3Client);
23
+ });
24
+ it("should create a functioning infinite query hook", ()=>{
25
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
26
+ validateFactoryHook(useInfiniteQuery, "ListObjects");
27
+ const { result } = renderHook(()=>useInfiniteQuery({
28
+ Bucket: "test-bucket"
29
+ }), {
30
+ wrapper: createQueryWrapper()
31
+ });
32
+ validateHookResult(result.current, "infiniteQuery");
33
+ });
34
+ it("should handle getPaginationParams for different operations", async ()=>{
35
+ const mockResponse = {
36
+ IsTruncated: false
37
+ };
38
+ mockS3Client.send.mockResolvedValue(mockResponse);
39
+ const useListObjects = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
40
+ const { result: listResult } = renderHook(()=>useListObjects({
41
+ Bucket: "test-bucket"
42
+ }), {
43
+ wrapper: createQueryWrapper()
44
+ });
45
+ const useListVersions = useCreateS3InfiniteQueryHook(MockCommand, "ListObjectVersions");
46
+ const { result: versionsResult } = renderHook(()=>useListVersions({
47
+ Bucket: "test-bucket"
48
+ }), {
49
+ wrapper: createQueryWrapper()
50
+ });
51
+ await waitFor(()=>{
52
+ expect(listResult.current.fetchStatus).not.toBe("idle");
53
+ expect(versionsResult.current.fetchStatus).not.toBe("idle");
54
+ });
55
+ expect(typeof listResult.current.fetchNextPage).toBe("function");
56
+ expect(typeof versionsResult.current.fetchNextPage).toBe("function");
57
+ });
58
+ it("should handle Prefix parameter in enabled logic correctly", ()=>{
59
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
60
+ const { result: undefinedResult } = renderHook(()=>useInfiniteQuery({
61
+ Bucket: "test-bucket",
62
+ Prefix: void 0
63
+ }), {
64
+ wrapper: createQueryWrapper()
65
+ });
66
+ expect(undefinedResult.current.fetchStatus).toBe("idle");
67
+ const { result: definedResult } = renderHook(()=>useInfiniteQuery({
68
+ Bucket: "test-bucket",
69
+ Prefix: "folder/"
70
+ }), {
71
+ wrapper: createQueryWrapper()
72
+ });
73
+ expect(definedResult.current.fetchStatus).not.toBe("idle");
74
+ });
75
+ it("should handle pagination data correctly", async ()=>{
76
+ const mockFirstPage = {
77
+ Contents: [
78
+ {
79
+ Key: "file1.txt"
80
+ },
81
+ {
82
+ Key: "file2.txt"
83
+ }
84
+ ],
85
+ IsTruncated: true,
86
+ NextContinuationToken: "token123"
87
+ };
88
+ const mockSecondPage = {
89
+ Contents: [
90
+ {
91
+ Key: "file3.txt"
92
+ },
93
+ {
94
+ Key: "file4.txt"
95
+ }
96
+ ],
97
+ IsTruncated: false
98
+ };
99
+ let callCount = 0;
100
+ mockS3Client.send.mockImplementation(()=>{
101
+ callCount++;
102
+ return Promise.resolve(1 === callCount ? mockFirstPage : mockSecondPage);
103
+ });
104
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
105
+ const { result } = renderHook(()=>useInfiniteQuery({
106
+ Bucket: "test-bucket"
107
+ }), {
108
+ wrapper: createQueryWrapper()
109
+ });
110
+ await waitFor(()=>{
111
+ expect(result.current.isSuccess).toBe(true);
112
+ });
113
+ const firstPageData = result.current.data;
114
+ expect(firstPageData?.pages).toHaveLength(1);
115
+ expect(firstPageData?.pages?.[0]).toEqual(mockFirstPage);
116
+ expect(result.current.hasNextPage).toBe(true);
117
+ result.current.fetchNextPage();
118
+ await waitFor(()=>{
119
+ const data = result.current.data;
120
+ expect(data?.pages).toHaveLength(2);
121
+ });
122
+ const finalData = result.current.data;
123
+ expect(finalData?.pages?.[1]).toEqual(mockSecondPage);
124
+ expect(result.current.hasNextPage).toBe(false);
125
+ });
126
+ it("should handle ListObjectVersions pagination patterns", async ()=>{
127
+ const mockVersionsResponse = {
128
+ Versions: [
129
+ {
130
+ Key: "file1.txt",
131
+ VersionId: "v1"
132
+ }
133
+ ],
134
+ DeleteMarkers: [
135
+ {
136
+ Key: "file2.txt",
137
+ VersionId: "v2"
138
+ }
139
+ ],
140
+ IsTruncated: true,
141
+ NextKeyMarker: "file1.txt",
142
+ NextVersionIdMarker: "v1"
143
+ };
144
+ mockS3Client.send.mockResolvedValue(mockVersionsResponse);
145
+ const useVersionsQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjectVersions");
146
+ const { result } = renderHook(()=>useVersionsQuery({
147
+ Bucket: "test-bucket"
148
+ }), {
149
+ wrapper: createQueryWrapper()
150
+ });
151
+ await waitFor(()=>{
152
+ expect(result.current.isSuccess).toBe(true);
153
+ });
154
+ const data = result.current.data;
155
+ expect(data?.pages).toHaveLength(1);
156
+ expect(data?.pages?.[0]).toEqual(mockVersionsResponse);
157
+ expect(result.current.hasNextPage).toBe(true);
158
+ expect(mockVersionsResponse.NextKeyMarker).toBe("file1.txt");
159
+ expect(mockVersionsResponse.NextVersionIdMarker).toBe("v1");
160
+ });
161
+ it("should handle infinite query errors with context", async ()=>{
162
+ const mockError = new Error("S3 List Error");
163
+ const enhancedError = new Error("Enhanced S3 List Error");
164
+ mockS3Client.send.mockRejectedValue(mockError);
165
+ mockCreateS3OperationError.mockReturnValue(enhancedError);
166
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
167
+ const { result } = renderHook(()=>useInfiniteQuery({
168
+ Bucket: "test-bucket"
169
+ }), {
170
+ wrapper: createQueryWrapper()
171
+ });
172
+ await waitFor(()=>{
173
+ expect(result.current.isError).toBe(true);
174
+ });
175
+ expect(result.current.error).toBe(enhancedError);
176
+ expect(mockCreateS3OperationError).toHaveBeenCalledWith(mockError, "ListObjects", "test-bucket");
177
+ });
178
+ it("should handle fetchNextPage correctly", async ()=>{
179
+ const mockFirstPage = {
180
+ Contents: [
181
+ {
182
+ Key: "file1.txt"
183
+ }
184
+ ],
185
+ IsTruncated: true,
186
+ NextContinuationToken: "token123"
187
+ };
188
+ mockS3Client.send.mockResolvedValue(mockFirstPage);
189
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
190
+ const { result } = renderHook(()=>useInfiniteQuery({
191
+ Bucket: "test-bucket"
192
+ }), {
193
+ wrapper: createQueryWrapper()
194
+ });
195
+ await waitFor(()=>{
196
+ expect(result.current.isSuccess).toBe(true);
197
+ });
198
+ expect(typeof result.current.fetchNextPage).toBe("function");
199
+ expect(result.current.isFetchingNextPage).toBe(false);
200
+ expect(result.current.hasNextPage).toBe(true);
201
+ expect(()=>result.current.fetchNextPage()).not.toThrow();
202
+ });
203
+ it("should handle infinite query options correctly", ()=>{
204
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
205
+ const customOptions = {
206
+ enabled: false,
207
+ staleTime: 10000,
208
+ refetchOnWindowFocus: false
209
+ };
210
+ const { result } = renderHook(()=>useInfiniteQuery({
211
+ Bucket: "test-bucket"
212
+ }, customOptions), {
213
+ wrapper: createQueryWrapper()
214
+ });
215
+ expect(result.current.fetchStatus).toBe("idle");
216
+ expect(result.current.isLoading).toBe(false);
217
+ });
218
+ it("should pass AbortSignal correctly for infinite queries", async ()=>{
219
+ let capturedAbortSignal;
220
+ mockS3Client.send.mockImplementation((_command, options)=>{
221
+ capturedAbortSignal = options?.abortSignal;
222
+ return Promise.resolve({
223
+ Contents: [],
224
+ IsTruncated: false
225
+ });
226
+ });
227
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
228
+ const { result } = renderHook(()=>useInfiniteQuery({
229
+ Bucket: "test-bucket"
230
+ }), {
231
+ wrapper: createQueryWrapper()
232
+ });
233
+ await waitFor(()=>{
234
+ expect(result.current.isSuccess).toBe(true);
235
+ });
236
+ expect(capturedAbortSignal).toBeInstanceOf(AbortSignal);
237
+ expect(capturedAbortSignal?.aborted).toBe(false);
238
+ });
239
+ it("should handle empty result sets correctly", async ()=>{
240
+ const mockEmptyResponse = {
241
+ Contents: [],
242
+ IsTruncated: false
243
+ };
244
+ mockS3Client.send.mockResolvedValue(mockEmptyResponse);
245
+ const useInfiniteQuery = useCreateS3InfiniteQueryHook(MockCommand, "ListObjects");
246
+ const { result } = renderHook(()=>useInfiniteQuery({
247
+ Bucket: "test-bucket"
248
+ }), {
249
+ wrapper: createQueryWrapper()
250
+ });
251
+ await waitFor(()=>{
252
+ expect(result.current.isSuccess).toBe(true);
253
+ });
254
+ const data = result.current.data;
255
+ expect(data?.pages).toHaveLength(1);
256
+ expect(data?.pages?.[0]).toEqual(mockEmptyResponse);
257
+ expect(result.current.hasNextPage).toBe(false);
258
+ });
259
+ });