@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,415 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { fireEvent, render, screen } from "@testing-library/react";
3
+ import { MemoryRouter } from "react-router";
4
+ import { createTestWrapper, mockOffsetSize } from "../../test/testUtils.js";
5
+ import { BucketList } from "../buckets/BucketList.js";
6
+ const renderBucketList = (props = {})=>{
7
+ const Wrapper = createTestWrapper();
8
+ return render(/*#__PURE__*/ jsx(MemoryRouter, {
9
+ children: /*#__PURE__*/ jsx(Wrapper, {
10
+ children: /*#__PURE__*/ jsx(BucketList, {
11
+ buckets: [],
12
+ ...props
13
+ })
14
+ })
15
+ }));
16
+ };
17
+ const mockBuckets = [
18
+ {
19
+ Name: "test-bucket-1",
20
+ CreationDate: new Date("2024-01-15T10:30:00Z")
21
+ },
22
+ {
23
+ Name: "test-bucket-2",
24
+ CreationDate: new Date("2024-01-16T14:45:00Z")
25
+ },
26
+ {
27
+ Name: "test-bucket-3",
28
+ CreationDate: new Date("2024-01-17T09:15:00Z")
29
+ }
30
+ ];
31
+ describe("BucketList", ()=>{
32
+ beforeEach(()=>{
33
+ jest.clearAllMocks();
34
+ mockOffsetSize(800, 600);
35
+ });
36
+ it("shows a table with proper headers", ()=>{
37
+ renderBucketList({
38
+ buckets: mockBuckets
39
+ });
40
+ expect(screen.getByRole("grid")).toBeInTheDocument();
41
+ expect(screen.getByText("Bucket Name")).toBeInTheDocument();
42
+ expect(screen.getByText("Storage Location")).toBeInTheDocument();
43
+ expect(screen.getByText("Created on")).toBeInTheDocument();
44
+ });
45
+ it("displays buckets with their names as clickable links", ()=>{
46
+ const onNavigateToBucket = jest.fn();
47
+ renderBucketList({
48
+ buckets: mockBuckets,
49
+ onNavigateToBucket
50
+ });
51
+ expect(screen.getByText("test-bucket-1")).toBeInTheDocument();
52
+ expect(screen.getByText("test-bucket-2")).toBeInTheDocument();
53
+ expect(screen.getByText("test-bucket-3")).toBeInTheDocument();
54
+ fireEvent.click(screen.getByText("test-bucket-1"));
55
+ expect(onNavigateToBucket).toHaveBeenCalledWith("test-bucket-1");
56
+ });
57
+ it("displays creation dates in formatted format", ()=>{
58
+ renderBucketList({
59
+ buckets: mockBuckets
60
+ });
61
+ const gridElement = screen.getByRole("grid");
62
+ expect(gridElement).toHaveTextContent("2024");
63
+ const dateElements = screen.getAllByText(/2024/);
64
+ expect(dateElements.length).toBeGreaterThanOrEqual(3);
65
+ });
66
+ it("shows storage location when renderBucketLocation is provided", ()=>{
67
+ const renderBucketLocation = jest.fn((bucketName)=>/*#__PURE__*/ jsxs("span", {
68
+ children: [
69
+ "Location for ",
70
+ bucketName
71
+ ]
72
+ }));
73
+ renderBucketList({
74
+ buckets: mockBuckets,
75
+ renderBucketLocation
76
+ });
77
+ expect(renderBucketLocation).toHaveBeenCalledWith("test-bucket-1");
78
+ expect(renderBucketLocation).toHaveBeenCalledWith("test-bucket-2");
79
+ expect(renderBucketLocation).toHaveBeenCalledWith("test-bucket-3");
80
+ });
81
+ it("shows dash for storage location when renderBucketLocation is not provided", ()=>{
82
+ renderBucketList({
83
+ buckets: mockBuckets
84
+ });
85
+ const dashes = screen.getAllByText("-");
86
+ expect(dashes.length).toBeGreaterThan(0);
87
+ });
88
+ it("handles bucket selection when onBucketSelect is provided", ()=>{
89
+ const onBucketSelect = jest.fn();
90
+ renderBucketList({
91
+ buckets: mockBuckets,
92
+ onBucketSelect
93
+ });
94
+ const rows = screen.getAllByRole("row");
95
+ fireEvent.click(rows[1]);
96
+ expect(onBucketSelect).toHaveBeenCalledWith("test-bucket-3");
97
+ });
98
+ it("shows selected bucket when selectedBucketName is provided", ()=>{
99
+ renderBucketList({
100
+ buckets: mockBuckets,
101
+ selectedBucketName: "test-bucket-2"
102
+ });
103
+ const selectedRow = screen.getByRole("row", {
104
+ name: /test-bucket-2/
105
+ });
106
+ expect(selectedRow).toHaveAttribute("aria-selected", "true");
107
+ });
108
+ it("handles create bucket button click", ()=>{
109
+ const onCreateBucket = jest.fn();
110
+ renderBucketList({
111
+ buckets: mockBuckets,
112
+ onCreateBucket
113
+ });
114
+ const createButton = screen.getByRole("button", {
115
+ name: /create bucket/i
116
+ });
117
+ expect(createButton).toBeInTheDocument();
118
+ fireEvent.click(createButton);
119
+ expect(onCreateBucket).toHaveBeenCalled();
120
+ });
121
+ it("shows search functionality", ()=>{
122
+ renderBucketList({
123
+ buckets: mockBuckets
124
+ });
125
+ const searchInput = screen.getByRole("searchbox");
126
+ expect(searchInput).toBeInTheDocument();
127
+ expect(searchInput).toHaveAttribute("placeholder", "Example: Search");
128
+ });
129
+ it("handles empty buckets list", ()=>{
130
+ renderBucketList({
131
+ buckets: []
132
+ });
133
+ expect(screen.getByRole("grid")).toBeInTheDocument();
134
+ expect(screen.getByText("Bucket Name")).toBeInTheDocument();
135
+ });
136
+ it("handles buckets without names gracefully", ()=>{
137
+ const bucketsWithMissingNames = [
138
+ {
139
+ Name: void 0,
140
+ CreationDate: new Date()
141
+ },
142
+ {
143
+ Name: "",
144
+ CreationDate: new Date()
145
+ },
146
+ {
147
+ Name: "valid-bucket",
148
+ CreationDate: new Date()
149
+ }
150
+ ];
151
+ renderBucketList({
152
+ buckets: bucketsWithMissingNames
153
+ });
154
+ expect(screen.getByText("valid-bucket")).toBeInTheDocument();
155
+ const dashes = screen.getAllByText("-");
156
+ expect(dashes.length).toBeGreaterThan(0);
157
+ });
158
+ it("handles buckets without creation dates", ()=>{
159
+ const bucketsWithoutDates = [
160
+ {
161
+ Name: "bucket-1",
162
+ CreationDate: void 0
163
+ },
164
+ {
165
+ Name: "bucket-2"
166
+ }
167
+ ];
168
+ renderBucketList({
169
+ buckets: bucketsWithoutDates
170
+ });
171
+ expect(screen.getByText("bucket-1")).toBeInTheDocument();
172
+ expect(screen.getByText("bucket-2")).toBeInTheDocument();
173
+ });
174
+ it("works when no callbacks are provided", ()=>{
175
+ renderBucketList({
176
+ buckets: mockBuckets
177
+ });
178
+ expect(()=>{
179
+ fireEvent.click(screen.getByText("test-bucket-1"));
180
+ const createButton = screen.getByRole("button", {
181
+ name: /create bucket/i
182
+ });
183
+ fireEvent.click(createButton);
184
+ }).not.toThrow();
185
+ });
186
+ it("handles different bucket statuses", ()=>{
187
+ expect(()=>{
188
+ renderBucketList({
189
+ buckets: mockBuckets,
190
+ bucketStatus: "loading"
191
+ });
192
+ renderBucketList({
193
+ buckets: mockBuckets,
194
+ bucketStatus: "error"
195
+ });
196
+ renderBucketList({
197
+ buckets: mockBuckets,
198
+ bucketStatus: "success"
199
+ });
200
+ }).not.toThrow();
201
+ });
202
+ it("prevents event propagation when clicking bucket name link", ()=>{
203
+ const onNavigateToBucket = jest.fn();
204
+ const onBucketSelect = jest.fn();
205
+ renderBucketList({
206
+ buckets: mockBuckets,
207
+ onNavigateToBucket,
208
+ onBucketSelect
209
+ });
210
+ fireEvent.click(screen.getByText("test-bucket-1"));
211
+ expect(onNavigateToBucket).toHaveBeenCalledWith("test-bucket-1");
212
+ expect(onBucketSelect).not.toHaveBeenCalled();
213
+ });
214
+ it("does not select already selected bucket", ()=>{
215
+ const onBucketSelect = jest.fn();
216
+ renderBucketList({
217
+ buckets: mockBuckets,
218
+ selectedBucketName: "test-bucket-1",
219
+ onBucketSelect
220
+ });
221
+ const bucketName = screen.getByText("test-bucket-1");
222
+ fireEvent.click(bucketName.closest('[role="row"]') || bucketName);
223
+ expect(onBucketSelect).not.toHaveBeenCalled();
224
+ });
225
+ describe("additionalColumns support", ()=>{
226
+ it("renders additional columns when additionalColumns prop is provided", ()=>{
227
+ const additionalColumns = [
228
+ {
229
+ Header: "Metrics",
230
+ accessor: "metrics",
231
+ id: "metrics",
232
+ Cell: ()=>/*#__PURE__*/ jsx("span", {
233
+ children: "Metrics Data"
234
+ })
235
+ }
236
+ ];
237
+ renderBucketList({
238
+ buckets: mockBuckets,
239
+ additionalColumns
240
+ });
241
+ expect(screen.getByText("Metrics")).toBeInTheDocument();
242
+ expect(screen.getAllByText("Metrics Data")).toHaveLength(3);
243
+ });
244
+ it("renders multiple additional columns in correct order", ()=>{
245
+ const additionalColumns = [
246
+ {
247
+ Header: "Column A",
248
+ accessor: "columnA",
249
+ id: "columnA",
250
+ Cell: ()=>/*#__PURE__*/ jsx("span", {
251
+ children: "A"
252
+ })
253
+ },
254
+ {
255
+ Header: "Column B",
256
+ accessor: "columnB",
257
+ id: "columnB",
258
+ Cell: ()=>/*#__PURE__*/ jsx("span", {
259
+ children: "B"
260
+ })
261
+ }
262
+ ];
263
+ renderBucketList({
264
+ buckets: mockBuckets,
265
+ additionalColumns
266
+ });
267
+ const headers = screen.getAllByRole("columnheader");
268
+ const headerTexts = headers.map((h)=>h.textContent);
269
+ expect(headerTexts).toContain("Bucket Name");
270
+ expect(headerTexts).toContain("Storage Location");
271
+ expect(headerTexts).toContain("Column A");
272
+ expect(headerTexts).toContain("Column B");
273
+ expect(headerTexts).toContain("Created on");
274
+ const bucketNameIndex = headerTexts.indexOf("Bucket Name");
275
+ const storageLocationIndex = headerTexts.indexOf("Storage Location");
276
+ const columnAIndex = headerTexts.indexOf("Column A");
277
+ const columnBIndex = headerTexts.indexOf("Column B");
278
+ const createdOnIndex = headerTexts.indexOf("Created on");
279
+ expect(bucketNameIndex).toBeLessThan(storageLocationIndex);
280
+ expect(storageLocationIndex).toBeLessThan(columnAIndex);
281
+ expect(columnAIndex).toBeLessThan(columnBIndex);
282
+ expect(columnBIndex).toBeLessThan(createdOnIndex);
283
+ });
284
+ it("works without additional columns (backward compatibility)", ()=>{
285
+ renderBucketList({
286
+ buckets: mockBuckets
287
+ });
288
+ const headers = screen.getAllByRole("columnheader");
289
+ const headerTexts = headers.map((h)=>h.textContent);
290
+ expect(headerTexts).toContain("Bucket Name");
291
+ expect(headerTexts).toContain("Storage Location");
292
+ expect(headerTexts).toContain("Created on");
293
+ expect(headerTexts).toHaveLength(3);
294
+ });
295
+ });
296
+ describe("transformBucketData support", ()=>{
297
+ it("transforms bucket data when transformBucketData is provided", ()=>{
298
+ const transformBucketData = jest.fn((bucket)=>({
299
+ ...bucket,
300
+ metrics: {
301
+ value: 100
302
+ }
303
+ }));
304
+ const additionalColumns = [
305
+ {
306
+ Header: "Metrics",
307
+ accessor: "metrics",
308
+ id: "metrics",
309
+ Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
310
+ children: [
311
+ "Value: ",
312
+ value.value
313
+ ]
314
+ })
315
+ }
316
+ ];
317
+ renderBucketList({
318
+ buckets: mockBuckets,
319
+ additionalColumns,
320
+ transformBucketData
321
+ });
322
+ expect(transformBucketData).toHaveBeenCalledTimes(3);
323
+ expect(transformBucketData).toHaveBeenCalledWith(mockBuckets[0]);
324
+ expect(transformBucketData).toHaveBeenCalledWith(mockBuckets[1]);
325
+ expect(transformBucketData).toHaveBeenCalledWith(mockBuckets[2]);
326
+ });
327
+ it("renders transformed data in additional columns", ()=>{
328
+ const transformBucketData = (bucket)=>({
329
+ ...bucket,
330
+ metrics: {
331
+ value: "test-bucket-1" === bucket.Name ? 50 : 100
332
+ }
333
+ });
334
+ const additionalColumns = [
335
+ {
336
+ Header: "Metrics",
337
+ accessor: "metrics",
338
+ id: "metrics",
339
+ Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
340
+ children: [
341
+ "Metric: ",
342
+ value.value
343
+ ]
344
+ })
345
+ }
346
+ ];
347
+ renderBucketList({
348
+ buckets: mockBuckets,
349
+ additionalColumns,
350
+ transformBucketData
351
+ });
352
+ expect(screen.getByText("Metric: 50")).toBeInTheDocument();
353
+ expect(screen.getAllByText("Metric: 100")).toHaveLength(2);
354
+ });
355
+ it("works without transformBucketData (uses default behavior)", ()=>{
356
+ const additionalColumns = [
357
+ {
358
+ Header: "Test Column",
359
+ accessor: "Name",
360
+ id: "testColumn",
361
+ Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
362
+ children: [
363
+ "Name: ",
364
+ value
365
+ ]
366
+ })
367
+ }
368
+ ];
369
+ renderBucketList({
370
+ buckets: mockBuckets,
371
+ additionalColumns
372
+ });
373
+ expect(screen.getByText("Name: test-bucket-1")).toBeInTheDocument();
374
+ expect(screen.getByText("Name: test-bucket-2")).toBeInTheDocument();
375
+ expect(screen.getByText("Name: test-bucket-3")).toBeInTheDocument();
376
+ });
377
+ });
378
+ describe("generic type support", ()=>{
379
+ it("maintains type safety with extended bucket types", ()=>{
380
+ const transformBucketData = (bucket)=>({
381
+ ...bucket,
382
+ customField: `Custom ${bucket.Name}`,
383
+ numericField: 42
384
+ });
385
+ const additionalColumns = [
386
+ {
387
+ Header: "Custom",
388
+ accessor: "customField",
389
+ id: "custom",
390
+ Cell: ({ value })=>/*#__PURE__*/ jsx("span", {
391
+ children: value
392
+ })
393
+ },
394
+ {
395
+ Header: "Number",
396
+ accessor: "numericField",
397
+ id: "numeric",
398
+ Cell: ({ value })=>/*#__PURE__*/ jsxs("span", {
399
+ children: [
400
+ "Num: ",
401
+ value
402
+ ]
403
+ })
404
+ }
405
+ ];
406
+ renderBucketList({
407
+ buckets: mockBuckets,
408
+ additionalColumns,
409
+ transformBucketData
410
+ });
411
+ expect(screen.getByText("Custom test-bucket-1")).toBeInTheDocument();
412
+ expect(screen.getAllByText("Num: 42")).toHaveLength(3);
413
+ });
414
+ });
415
+ });