@scality/data-browser-library 1.0.0-preview.8 → 1.0.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.
- package/dist/components/DataBrowserUI.d.ts +12 -0
- package/dist/components/DataBrowserUI.js +99 -0
- package/dist/components/Editor.d.ts +1 -1
- package/dist/components/Editor.js +3 -3
- package/dist/components/__tests__/BucketAccessor.test.js +214 -0
- package/dist/components/__tests__/BucketCorsPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketCorsPage.test.js +263 -0
- package/dist/components/__tests__/BucketCreate.test.d.ts +1 -0
- package/dist/components/__tests__/BucketCreate.test.js +574 -0
- package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
- package/dist/components/__tests__/BucketDetails.test.js +421 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +14 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.js +618 -0
- package/dist/components/__tests__/BucketLifecycleList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketLifecycleList.test.js +325 -0
- package/dist/components/__tests__/BucketList.test.js +495 -81
- package/dist/components/__tests__/BucketNotificationFormPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketNotificationFormPage.test.js +348 -0
- package/dist/components/__tests__/BucketNotificationList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketNotificationList.test.js +379 -0
- package/dist/components/__tests__/BucketOverview.test.js +484 -179
- package/dist/components/__tests__/BucketPolicyPage.test.js +151 -99
- package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +16 -0
- package/dist/components/__tests__/BucketReplicationFormPage.test.js +1757 -0
- package/dist/components/__tests__/BucketReplicationList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketReplicationList.test.js +344 -0
- package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
- package/dist/components/__tests__/DeleteBucketButton.test.js +64 -64
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +196 -0
- package/dist/components/__tests__/DeleteObjectButton.test.js +64 -64
- package/dist/components/__tests__/EmptyBucketButton.test.d.ts +1 -0
- package/dist/components/__tests__/EmptyBucketButton.test.js +302 -0
- package/dist/components/__tests__/MetadataSearch.test.js +65 -65
- package/dist/components/__tests__/ObjectList.test.js +741 -240
- package/dist/components/__tests__/UploadButton.test.js +45 -45
- package/dist/components/breadcrumb/Breadcrumb.d.ts +6 -0
- package/dist/components/breadcrumb/Breadcrumb.js +37 -0
- package/dist/components/breadcrumb/DataBrowserBreadcrumb.d.ts +1 -0
- package/dist/components/breadcrumb/DataBrowserBreadcrumb.js +10 -0
- package/dist/components/breadcrumb/__tests__/Breadcrumb.test.d.ts +1 -0
- package/dist/components/breadcrumb/__tests__/Breadcrumb.test.js +196 -0
- package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.d.ts +1 -0
- package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.js +153 -0
- package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.d.ts +1 -0
- package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.js +134 -0
- package/dist/components/breadcrumb/index.d.ts +8 -0
- package/dist/components/breadcrumb/index.js +4 -0
- package/dist/components/breadcrumb/useBreadcrumbPaths.d.ts +2 -0
- package/dist/components/breadcrumb/useBreadcrumbPaths.js +82 -0
- package/dist/components/buckets/BucketAccessor.d.ts +2 -0
- package/dist/components/buckets/BucketAccessor.js +125 -0
- package/dist/components/buckets/BucketConfigEditButton.d.ts +8 -0
- package/dist/components/buckets/{BucketPolicyButton.js → BucketConfigEditButton.js} +9 -5
- package/dist/components/buckets/BucketCorsPage.d.ts +1 -0
- package/dist/components/buckets/BucketCorsPage.js +234 -0
- package/dist/components/buckets/BucketCreate.d.ts +50 -0
- package/dist/components/buckets/BucketCreate.js +279 -0
- package/dist/components/buckets/BucketDetails.d.ts +42 -0
- package/dist/components/buckets/BucketDetails.js +256 -40
- package/dist/components/buckets/BucketLifecycleFormPage.d.ts +15 -0
- package/dist/components/buckets/BucketLifecycleFormPage.js +1086 -0
- package/dist/components/buckets/BucketLifecycleList.d.ts +10 -0
- package/dist/components/buckets/BucketLifecycleList.js +270 -0
- package/dist/components/buckets/BucketList.d.ts +6 -4
- package/dist/components/buckets/BucketList.js +161 -94
- package/dist/components/buckets/BucketLocation.js +4 -4
- package/dist/components/buckets/BucketOverview.d.ts +86 -5
- package/dist/components/buckets/BucketOverview.js +481 -192
- package/dist/components/buckets/BucketPage.js +44 -22
- package/dist/components/buckets/BucketPolicyPage.js +155 -127
- package/dist/components/buckets/BucketReplicationFormPage.d.ts +1 -0
- package/dist/components/buckets/BucketReplicationFormPage.js +835 -0
- package/dist/components/buckets/BucketReplicationList.d.ts +11 -0
- package/dist/components/buckets/BucketReplicationList.js +189 -0
- package/dist/components/buckets/BucketVersioning.d.ts +4 -0
- package/dist/components/buckets/BucketVersioning.js +76 -0
- package/dist/components/buckets/DeleteBucketButton.js +8 -8
- package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +18 -0
- package/dist/components/buckets/DeleteBucketConfigRuleButton.js +53 -0
- package/dist/components/buckets/EmptyBucketButton.d.ts +5 -0
- package/dist/components/buckets/EmptyBucketButton.js +232 -0
- package/dist/components/buckets/EmptyBucketSummary.d.ts +9 -0
- package/dist/components/buckets/EmptyBucketSummary.js +60 -0
- package/dist/components/buckets/EmptyBucketSummaryList.d.ts +13 -0
- package/dist/components/buckets/EmptyBucketSummaryList.js +140 -0
- package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
- package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
- package/dist/components/buckets/notifications/BucketNotificationFormPage.d.ts +1 -0
- package/dist/components/buckets/notifications/BucketNotificationFormPage.js +316 -0
- package/dist/components/buckets/notifications/BucketNotificationList.d.ts +10 -0
- package/dist/components/buckets/notifications/BucketNotificationList.js +267 -0
- package/dist/components/buckets/notifications/EventsSection.js +145 -29
- package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
- package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
- package/dist/components/buckets/notifications/events.d.ts +71 -7
- package/dist/components/buckets/notifications/events.js +98 -16
- package/dist/components/index.d.ts +27 -13
- package/dist/components/index.js +20 -6
- package/dist/components/layouts/ArrowNavigation.d.ts +3 -0
- package/dist/components/layouts/ArrowNavigation.js +28 -0
- package/dist/components/layouts/BrowserPageLayout.d.ts +5 -1
- package/dist/components/layouts/BrowserPageLayout.js +10 -5
- package/dist/components/objects/CreateFolderButton.d.ts +2 -2
- package/dist/components/objects/CreateFolderButton.js +12 -12
- package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
- package/dist/components/objects/DeleteObjectButton.js +19 -21
- package/dist/components/objects/GetPresignedUrlButton.d.ts +7 -0
- package/dist/components/objects/GetPresignedUrlButton.js +255 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -2
- package/dist/components/objects/ObjectDetails/ObjectMetadata.js +263 -230
- package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +2 -2
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +540 -138
- package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +2 -2
- package/dist/components/objects/ObjectDetails/ObjectTags.js +95 -123
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +1064 -0
- package/dist/components/objects/ObjectDetails/index.d.ts +18 -2
- package/dist/components/objects/ObjectDetails/index.js +152 -40
- package/dist/components/objects/ObjectList.d.ts +12 -10
- package/dist/components/objects/ObjectList.js +590 -263
- package/dist/components/objects/ObjectLock/EditRetentionButton.d.ts +4 -0
- package/dist/components/objects/ObjectLock/EditRetentionButton.js +32 -0
- package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.d.ts +3 -0
- package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +211 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +9 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettings.js +159 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +8 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +39 -0
- package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.d.ts +1 -0
- package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +204 -0
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.d.ts +1 -0
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +374 -0
- package/dist/components/objects/ObjectPage.js +12 -8
- package/dist/components/objects/UploadButton.d.ts +3 -3
- package/dist/components/objects/UploadButton.js +10 -10
- package/dist/components/objects/__tests__/GetPresignedUrlButton.test.d.ts +1 -0
- package/dist/components/objects/__tests__/GetPresignedUrlButton.test.js +531 -0
- package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
- package/dist/components/providers/DataBrowserProvider.js +60 -38
- package/dist/components/providers/QueryProvider.d.ts +9 -0
- package/dist/components/providers/QueryProvider.js +21 -0
- package/dist/components/search/MetadataSearch.js +29 -28
- package/dist/components/search/SearchHints.js +1 -1
- package/dist/components/ui/ArrayFieldActions.d.ts +36 -0
- package/dist/components/ui/ArrayFieldActions.js +43 -0
- package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +16 -0
- package/dist/components/ui/ConfirmDeleteRuleModal.js +48 -0
- package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
- package/dist/components/ui/DeleteObjectModalContent.js +12 -12
- package/dist/components/ui/FilterFormSection.d.ts +44 -0
- package/dist/components/ui/FilterFormSection.js +159 -0
- package/dist/components/ui/Search.elements.d.ts +2 -2
- package/dist/components/ui/Search.elements.js +7 -7
- package/dist/components/ui/Table.elements.d.ts +2 -1
- package/dist/components/ui/Table.elements.js +18 -12
- package/dist/config/__tests__/factory.test.d.ts +1 -0
- package/dist/config/__tests__/factory.test.js +311 -0
- package/dist/config/factory.d.ts +14 -49
- package/dist/config/factory.js +23 -68
- package/dist/config/types.d.ts +212 -34
- package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
- package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
- package/dist/hooks/__tests__/useAccessibleBuckets.test.d.ts +1 -0
- package/dist/hooks/__tests__/useAccessibleBuckets.test.js +145 -0
- package/dist/hooks/__tests__/useISVBucketDetection.test.d.ts +1 -0
- package/dist/hooks/__tests__/useISVBucketDetection.test.js +188 -0
- package/dist/hooks/__tests__/useIsBucketEmpty.test.js +27 -27
- package/dist/hooks/__tests__/useLoginMutation.test.d.ts +1 -0
- package/dist/hooks/__tests__/useLoginMutation.test.js +194 -0
- package/dist/hooks/bucketConfiguration.d.ts +8 -1
- package/dist/hooks/bucketConfiguration.js +52 -51
- package/dist/hooks/bucketOperations.d.ts +10 -1
- package/dist/hooks/bucketOperations.js +10 -9
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +80 -80
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +80 -80
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +44 -44
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +63 -63
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +95 -52
- package/dist/hooks/factories/index.d.ts +4 -4
- package/dist/hooks/factories/index.js +2 -2
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +16 -13
- package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3LoginHook.js +1 -1
- package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
- package/dist/hooks/factories/useCreateS3MutationHook.js +7 -2
- package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3QueryHook.js +29 -3
- package/dist/hooks/index.d.ts +19 -8
- package/dist/hooks/index.js +16 -5
- package/dist/hooks/loginOperations.d.ts +1 -1
- package/dist/hooks/loginOperations.js +1 -1
- package/dist/hooks/objectOperations.d.ts +2 -2
- package/dist/hooks/objectOperations.js +50 -49
- package/dist/hooks/presignedOperations.d.ts +4 -4
- package/dist/hooks/presignedOperations.js +5 -5
- package/dist/hooks/useAccessibleBuckets.d.ts +11 -0
- package/dist/hooks/useAccessibleBuckets.js +115 -0
- package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
- package/dist/hooks/useBatchObjectLegalHold.js +48 -0
- package/dist/hooks/useBucketConfigEditor.d.ts +31 -0
- package/dist/hooks/useBucketConfigEditor.js +82 -0
- package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
- package/dist/hooks/useDataBrowserNavigate.js +24 -0
- package/dist/hooks/useDeleteBucketConfigRule.d.ts +26 -0
- package/dist/hooks/useDeleteBucketConfigRule.js +46 -0
- package/dist/hooks/useEmptyBucket.d.ts +27 -0
- package/dist/hooks/useEmptyBucket.js +116 -0
- package/dist/hooks/useFeatures.d.ts +7 -0
- package/dist/hooks/useFeatures.js +8 -0
- package/dist/hooks/useISVBucketDetection.d.ts +15 -0
- package/dist/hooks/useISVBucketDetection.js +27 -0
- package/dist/hooks/useIsBucketEmpty.js +4 -4
- package/dist/hooks/useLimitedAccessFlow.d.ts +48 -0
- package/dist/hooks/useLimitedAccessFlow.js +23 -0
- package/dist/hooks/useS3Client.d.ts +6 -0
- package/dist/hooks/useS3Client.js +3 -2
- package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
- package/dist/hooks/useS3ConfigSwitch.js +37 -0
- package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
- package/dist/hooks/useSupportedNotificationEvents.js +8 -0
- package/dist/hooks/useTableRowSelection.d.ts +9 -0
- package/dist/hooks/useTableRowSelection.js +45 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +2 -2
- package/dist/schemas/bucketPolicySchema.json +3 -13
- package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
- package/dist/test/msw/handlers/deleteBucket.js +20 -10
- package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
- package/dist/test/msw/handlers/getBucketAcl.js +29 -17
- package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
- package/dist/test/msw/handlers/getBucketLocation.js +29 -15
- package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
- package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
- package/dist/test/msw/handlers/headObject.d.ts +1 -1
- package/dist/test/msw/handlers/headObject.js +31 -13
- package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
- package/dist/test/msw/handlers/listBuckets.js +5 -3
- package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
- package/dist/test/msw/handlers/listObjectVersions.js +38 -26
- package/dist/test/msw/handlers/listObjects.d.ts +1 -1
- package/dist/test/msw/handlers/listObjects.js +35 -23
- package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
- package/dist/test/msw/handlers/objectLegalHold.js +32 -17
- package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
- package/dist/test/msw/handlers/objectRetention.js +31 -17
- package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
- package/dist/test/msw/handlers/putBucketAcl.js +29 -14
- package/dist/test/msw/handlers/putObject.d.ts +1 -1
- package/dist/test/msw/handlers/putObject.js +27 -12
- package/dist/test/msw/handlers.d.ts +3 -3
- package/dist/test/msw/handlers.js +77 -54
- package/dist/test/msw/index.d.ts +2 -2
- package/dist/test/msw/index.js +1 -1
- package/dist/test/msw/server.d.ts +1 -1
- package/dist/test/msw/server.js +1 -1
- package/dist/test/msw/utils.js +2 -2
- package/dist/test/setup.d.ts +1 -1
- package/dist/test/setup.js +13 -30
- package/dist/test/testUtils.d.ts +170 -36
- package/dist/test/testUtils.js +229 -116
- package/dist/test/utils/errorHandling.test.js +146 -108
- package/dist/types/index.d.ts +49 -36
- package/dist/types/monaco.d.ts +13 -0
- package/dist/types/monaco.js +0 -0
- package/dist/utils/__tests__/proxyMiddleware.test.d.ts +1 -0
- package/dist/utils/__tests__/proxyMiddleware.test.js +579 -0
- package/dist/utils/__tests__/s3Client.test.d.ts +1 -0
- package/dist/utils/__tests__/s3Client.test.js +340 -0
- package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
- package/dist/utils/__tests__/s3ConfigIdentifier.test.js +437 -0
- package/dist/utils/constants.d.ts +22 -0
- package/dist/utils/constants.js +19 -0
- package/dist/utils/deletion/index.d.ts +2 -2
- package/dist/utils/deletion/index.js +1 -1
- package/dist/utils/deletion/messages.d.ts +1 -1
- package/dist/utils/deletion/messages.js +4 -4
- package/dist/utils/errorHandling.d.ts +12 -3
- package/dist/utils/errorHandling.js +12 -7
- package/dist/utils/hooks.js +8 -8
- package/dist/utils/index.d.ts +5 -2
- package/dist/utils/index.js +5 -1
- package/dist/utils/proxyMiddleware.d.ts +32 -13
- package/dist/utils/proxyMiddleware.js +90 -36
- package/dist/utils/s3Client.d.ts +14 -4
- package/dist/utils/s3Client.js +5 -26
- package/dist/utils/s3ConfigIdentifier.d.ts +79 -0
- package/dist/utils/s3ConfigIdentifier.js +57 -0
- package/dist/utils/s3RuleUtils.d.ts +53 -0
- package/dist/utils/s3RuleUtils.js +101 -0
- package/package.json +10 -8
- package/dist/components/__tests__/BucketNotificationCreatePage.test.js +0 -316
- package/dist/components/buckets/BucketPolicyButton.d.ts +0 -7
- package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +0 -1
- package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +0 -234
- package/dist/hooks/useLoginMutation.d.ts +0 -21
- package/dist/hooks/useLoginMutation.js +0 -9
- package/dist/utils/useFeatures.d.ts +0 -1
- package/dist/utils/useFeatures.js +0 -7
- /package/dist/components/__tests__/{BucketNotificationCreatePage.test.d.ts → BucketAccessor.test.d.ts} +0 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
3
|
+
import { MemoryRouter, useNavigate } from "react-router";
|
|
4
|
+
import { useISVBucketStatus } from "../../../../hooks/index.js";
|
|
5
|
+
import { createTestWrapper } from "../../../../test/testUtils.js";
|
|
6
|
+
import { EditRetentionButton } from "../EditRetentionButton.js";
|
|
7
|
+
jest.mock('../../../../hooks');
|
|
8
|
+
jest.mock('react-router', ()=>({
|
|
9
|
+
...jest.requireActual('react-router'),
|
|
10
|
+
useNavigate: jest.fn()
|
|
11
|
+
}));
|
|
12
|
+
const mockUseISVBucketStatus = jest.mocked(useISVBucketStatus);
|
|
13
|
+
const mockUseNavigate = jest.mocked(useNavigate);
|
|
14
|
+
const renderEditRetentionButton = (props = {})=>{
|
|
15
|
+
const Wrapper = createTestWrapper();
|
|
16
|
+
const mockNavigate = jest.fn();
|
|
17
|
+
mockUseNavigate.mockReturnValue(mockNavigate);
|
|
18
|
+
const result = render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
19
|
+
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
20
|
+
children: /*#__PURE__*/ jsx(EditRetentionButton, {
|
|
21
|
+
bucketName: "test-bucket",
|
|
22
|
+
...props
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
}));
|
|
26
|
+
return {
|
|
27
|
+
...result,
|
|
28
|
+
navigate: mockNavigate
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
beforeEach(()=>{
|
|
32
|
+
jest.clearAllMocks();
|
|
33
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
34
|
+
isVeeamBucket: false,
|
|
35
|
+
isCommvaultBucket: false,
|
|
36
|
+
isISVManaged: false,
|
|
37
|
+
isvApplication: void 0,
|
|
38
|
+
isLoading: false,
|
|
39
|
+
bucketTagsStatus: 'success'
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
it('renders edit button', ()=>{
|
|
43
|
+
renderEditRetentionButton();
|
|
44
|
+
const editButton = screen.getByRole('button', {
|
|
45
|
+
name: /edit default retention/i
|
|
46
|
+
});
|
|
47
|
+
expect(editButton).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
it('navigates to object lock settings page when clicked', ()=>{
|
|
50
|
+
const { navigate } = renderEditRetentionButton();
|
|
51
|
+
const editButton = screen.getByRole('button', {
|
|
52
|
+
name: /edit default retention/i
|
|
53
|
+
});
|
|
54
|
+
fireEvent.click(editButton);
|
|
55
|
+
expect(navigate).toHaveBeenCalledWith('/buckets/test-bucket/objects/object-lock-settings');
|
|
56
|
+
});
|
|
57
|
+
it('navigates with correct bucket name', ()=>{
|
|
58
|
+
const { navigate } = renderEditRetentionButton();
|
|
59
|
+
const editButton = screen.getByRole('button', {
|
|
60
|
+
name: /edit default retention/i
|
|
61
|
+
});
|
|
62
|
+
fireEvent.click(editButton);
|
|
63
|
+
expect(navigate).toHaveBeenCalledWith('/buckets/test-bucket/objects/object-lock-settings');
|
|
64
|
+
});
|
|
65
|
+
it('is enabled for regular buckets without ISV tags', ()=>{
|
|
66
|
+
renderEditRetentionButton();
|
|
67
|
+
const editButton = screen.getByRole('button', {
|
|
68
|
+
name: /edit default retention/i
|
|
69
|
+
});
|
|
70
|
+
expect(editButton).not.toBeDisabled();
|
|
71
|
+
});
|
|
72
|
+
it('is disabled for Veeam Backup & Replication buckets', ()=>{
|
|
73
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
74
|
+
isVeeamBucket: true,
|
|
75
|
+
isCommvaultBucket: false,
|
|
76
|
+
isISVManaged: true,
|
|
77
|
+
isvApplication: 'Veeam',
|
|
78
|
+
isLoading: false,
|
|
79
|
+
bucketTagsStatus: 'success'
|
|
80
|
+
});
|
|
81
|
+
renderEditRetentionButton();
|
|
82
|
+
const editButton = screen.getByRole('button', {
|
|
83
|
+
name: /edit default retention/i
|
|
84
|
+
});
|
|
85
|
+
expect(editButton).toBeDisabled();
|
|
86
|
+
});
|
|
87
|
+
it('is disabled for Veeam Office 365 v6/v7 buckets', ()=>{
|
|
88
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
89
|
+
isVeeamBucket: true,
|
|
90
|
+
isCommvaultBucket: false,
|
|
91
|
+
isISVManaged: true,
|
|
92
|
+
isvApplication: 'Veeam',
|
|
93
|
+
isLoading: false,
|
|
94
|
+
bucketTagsStatus: 'success'
|
|
95
|
+
});
|
|
96
|
+
renderEditRetentionButton();
|
|
97
|
+
const editButton = screen.getByRole('button', {
|
|
98
|
+
name: /edit default retention/i
|
|
99
|
+
});
|
|
100
|
+
expect(editButton).toBeDisabled();
|
|
101
|
+
});
|
|
102
|
+
it('is disabled for Veeam Office 365 v8+ buckets', ()=>{
|
|
103
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
104
|
+
isVeeamBucket: true,
|
|
105
|
+
isCommvaultBucket: false,
|
|
106
|
+
isISVManaged: true,
|
|
107
|
+
isvApplication: 'Veeam',
|
|
108
|
+
isLoading: false,
|
|
109
|
+
bucketTagsStatus: 'success'
|
|
110
|
+
});
|
|
111
|
+
renderEditRetentionButton();
|
|
112
|
+
const editButton = screen.getByRole('button', {
|
|
113
|
+
name: /edit default retention/i
|
|
114
|
+
});
|
|
115
|
+
expect(editButton).toBeDisabled();
|
|
116
|
+
});
|
|
117
|
+
it('is disabled for Commvault buckets', ()=>{
|
|
118
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
119
|
+
isVeeamBucket: false,
|
|
120
|
+
isCommvaultBucket: true,
|
|
121
|
+
isISVManaged: true,
|
|
122
|
+
isvApplication: 'Commvault',
|
|
123
|
+
isLoading: false,
|
|
124
|
+
bucketTagsStatus: 'success'
|
|
125
|
+
});
|
|
126
|
+
renderEditRetentionButton();
|
|
127
|
+
const editButton = screen.getByRole('button', {
|
|
128
|
+
name: /edit default retention/i
|
|
129
|
+
});
|
|
130
|
+
expect(editButton).toBeDisabled();
|
|
131
|
+
});
|
|
132
|
+
it('is disabled for ISV buckets tagged as Veeam Backup for Microsoft 365', ()=>{
|
|
133
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
134
|
+
isVeeamBucket: true,
|
|
135
|
+
isCommvaultBucket: false,
|
|
136
|
+
isISVManaged: true,
|
|
137
|
+
isvApplication: 'Veeam',
|
|
138
|
+
isLoading: false,
|
|
139
|
+
bucketTagsStatus: 'success'
|
|
140
|
+
});
|
|
141
|
+
renderEditRetentionButton();
|
|
142
|
+
const editButton = screen.getByRole('button', {
|
|
143
|
+
name: /edit default retention/i
|
|
144
|
+
});
|
|
145
|
+
expect(editButton).toBeDisabled();
|
|
146
|
+
});
|
|
147
|
+
it('is disabled for ISV buckets tagged as Veeam Backup & Replication', ()=>{
|
|
148
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
149
|
+
isVeeamBucket: true,
|
|
150
|
+
isCommvaultBucket: false,
|
|
151
|
+
isISVManaged: true,
|
|
152
|
+
isvApplication: 'Veeam',
|
|
153
|
+
isLoading: false,
|
|
154
|
+
bucketTagsStatus: 'success'
|
|
155
|
+
});
|
|
156
|
+
renderEditRetentionButton();
|
|
157
|
+
const editButton = screen.getByRole('button', {
|
|
158
|
+
name: /edit default retention/i
|
|
159
|
+
});
|
|
160
|
+
expect(editButton).toBeDisabled();
|
|
161
|
+
});
|
|
162
|
+
it('handles missing bucket tags gracefully', ()=>{
|
|
163
|
+
renderEditRetentionButton();
|
|
164
|
+
const editButton = screen.getByRole('button', {
|
|
165
|
+
name: /edit default retention/i
|
|
166
|
+
});
|
|
167
|
+
expect(editButton).not.toBeDisabled();
|
|
168
|
+
});
|
|
169
|
+
it('handles empty TagSet gracefully', ()=>{
|
|
170
|
+
renderEditRetentionButton();
|
|
171
|
+
const editButton = screen.getByRole('button', {
|
|
172
|
+
name: /edit default retention/i
|
|
173
|
+
});
|
|
174
|
+
expect(editButton).not.toBeDisabled();
|
|
175
|
+
});
|
|
176
|
+
it('is enabled for buckets with non-ISV tags', ()=>{
|
|
177
|
+
renderEditRetentionButton();
|
|
178
|
+
const editButton = screen.getByRole('button', {
|
|
179
|
+
name: /edit default retention/i
|
|
180
|
+
});
|
|
181
|
+
expect(editButton).not.toBeDisabled();
|
|
182
|
+
});
|
|
183
|
+
it('handles bucket tagging query error gracefully', ()=>{
|
|
184
|
+
renderEditRetentionButton();
|
|
185
|
+
const editButton = screen.getByRole('button', {
|
|
186
|
+
name: /edit default retention/i
|
|
187
|
+
});
|
|
188
|
+
expect(editButton).not.toBeDisabled();
|
|
189
|
+
});
|
|
190
|
+
it('shows loading state when fetching bucket tags', ()=>{
|
|
191
|
+
mockUseISVBucketStatus.mockReturnValue({
|
|
192
|
+
isVeeamBucket: false,
|
|
193
|
+
isCommvaultBucket: false,
|
|
194
|
+
isISVManaged: false,
|
|
195
|
+
isvApplication: void 0,
|
|
196
|
+
isLoading: true,
|
|
197
|
+
bucketTagsStatus: 'pending'
|
|
198
|
+
});
|
|
199
|
+
renderEditRetentionButton();
|
|
200
|
+
const editButton = screen.getByRole('button', {
|
|
201
|
+
name: /edit default retention/i
|
|
202
|
+
});
|
|
203
|
+
expect(editButton).toBeInTheDocument();
|
|
204
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
3
|
+
import user_event from "@testing-library/user-event";
|
|
4
|
+
import { MemoryRouter, Route, Routes } from "react-router";
|
|
5
|
+
import { useGetBucketObjectLockConfiguration, useSetBucketObjectLockConfiguration } from "../../../../hooks/index.js";
|
|
6
|
+
import { createTestWrapper } from "../../../../test/testUtils.js";
|
|
7
|
+
import { ObjectLockSettings } from "../ObjectLockSettings.js";
|
|
8
|
+
jest.mock('../../../../hooks', ()=>({
|
|
9
|
+
useGetBucketObjectLockConfiguration: jest.fn(),
|
|
10
|
+
useSetBucketObjectLockConfiguration: jest.fn()
|
|
11
|
+
}));
|
|
12
|
+
const mockUseGetBucketObjectLockConfiguration = jest.mocked(useGetBucketObjectLockConfiguration);
|
|
13
|
+
const mockUseSetBucketObjectLockConfiguration = jest.mocked(useSetBucketObjectLockConfiguration);
|
|
14
|
+
const mockNavigate = jest.fn();
|
|
15
|
+
jest.mock('react-router', ()=>({
|
|
16
|
+
...jest.requireActual('react-router'),
|
|
17
|
+
useNavigate: ()=>mockNavigate
|
|
18
|
+
}));
|
|
19
|
+
const renderObjectLockSettings = (bucketName = 'test-bucket')=>{
|
|
20
|
+
const Wrapper = createTestWrapper();
|
|
21
|
+
return render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
22
|
+
initialEntries: [
|
|
23
|
+
`/buckets/${bucketName}/objects/settings`
|
|
24
|
+
],
|
|
25
|
+
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
26
|
+
children: /*#__PURE__*/ jsx(Routes, {
|
|
27
|
+
children: /*#__PURE__*/ jsx(Route, {
|
|
28
|
+
path: "/buckets/:bucketName/objects/settings",
|
|
29
|
+
element: /*#__PURE__*/ jsx(ObjectLockSettings, {})
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
})
|
|
33
|
+
}));
|
|
34
|
+
};
|
|
35
|
+
describe('ObjectLockSettings', ()=>{
|
|
36
|
+
const mockMutate = jest.fn();
|
|
37
|
+
beforeEach(()=>{
|
|
38
|
+
jest.clearAllMocks();
|
|
39
|
+
mockNavigate.mockClear();
|
|
40
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
41
|
+
data: void 0,
|
|
42
|
+
status: 'success'
|
|
43
|
+
});
|
|
44
|
+
mockUseSetBucketObjectLockConfiguration.mockReturnValue({
|
|
45
|
+
mutate: mockMutate,
|
|
46
|
+
isPending: false
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
it('displays loading state while fetching bucket configuration', ()=>{
|
|
50
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
51
|
+
data: void 0,
|
|
52
|
+
status: 'pending'
|
|
53
|
+
});
|
|
54
|
+
renderObjectLockSettings();
|
|
55
|
+
expect(screen.getByText('Loading retention settings...')).toBeInTheDocument();
|
|
56
|
+
});
|
|
57
|
+
it('renders form with Object Lock checkbox', async ()=>{
|
|
58
|
+
renderObjectLockSettings();
|
|
59
|
+
await waitFor(()=>{
|
|
60
|
+
expect(screen.getByText('Object-lock settings')).toBeInTheDocument();
|
|
61
|
+
});
|
|
62
|
+
expect(screen.getByLabelText(/object-lock/i)).toBeInTheDocument();
|
|
63
|
+
});
|
|
64
|
+
it('disables save button when Object Lock is not enabled', async ()=>{
|
|
65
|
+
renderObjectLockSettings();
|
|
66
|
+
await waitFor(()=>{
|
|
67
|
+
const saveButton = screen.getByRole('button', {
|
|
68
|
+
name: /save/i
|
|
69
|
+
});
|
|
70
|
+
expect(saveButton).toBeDisabled();
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
it('shows Default Retention fields when Object Lock is enabled', async ()=>{
|
|
74
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
75
|
+
data: {
|
|
76
|
+
ObjectLockConfiguration: {
|
|
77
|
+
ObjectLockEnabled: 'Enabled'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
status: 'success'
|
|
81
|
+
});
|
|
82
|
+
renderObjectLockSettings();
|
|
83
|
+
await waitFor(()=>{
|
|
84
|
+
expect(screen.getByText('Default Retention')).toBeInTheDocument();
|
|
85
|
+
expect(screen.getByText('Retention mode')).toBeInTheDocument();
|
|
86
|
+
expect(screen.getByText('Retention period')).toBeInTheDocument();
|
|
87
|
+
}, {
|
|
88
|
+
timeout: 3000
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
it('enables save button when Object Lock is enabled', async ()=>{
|
|
92
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
93
|
+
data: {
|
|
94
|
+
ObjectLockConfiguration: {
|
|
95
|
+
ObjectLockEnabled: 'Enabled'
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
status: 'success'
|
|
99
|
+
});
|
|
100
|
+
renderObjectLockSettings();
|
|
101
|
+
await waitFor(()=>{
|
|
102
|
+
const saveButton = screen.getByRole('button', {
|
|
103
|
+
name: /save/i
|
|
104
|
+
});
|
|
105
|
+
expect(saveButton).toBeEnabled();
|
|
106
|
+
}, {
|
|
107
|
+
timeout: 3000
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
it('enables retention fields when Default Retention is checked', async ()=>{
|
|
111
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
112
|
+
data: {
|
|
113
|
+
ObjectLockConfiguration: {
|
|
114
|
+
ObjectLockEnabled: 'Enabled'
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
status: 'success'
|
|
118
|
+
});
|
|
119
|
+
renderObjectLockSettings();
|
|
120
|
+
await waitFor(()=>{
|
|
121
|
+
expect(screen.getByText('Default Retention')).toBeInTheDocument();
|
|
122
|
+
});
|
|
123
|
+
const defaultRetentionCheckbox = screen.getByLabelText(/default retention/i);
|
|
124
|
+
expect(defaultRetentionCheckbox).not.toBeChecked();
|
|
125
|
+
fireEvent.click(defaultRetentionCheckbox);
|
|
126
|
+
await waitFor(()=>{
|
|
127
|
+
const governanceRadio = screen.getByLabelText(/governance/i);
|
|
128
|
+
expect(governanceRadio).not.toBeDisabled();
|
|
129
|
+
}, {
|
|
130
|
+
timeout: 3000
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
it('disables retention fields when Default Retention is unchecked', async ()=>{
|
|
134
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
135
|
+
data: {
|
|
136
|
+
ObjectLockConfiguration: {
|
|
137
|
+
ObjectLockEnabled: 'Enabled',
|
|
138
|
+
Rule: {
|
|
139
|
+
DefaultRetention: {
|
|
140
|
+
Mode: 'GOVERNANCE',
|
|
141
|
+
Days: 30
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
status: 'success'
|
|
147
|
+
});
|
|
148
|
+
renderObjectLockSettings();
|
|
149
|
+
await waitFor(()=>{
|
|
150
|
+
const defaultRetentionCheckbox = screen.getByLabelText(/default retention/i);
|
|
151
|
+
fireEvent.click(defaultRetentionCheckbox);
|
|
152
|
+
});
|
|
153
|
+
await waitFor(()=>{
|
|
154
|
+
const governanceRadio = screen.getByLabelText(/governance/i);
|
|
155
|
+
expect(governanceRadio).toBeDisabled();
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
it('shows validation error when retention period is invalid', async ()=>{
|
|
159
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
160
|
+
data: {
|
|
161
|
+
ObjectLockConfiguration: {
|
|
162
|
+
ObjectLockEnabled: 'Enabled'
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
status: 'success'
|
|
166
|
+
});
|
|
167
|
+
renderObjectLockSettings();
|
|
168
|
+
await waitFor(()=>{
|
|
169
|
+
expect(screen.getByText('Default Retention')).toBeInTheDocument();
|
|
170
|
+
});
|
|
171
|
+
const defaultRetentionCheckbox = screen.getByLabelText(/default retention/i);
|
|
172
|
+
fireEvent.click(defaultRetentionCheckbox);
|
|
173
|
+
await waitFor(()=>{
|
|
174
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
175
|
+
expect(retentionPeriodInput).toBeInTheDocument();
|
|
176
|
+
});
|
|
177
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
178
|
+
await user_event.clear(retentionPeriodInput);
|
|
179
|
+
await user_event.type(retentionPeriodInput, '0');
|
|
180
|
+
await waitFor(()=>{
|
|
181
|
+
const saveButton = screen.getByRole('button', {
|
|
182
|
+
name: /save/i
|
|
183
|
+
});
|
|
184
|
+
expect(saveButton).toBeDisabled();
|
|
185
|
+
}, {
|
|
186
|
+
timeout: 3000
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
it('saves Object Lock configuration with Default Retention and navigates on success', async ()=>{
|
|
190
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
191
|
+
data: {
|
|
192
|
+
ObjectLockConfiguration: {
|
|
193
|
+
ObjectLockEnabled: 'Enabled'
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
status: 'success'
|
|
197
|
+
});
|
|
198
|
+
renderObjectLockSettings();
|
|
199
|
+
await waitFor(()=>{
|
|
200
|
+
expect(screen.getByText('Default Retention')).toBeInTheDocument();
|
|
201
|
+
});
|
|
202
|
+
const defaultRetentionCheckbox = screen.getByLabelText(/default retention/i);
|
|
203
|
+
fireEvent.click(defaultRetentionCheckbox);
|
|
204
|
+
await waitFor(()=>{
|
|
205
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
206
|
+
expect(retentionPeriodInput).toBeInTheDocument();
|
|
207
|
+
});
|
|
208
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
209
|
+
await user_event.clear(retentionPeriodInput);
|
|
210
|
+
await user_event.type(retentionPeriodInput, '30');
|
|
211
|
+
const governanceRadio = screen.getByLabelText(/governance/i);
|
|
212
|
+
fireEvent.click(governanceRadio);
|
|
213
|
+
mockMutate.mockImplementation((_, options)=>{
|
|
214
|
+
options?.onSuccess?.();
|
|
215
|
+
});
|
|
216
|
+
const saveButton = screen.getByRole('button', {
|
|
217
|
+
name: /save/i
|
|
218
|
+
});
|
|
219
|
+
await waitFor(()=>expect(saveButton).toBeEnabled(), {
|
|
220
|
+
timeout: 3000
|
|
221
|
+
});
|
|
222
|
+
fireEvent.click(saveButton);
|
|
223
|
+
await waitFor(()=>{
|
|
224
|
+
expect(mockMutate).toHaveBeenCalled();
|
|
225
|
+
const callArgs = mockMutate.mock.calls[0][0];
|
|
226
|
+
expect(callArgs.Bucket).toBe('test-bucket');
|
|
227
|
+
expect(callArgs.ObjectLockConfiguration.ObjectLockEnabled).toBe('Enabled');
|
|
228
|
+
expect(callArgs.ObjectLockConfiguration.Rule.DefaultRetention.Mode).toBe('GOVERNANCE');
|
|
229
|
+
expect(callArgs.ObjectLockConfiguration.Rule.DefaultRetention.Days || callArgs.ObjectLockConfiguration.Rule.DefaultRetention.Years).toBe(30);
|
|
230
|
+
expect(mockNavigate).toHaveBeenCalledWith('/buckets/test-bucket');
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
it('saves Object Lock configuration with Years frequency', async ()=>{
|
|
234
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
235
|
+
data: {
|
|
236
|
+
ObjectLockConfiguration: {
|
|
237
|
+
ObjectLockEnabled: 'Enabled'
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
status: 'success'
|
|
241
|
+
});
|
|
242
|
+
renderObjectLockSettings();
|
|
243
|
+
await waitFor(()=>{
|
|
244
|
+
expect(screen.getByText('Default Retention')).toBeInTheDocument();
|
|
245
|
+
});
|
|
246
|
+
const defaultRetentionCheckbox = screen.getByLabelText(/default retention/i);
|
|
247
|
+
fireEvent.click(defaultRetentionCheckbox);
|
|
248
|
+
await waitFor(()=>{
|
|
249
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
250
|
+
expect(retentionPeriodInput).toBeInTheDocument();
|
|
251
|
+
});
|
|
252
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
253
|
+
await user_event.clear(retentionPeriodInput);
|
|
254
|
+
await user_event.type(retentionPeriodInput, '2');
|
|
255
|
+
mockMutate.mockImplementation((_, options)=>{
|
|
256
|
+
options?.onSuccess?.();
|
|
257
|
+
});
|
|
258
|
+
const saveButton = screen.getByRole('button', {
|
|
259
|
+
name: /save/i
|
|
260
|
+
});
|
|
261
|
+
await waitFor(()=>expect(saveButton).toBeEnabled(), {
|
|
262
|
+
timeout: 3000
|
|
263
|
+
});
|
|
264
|
+
fireEvent.click(saveButton);
|
|
265
|
+
await waitFor(()=>{
|
|
266
|
+
expect(mockMutate).toHaveBeenCalled();
|
|
267
|
+
const callArgs = mockMutate.mock.calls[0][0];
|
|
268
|
+
expect(callArgs.Bucket).toBe('test-bucket');
|
|
269
|
+
expect(callArgs.ObjectLockConfiguration.ObjectLockEnabled).toBe('Enabled');
|
|
270
|
+
expect(callArgs.ObjectLockConfiguration.Rule.DefaultRetention.Mode).toBe('GOVERNANCE');
|
|
271
|
+
expect(callArgs.ObjectLockConfiguration.Rule.DefaultRetention.Days || callArgs.ObjectLockConfiguration.Rule.DefaultRetention.Years).toBe(2);
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
it('saves Object Lock configuration without Default Retention', async ()=>{
|
|
275
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
276
|
+
data: {
|
|
277
|
+
ObjectLockConfiguration: {
|
|
278
|
+
ObjectLockEnabled: 'Enabled'
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
status: 'success'
|
|
282
|
+
});
|
|
283
|
+
renderObjectLockSettings();
|
|
284
|
+
await waitFor(()=>{
|
|
285
|
+
const saveButton = screen.getByRole('button', {
|
|
286
|
+
name: /save/i
|
|
287
|
+
});
|
|
288
|
+
expect(saveButton).toBeEnabled();
|
|
289
|
+
}, {
|
|
290
|
+
timeout: 3000
|
|
291
|
+
});
|
|
292
|
+
mockMutate.mockImplementation((_, options)=>{
|
|
293
|
+
options?.onSuccess?.();
|
|
294
|
+
});
|
|
295
|
+
const saveButton = screen.getByRole('button', {
|
|
296
|
+
name: /save/i
|
|
297
|
+
});
|
|
298
|
+
fireEvent.click(saveButton);
|
|
299
|
+
await waitFor(()=>{
|
|
300
|
+
expect(mockMutate).toHaveBeenCalled();
|
|
301
|
+
const callArgs = mockMutate.mock.calls[0][0];
|
|
302
|
+
expect(callArgs.Bucket).toBe('test-bucket');
|
|
303
|
+
expect(callArgs.ObjectLockConfiguration.ObjectLockEnabled).toBe('Enabled');
|
|
304
|
+
expect(callArgs.ObjectLockConfiguration.Rule).toBeUndefined();
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
it('displays error toast when save fails', async ()=>{
|
|
308
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
309
|
+
data: {
|
|
310
|
+
ObjectLockConfiguration: {
|
|
311
|
+
ObjectLockEnabled: 'Enabled'
|
|
312
|
+
}
|
|
313
|
+
},
|
|
314
|
+
status: 'success'
|
|
315
|
+
});
|
|
316
|
+
renderObjectLockSettings();
|
|
317
|
+
await waitFor(()=>{
|
|
318
|
+
const saveButton = screen.getByRole('button', {
|
|
319
|
+
name: /save/i
|
|
320
|
+
});
|
|
321
|
+
expect(saveButton).toBeEnabled();
|
|
322
|
+
}, {
|
|
323
|
+
timeout: 3000
|
|
324
|
+
});
|
|
325
|
+
const error = new Error('Access Denied');
|
|
326
|
+
mockMutate.mockImplementation((_, options)=>{
|
|
327
|
+
options?.onError?.(error);
|
|
328
|
+
});
|
|
329
|
+
const saveButton = screen.getByRole('button', {
|
|
330
|
+
name: /save/i
|
|
331
|
+
});
|
|
332
|
+
fireEvent.click(saveButton);
|
|
333
|
+
await waitFor(()=>{
|
|
334
|
+
expect(mockNavigate).not.toHaveBeenCalled();
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
it('navigates back when cancel button is clicked', async ()=>{
|
|
338
|
+
renderObjectLockSettings();
|
|
339
|
+
await waitFor(()=>{
|
|
340
|
+
const cancelButton = screen.getByRole('button', {
|
|
341
|
+
name: /cancel/i
|
|
342
|
+
});
|
|
343
|
+
fireEvent.click(cancelButton);
|
|
344
|
+
});
|
|
345
|
+
expect(mockNavigate).toHaveBeenCalledWith('/buckets/test-bucket');
|
|
346
|
+
});
|
|
347
|
+
it('populates form with existing bucket configuration', async ()=>{
|
|
348
|
+
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
349
|
+
data: {
|
|
350
|
+
ObjectLockConfiguration: {
|
|
351
|
+
ObjectLockEnabled: 'Enabled',
|
|
352
|
+
Rule: {
|
|
353
|
+
DefaultRetention: {
|
|
354
|
+
Mode: 'COMPLIANCE',
|
|
355
|
+
Days: 60
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
status: 'success'
|
|
361
|
+
});
|
|
362
|
+
renderObjectLockSettings();
|
|
363
|
+
await waitFor(()=>{
|
|
364
|
+
const objectLockCheckbox = screen.getByLabelText(/object-lock/i);
|
|
365
|
+
expect(objectLockCheckbox).toBeChecked();
|
|
366
|
+
});
|
|
367
|
+
const defaultRetentionCheckbox = screen.getByLabelText(/default retention/i);
|
|
368
|
+
expect(defaultRetentionCheckbox).toBeChecked();
|
|
369
|
+
const complianceRadio = screen.getByLabelText(/compliance/i);
|
|
370
|
+
expect(complianceRadio).toBeChecked();
|
|
371
|
+
const retentionPeriodInput = screen.getByLabelText(/retention period/i);
|
|
372
|
+
expect(retentionPeriodInput).toHaveValue(60);
|
|
373
|
+
});
|
|
374
|
+
});
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
|
3
2
|
import { useCallback, useState } from "react";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { useParams, useSearchParams } from "react-router";
|
|
4
|
+
import { useDataBrowserNavigate } from "../../hooks/useDataBrowserNavigate.js";
|
|
6
5
|
import { BrowserPageLayout } from "../layouts/BrowserPageLayout.js";
|
|
6
|
+
import { ObjectDetails } from "./ObjectDetails/index.js";
|
|
7
|
+
import { ObjectList } from "./ObjectList.js";
|
|
7
8
|
const ObjectPage = ()=>{
|
|
8
9
|
const { bucketName } = useParams();
|
|
9
|
-
const navigate =
|
|
10
|
+
const navigate = useDataBrowserNavigate();
|
|
10
11
|
const [searchParams] = useSearchParams();
|
|
11
12
|
const [item, setItem] = useState(null);
|
|
12
|
-
const prefix = searchParams.get(
|
|
13
|
+
const prefix = searchParams.get('prefix') || '';
|
|
13
14
|
const handlePrefixChange = useCallback((newPrefix)=>{
|
|
14
15
|
const newSearchParams = new URLSearchParams(searchParams);
|
|
15
|
-
newSearchParams.set(
|
|
16
|
+
newSearchParams.set('prefix', newPrefix);
|
|
16
17
|
setItem(null);
|
|
17
18
|
navigate(`?${newSearchParams.toString()}`, {
|
|
18
19
|
replace: true
|
|
@@ -28,6 +29,7 @@ const ObjectPage = ()=>{
|
|
|
28
29
|
setItem(object);
|
|
29
30
|
};
|
|
30
31
|
return /*#__PURE__*/ jsx(BrowserPageLayout, {
|
|
32
|
+
iconName: "Bucket",
|
|
31
33
|
title: bucketName,
|
|
32
34
|
leftPanel: /*#__PURE__*/ jsx(ObjectList, {
|
|
33
35
|
bucketName: bucketName,
|
|
@@ -35,9 +37,11 @@ const ObjectPage = ()=>{
|
|
|
35
37
|
onObjectSelect: handleObjectSelect,
|
|
36
38
|
onPrefixChange: handlePrefixChange
|
|
37
39
|
}),
|
|
38
|
-
rightPanel:
|
|
40
|
+
rightPanel: /*#__PURE__*/ jsx(ObjectDetails, {
|
|
39
41
|
item: item
|
|
40
|
-
})
|
|
42
|
+
}),
|
|
43
|
+
withArrowNavigation: true,
|
|
44
|
+
arrowNavigationPath: `/buckets/${bucketName}`
|
|
41
45
|
});
|
|
42
46
|
};
|
|
43
47
|
export { ObjectPage };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type
|
|
1
|
+
import type { PutObjectCommandInput } from '@aws-sdk/client-s3';
|
|
2
|
+
import type React from 'react';
|
|
3
3
|
interface UploadButtonProps {
|
|
4
4
|
/**
|
|
5
5
|
* The S3 bucket name where files will be uploaded
|
|
@@ -16,7 +16,7 @@ interface UploadButtonProps {
|
|
|
16
16
|
/**
|
|
17
17
|
* Button variant
|
|
18
18
|
*/
|
|
19
|
-
variant?:
|
|
19
|
+
variant?: 'primary' | 'secondary' | 'outline';
|
|
20
20
|
/**
|
|
21
21
|
* Upload options to configure metadata, encryption, etc.
|
|
22
22
|
*/
|