@scality/data-browser-library 1.0.0-preview.13 → 1.0.0-preview.16
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 +6 -14
- package/dist/components/DataBrowserUI.js +79 -55
- package/dist/components/Editor.d.ts +1 -1
- package/dist/components/Editor.js +3 -3
- package/dist/components/__tests__/BucketCreate.test.js +102 -102
- package/dist/components/__tests__/BucketDetails.test.js +122 -123
- package/dist/components/__tests__/BucketLifecycleFormPage.test.js +177 -177
- package/dist/components/__tests__/BucketLifecycleList.test.js +85 -85
- package/dist/components/__tests__/BucketList.test.js +175 -176
- package/dist/components/__tests__/BucketNotificationCreatePage.test.js +84 -84
- package/dist/components/__tests__/BucketOverview.test.js +257 -201
- package/dist/components/__tests__/BucketPolicyPage.test.js +62 -62
- package/dist/components/__tests__/BucketReplicationFormPage.test.js +542 -542
- package/dist/components/__tests__/BucketReplicationList.test.js +106 -106
- package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
- package/dist/components/__tests__/DeleteBucketButton.test.js +62 -62
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +47 -47
- package/dist/components/__tests__/DeleteObjectButton.test.js +63 -63
- package/dist/components/__tests__/EmptyBucketButton.test.js +56 -56
- package/dist/components/__tests__/MetadataSearch.test.js +65 -65
- package/dist/components/__tests__/ObjectList.test.js +252 -251
- package/dist/components/__tests__/UploadButton.test.js +45 -45
- package/dist/components/buckets/BucketCreate.d.ts +2 -2
- package/dist/components/buckets/BucketCreate.js +41 -41
- package/dist/components/buckets/BucketDetails.d.ts +2 -2
- package/dist/components/buckets/BucketDetails.js +48 -36
- package/dist/components/buckets/BucketLifecycleFormPage.js +161 -160
- package/dist/components/buckets/BucketLifecycleList.d.ts +2 -2
- package/dist/components/buckets/BucketLifecycleList.js +46 -46
- package/dist/components/buckets/BucketList.d.ts +2 -2
- package/dist/components/buckets/BucketList.js +28 -27
- package/dist/components/buckets/BucketLocation.js +3 -3
- package/dist/components/buckets/BucketOverview.d.ts +1 -1
- package/dist/components/buckets/BucketOverview.js +64 -65
- package/dist/components/buckets/BucketPage.js +19 -11
- package/dist/components/buckets/BucketPolicyButton.js +2 -2
- package/dist/components/buckets/BucketPolicyPage.js +27 -25
- package/dist/components/buckets/BucketReplicationFormPage.js +133 -132
- package/dist/components/buckets/BucketReplicationList.d.ts +2 -2
- package/dist/components/buckets/BucketReplicationList.js +41 -41
- package/dist/components/buckets/BucketVersioning.js +11 -11
- package/dist/components/buckets/DeleteBucketButton.js +5 -5
- package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +2 -2
- package/dist/components/buckets/DeleteBucketConfigRuleButton.js +1 -1
- package/dist/components/buckets/EmptyBucketButton.js +19 -19
- package/dist/components/buckets/EmptyBucketSummary.d.ts +1 -1
- package/dist/components/buckets/EmptyBucketSummary.js +1 -1
- package/dist/components/buckets/EmptyBucketSummaryList.js +22 -22
- package/dist/components/buckets/__tests__/BucketVersioning.test.js +45 -45
- package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +34 -33
- package/dist/components/buckets/notifications/EventsSection.js +144 -28
- 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 +24 -22
- package/dist/components/index.js +5 -3
- package/dist/components/layouts/ArrowNavigation.d.ts +1 -2
- package/dist/components/layouts/ArrowNavigation.js +3 -3
- package/dist/components/layouts/BrowserPageLayout.d.ts +2 -3
- package/dist/components/layouts/BrowserPageLayout.js +1 -1
- package/dist/components/objects/CreateFolderButton.d.ts +2 -2
- package/dist/components/objects/CreateFolderButton.js +9 -9
- package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
- package/dist/components/objects/DeleteObjectButton.js +20 -20
- package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +1 -1
- package/dist/components/objects/ObjectDetails/ObjectMetadata.js +56 -56
- package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +1 -1
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +39 -39
- package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +1 -1
- package/dist/components/objects/ObjectDetails/ObjectTags.js +25 -25
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +119 -119
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +211 -211
- package/dist/components/objects/ObjectDetails/index.d.ts +1 -1
- package/dist/components/objects/ObjectDetails/index.js +30 -30
- package/dist/components/objects/ObjectList.d.ts +5 -5
- package/dist/components/objects/ObjectList.js +113 -112
- package/dist/components/objects/ObjectLock/EditRetentionButton.js +3 -3
- package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +14 -14
- package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +1 -1
- package/dist/components/objects/ObjectLock/ObjectLockSettings.js +29 -28
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +1 -1
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +6 -6
- package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +50 -50
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +77 -77
- package/dist/components/objects/ObjectPage.js +5 -4
- package/dist/components/objects/UploadButton.d.ts +3 -3
- package/dist/components/objects/UploadButton.js +5 -5
- 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 +22 -0
- package/dist/components/search/MetadataSearch.js +26 -25
- package/dist/components/search/SearchHints.js +1 -1
- package/dist/components/ui/ArrayFieldActions.js +4 -4
- package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +1 -1
- package/dist/components/ui/ConfirmDeleteRuleModal.js +1 -1
- package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
- package/dist/components/ui/DeleteObjectModalContent.js +12 -12
- package/dist/components/ui/FilterFormSection.d.ts +2 -2
- package/dist/components/ui/FilterFormSection.js +29 -29
- package/dist/components/ui/Search.elements.d.ts +1 -1
- package/dist/components/ui/Search.elements.js +7 -7
- package/dist/components/ui/Table.elements.js +5 -5
- package/dist/config/factory.d.ts +23 -10
- package/dist/config/factory.js +22 -7
- package/dist/config/types.d.ts +20 -3
- package/dist/contexts/DataBrowserUICustomizationContext.d.ts +2 -2
- package/dist/hooks/__tests__/useISVBucketDetection.test.js +42 -42
- package/dist/hooks/__tests__/useIsBucketEmpty.test.js +25 -25
- package/dist/hooks/bucketConfiguration.d.ts +1 -1
- package/dist/hooks/bucketConfiguration.js +48 -48
- package/dist/hooks/bucketOperations.d.ts +1 -1
- package/dist/hooks/bucketOperations.js +6 -6
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +78 -78
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +78 -78
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +42 -42
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +61 -61
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +63 -63
- package/dist/hooks/factories/index.d.ts +4 -4
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +15 -12
- package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
- package/dist/hooks/factories/useCreateS3MutationHook.js +6 -1
- package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3QueryHook.js +8 -5
- package/dist/hooks/index.d.ts +16 -13
- package/dist/hooks/index.js +4 -1
- 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 +49 -49
- package/dist/hooks/presignedOperations.d.ts +2 -2
- package/dist/hooks/presignedOperations.js +3 -3
- package/dist/hooks/useBatchObjectLegalHold.js +7 -4
- package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
- package/dist/hooks/useDataBrowserNavigate.js +24 -0
- package/dist/hooks/useDeleteBucketConfigRule.d.ts +2 -2
- package/dist/hooks/useDeleteBucketConfigRule.js +4 -4
- package/dist/hooks/useEmptyBucket.js +10 -10
- package/dist/hooks/useFeatures.d.ts +7 -0
- package/dist/hooks/useFeatures.js +8 -0
- package/dist/hooks/useISVBucketDetection.js +5 -5
- package/dist/hooks/useIsBucketEmpty.js +4 -4
- package/dist/hooks/useLoginMutation.d.ts +1 -1
- package/dist/hooks/useLoginMutation.js +1 -1
- 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/index.d.ts +6 -6
- 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 +31 -16
- 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 +72 -49
- package/dist/test/msw/index.d.ts +2 -2
- 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 +19 -19
- package/dist/test/testUtils.d.ts +9 -15
- package/dist/test/testUtils.js +73 -91
- package/dist/test/utils/errorHandling.test.js +119 -119
- package/dist/types/index.d.ts +6 -31
- package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
- package/dist/utils/__tests__/s3ConfigIdentifier.test.js +429 -0
- package/dist/utils/constants.js +8 -8
- package/dist/utils/deletion/index.d.ts +2 -2
- package/dist/utils/deletion/messages.d.ts +1 -1
- package/dist/utils/deletion/messages.js +4 -4
- package/dist/utils/errorHandling.d.ts +3 -3
- package/dist/utils/errorHandling.js +6 -6
- package/dist/utils/hooks.js +8 -8
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.js +2 -0
- package/dist/utils/proxyMiddleware.d.ts +1 -1
- package/dist/utils/proxyMiddleware.js +6 -11
- package/dist/utils/s3Client.d.ts +2 -2
- package/dist/utils/s3Client.js +1 -1
- package/dist/utils/s3ConfigIdentifier.d.ts +68 -0
- package/dist/utils/s3ConfigIdentifier.js +55 -0
- package/dist/utils/s3RuleUtils.d.ts +5 -5
- package/dist/utils/s3RuleUtils.js +17 -17
- package/package.json +2 -2
- package/dist/utils/useFeatures.d.ts +0 -1
- package/dist/utils/useFeatures.js +0 -7
|
@@ -1,34 +1,14 @@
|
|
|
1
|
-
import * as __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__ from "react-router-dom";
|
|
2
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
3
|
import { fireEvent, render, screen } from "@testing-library/react";
|
|
4
|
+
import { MemoryRouter } from "react-router";
|
|
4
5
|
import { useGetBucketAcl, useGetBucketCors, useGetBucketLocation, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketTagging, useGetBucketVersioning, useISVBucketStatus } from "../../hooks/index.js";
|
|
5
6
|
import { applyBucketMocks, createTestWrapper } from "../../test/testUtils.js";
|
|
6
|
-
import { BucketOverview } from "../buckets/BucketOverview.js";
|
|
7
|
-
import { useFeatures } from "../../
|
|
7
|
+
import { BucketOverview, useBucketOverviewContext } from "../buckets/BucketOverview.js";
|
|
8
|
+
import { useFeatures } from "../../hooks/useFeatures.js";
|
|
8
9
|
import * as __WEBPACK_EXTERNAL_MODULE__contexts_DataBrowserUICustomizationContext_js_f267b01c__ from "../../contexts/DataBrowserUICustomizationContext.js";
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
module.exports = __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__;
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
var __webpack_module_cache__ = {};
|
|
15
|
-
function __webpack_require__(moduleId) {
|
|
16
|
-
var cachedModule = __webpack_module_cache__[moduleId];
|
|
17
|
-
if (void 0 !== cachedModule) return cachedModule.exports;
|
|
18
|
-
var module = __webpack_module_cache__[moduleId] = {
|
|
19
|
-
exports: {}
|
|
20
|
-
};
|
|
21
|
-
__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
22
|
-
return module.exports;
|
|
23
|
-
}
|
|
24
|
-
var external_react_router_dom_ = __webpack_require__("react-router-dom");
|
|
25
|
-
jest.mock("../../hooks");
|
|
26
|
-
jest.mock("../../utils/useFeatures");
|
|
27
|
-
jest.mock("../../contexts/DataBrowserUICustomizationContext");
|
|
28
|
-
jest.mock("react-router-dom", ()=>({
|
|
29
|
-
...jest.requireActual("react-router-dom"),
|
|
30
|
-
useNavigate: jest.fn()
|
|
31
|
-
}));
|
|
10
|
+
jest.mock('../../hooks');
|
|
11
|
+
jest.mock('../../hooks/useFeatures');
|
|
32
12
|
const mockUseGetBucketVersioning = jest.mocked(useGetBucketVersioning);
|
|
33
13
|
const mockUseGetBucketAcl = jest.mocked(useGetBucketAcl);
|
|
34
14
|
const mockUseGetBucketLocation = jest.mocked(useGetBucketLocation);
|
|
@@ -39,14 +19,12 @@ const mockUseGetBucketTagging = jest.mocked(useGetBucketTagging);
|
|
|
39
19
|
const mockUseISVBucketStatus = jest.mocked(useISVBucketStatus);
|
|
40
20
|
const mockUseFeatures = jest.mocked(useFeatures);
|
|
41
21
|
const mockUseDataBrowserUICustomization = (config = {})=>{
|
|
42
|
-
jest.spyOn(__WEBPACK_EXTERNAL_MODULE__contexts_DataBrowserUICustomizationContext_js_f267b01c__,
|
|
22
|
+
jest.spyOn(__WEBPACK_EXTERNAL_MODULE__contexts_DataBrowserUICustomizationContext_js_f267b01c__, 'useDataBrowserUICustomization').mockReturnValue(config);
|
|
43
23
|
};
|
|
44
24
|
const renderBucketOverview = (props = {})=>{
|
|
45
|
-
const { bucketName =
|
|
25
|
+
const { bucketName = 'test-bucket', onEmptyBucket, onDeleteBucket, onEditPolicy, renderEmptyButton, renderDeleteButton, isEmptyBucketDisabled, isDeleteBucketDisabled } = props;
|
|
46
26
|
const Wrapper = createTestWrapper();
|
|
47
|
-
|
|
48
|
-
__webpack_require__("react-router-dom").useNavigate.mockReturnValue(mockNavigate);
|
|
49
|
-
return render(/*#__PURE__*/ jsx(external_react_router_dom_.MemoryRouter, {
|
|
27
|
+
return render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
50
28
|
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
51
29
|
children: /*#__PURE__*/ jsxs(BucketOverview, {
|
|
52
30
|
bucketName: bucketName,
|
|
@@ -86,560 +64,638 @@ const mockHookDefaults = (overrides = {})=>{
|
|
|
86
64
|
useFeatures: mockUseFeatures
|
|
87
65
|
}, overrides);
|
|
88
66
|
};
|
|
89
|
-
describe(
|
|
67
|
+
describe('BucketOverview', ()=>{
|
|
90
68
|
beforeEach(()=>{
|
|
91
69
|
jest.clearAllMocks();
|
|
92
70
|
mockHookDefaults();
|
|
93
71
|
mockUseDataBrowserUICustomization({});
|
|
94
72
|
});
|
|
95
|
-
it(
|
|
73
|
+
it('renders bucket overview with all sections', ()=>{
|
|
96
74
|
renderBucketOverview();
|
|
97
|
-
expect(screen.getByText(
|
|
98
|
-
expect(screen.getByText(
|
|
99
|
-
expect(screen.getByText(
|
|
75
|
+
expect(screen.getByText('General')).toBeInTheDocument();
|
|
76
|
+
expect(screen.getByText('Data protection')).toBeInTheDocument();
|
|
77
|
+
expect(screen.getByText('Permissions')).toBeInTheDocument();
|
|
100
78
|
});
|
|
101
|
-
it(
|
|
79
|
+
it('displays bucket name correctly', ()=>{
|
|
102
80
|
renderBucketOverview({
|
|
103
|
-
bucketName:
|
|
81
|
+
bucketName: 'my-test-bucket'
|
|
104
82
|
});
|
|
105
|
-
expect(screen.getByText(
|
|
83
|
+
expect(screen.getByText('my-test-bucket')).toBeInTheDocument();
|
|
106
84
|
});
|
|
107
|
-
it(
|
|
85
|
+
it('shows versioning status when enabled', ()=>{
|
|
108
86
|
mockUseGetBucketVersioning.mockReturnValue({
|
|
109
87
|
data: {
|
|
110
|
-
Status:
|
|
88
|
+
Status: 'Enabled'
|
|
111
89
|
},
|
|
112
|
-
status:
|
|
90
|
+
status: 'success'
|
|
113
91
|
});
|
|
114
92
|
renderBucketOverview();
|
|
115
|
-
expect(screen.getByText(
|
|
93
|
+
expect(screen.getByText('Active')).toBeInTheDocument();
|
|
116
94
|
});
|
|
117
|
-
it(
|
|
95
|
+
it('shows versioning status when disabled', ()=>{
|
|
118
96
|
mockUseGetBucketVersioning.mockReturnValue({
|
|
119
97
|
data: {
|
|
120
|
-
Status:
|
|
98
|
+
Status: 'Suspended'
|
|
121
99
|
},
|
|
122
|
-
status:
|
|
100
|
+
status: 'success'
|
|
123
101
|
});
|
|
124
102
|
renderBucketOverview();
|
|
125
|
-
expect(screen.getByText(
|
|
103
|
+
expect(screen.getByText('Inactive')).toBeInTheDocument();
|
|
126
104
|
});
|
|
127
|
-
it(
|
|
105
|
+
it('displays bucket location', ()=>{
|
|
128
106
|
mockUseGetBucketLocation.mockReturnValue({
|
|
129
107
|
data: {
|
|
130
|
-
LocationConstraint:
|
|
108
|
+
LocationConstraint: 'eu-west-1'
|
|
131
109
|
},
|
|
132
|
-
status:
|
|
110
|
+
status: 'success'
|
|
133
111
|
});
|
|
134
112
|
renderBucketOverview();
|
|
135
|
-
expect(screen.getByText(
|
|
113
|
+
expect(screen.getByText('eu-west-1')).toBeInTheDocument();
|
|
136
114
|
});
|
|
137
|
-
it(
|
|
115
|
+
it('shows default location when LocationConstraint is null', ()=>{
|
|
138
116
|
mockUseGetBucketLocation.mockReturnValue({
|
|
139
117
|
data: {
|
|
140
118
|
LocationConstraint: null
|
|
141
119
|
},
|
|
142
|
-
status:
|
|
120
|
+
status: 'success'
|
|
143
121
|
});
|
|
144
122
|
renderBucketOverview();
|
|
145
|
-
expect(screen.getByText(
|
|
123
|
+
expect(screen.getByText('us-east-1')).toBeInTheDocument();
|
|
146
124
|
});
|
|
147
|
-
it(
|
|
125
|
+
it('shows object-lock enabled status', ()=>{
|
|
148
126
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
149
127
|
data: {
|
|
150
128
|
ObjectLockConfiguration: {
|
|
151
|
-
ObjectLockEnabled:
|
|
129
|
+
ObjectLockEnabled: 'Enabled'
|
|
152
130
|
}
|
|
153
131
|
},
|
|
154
|
-
status:
|
|
132
|
+
status: 'success'
|
|
155
133
|
});
|
|
156
134
|
renderBucketOverview();
|
|
157
|
-
expect(screen.getByText(
|
|
135
|
+
expect(screen.getByText('Enabled')).toBeInTheDocument();
|
|
158
136
|
});
|
|
159
|
-
it(
|
|
137
|
+
it('shows object-lock disabled status', ()=>{
|
|
160
138
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
161
139
|
data: {
|
|
162
140
|
ObjectLockConfiguration: {
|
|
163
|
-
ObjectLockEnabled:
|
|
141
|
+
ObjectLockEnabled: 'Disabled'
|
|
164
142
|
}
|
|
165
143
|
},
|
|
166
|
-
status:
|
|
144
|
+
status: 'success'
|
|
167
145
|
});
|
|
168
146
|
renderBucketOverview();
|
|
169
|
-
expect(screen.getByText(
|
|
147
|
+
expect(screen.getByText('Disabled')).toBeInTheDocument();
|
|
170
148
|
});
|
|
171
|
-
it(
|
|
149
|
+
it('shows default retention as Inactive when not configured', ()=>{
|
|
172
150
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
173
151
|
data: {
|
|
174
152
|
ObjectLockConfiguration: {
|
|
175
|
-
ObjectLockEnabled:
|
|
153
|
+
ObjectLockEnabled: 'Enabled'
|
|
176
154
|
}
|
|
177
155
|
},
|
|
178
|
-
status:
|
|
156
|
+
status: 'success'
|
|
179
157
|
});
|
|
180
158
|
renderBucketOverview();
|
|
181
|
-
expect(screen.getByText(
|
|
159
|
+
expect(screen.getByText('Inactive')).toBeInTheDocument();
|
|
182
160
|
});
|
|
183
|
-
it(
|
|
161
|
+
it('shows default retention with days in Governance mode', ()=>{
|
|
184
162
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
185
163
|
data: {
|
|
186
164
|
ObjectLockConfiguration: {
|
|
187
|
-
ObjectLockEnabled:
|
|
165
|
+
ObjectLockEnabled: 'Enabled',
|
|
188
166
|
Rule: {
|
|
189
167
|
DefaultRetention: {
|
|
190
|
-
Mode:
|
|
168
|
+
Mode: 'GOVERNANCE',
|
|
191
169
|
Days: 30
|
|
192
170
|
}
|
|
193
171
|
}
|
|
194
172
|
}
|
|
195
173
|
},
|
|
196
|
-
status:
|
|
174
|
+
status: 'success'
|
|
197
175
|
});
|
|
198
176
|
renderBucketOverview();
|
|
199
|
-
expect(screen.getByText(
|
|
177
|
+
expect(screen.getByText('Governance - 30 days')).toBeInTheDocument();
|
|
200
178
|
});
|
|
201
|
-
it(
|
|
179
|
+
it('shows default retention with single day', ()=>{
|
|
202
180
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
203
181
|
data: {
|
|
204
182
|
ObjectLockConfiguration: {
|
|
205
|
-
ObjectLockEnabled:
|
|
183
|
+
ObjectLockEnabled: 'Enabled',
|
|
206
184
|
Rule: {
|
|
207
185
|
DefaultRetention: {
|
|
208
|
-
Mode:
|
|
186
|
+
Mode: 'COMPLIANCE',
|
|
209
187
|
Days: 1
|
|
210
188
|
}
|
|
211
189
|
}
|
|
212
190
|
}
|
|
213
191
|
},
|
|
214
|
-
status:
|
|
192
|
+
status: 'success'
|
|
215
193
|
});
|
|
216
194
|
renderBucketOverview();
|
|
217
|
-
expect(screen.getByText(
|
|
195
|
+
expect(screen.getByText('Compliance - 1 day')).toBeInTheDocument();
|
|
218
196
|
});
|
|
219
|
-
it(
|
|
197
|
+
it('shows default retention with years in Compliance mode', ()=>{
|
|
220
198
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
221
199
|
data: {
|
|
222
200
|
ObjectLockConfiguration: {
|
|
223
|
-
ObjectLockEnabled:
|
|
201
|
+
ObjectLockEnabled: 'Enabled',
|
|
224
202
|
Rule: {
|
|
225
203
|
DefaultRetention: {
|
|
226
|
-
Mode:
|
|
204
|
+
Mode: 'COMPLIANCE',
|
|
227
205
|
Years: 7
|
|
228
206
|
}
|
|
229
207
|
}
|
|
230
208
|
}
|
|
231
209
|
},
|
|
232
|
-
status:
|
|
210
|
+
status: 'success'
|
|
233
211
|
});
|
|
234
212
|
renderBucketOverview();
|
|
235
|
-
expect(screen.getByText(
|
|
213
|
+
expect(screen.getByText('Compliance - 7 years')).toBeInTheDocument();
|
|
236
214
|
});
|
|
237
|
-
it(
|
|
215
|
+
it('shows default retention with single year', ()=>{
|
|
238
216
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
239
217
|
data: {
|
|
240
218
|
ObjectLockConfiguration: {
|
|
241
|
-
ObjectLockEnabled:
|
|
219
|
+
ObjectLockEnabled: 'Enabled',
|
|
242
220
|
Rule: {
|
|
243
221
|
DefaultRetention: {
|
|
244
|
-
Mode:
|
|
222
|
+
Mode: 'GOVERNANCE',
|
|
245
223
|
Years: 1
|
|
246
224
|
}
|
|
247
225
|
}
|
|
248
226
|
}
|
|
249
227
|
},
|
|
250
|
-
status:
|
|
228
|
+
status: 'success'
|
|
251
229
|
});
|
|
252
230
|
renderBucketOverview();
|
|
253
|
-
expect(screen.getByText(
|
|
231
|
+
expect(screen.getByText('Governance - 1 year')).toBeInTheDocument();
|
|
254
232
|
});
|
|
255
|
-
it(
|
|
233
|
+
it('shows edit retention button when object lock is enabled', ()=>{
|
|
256
234
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
257
235
|
data: {
|
|
258
236
|
ObjectLockConfiguration: {
|
|
259
|
-
ObjectLockEnabled:
|
|
237
|
+
ObjectLockEnabled: 'Enabled',
|
|
260
238
|
Rule: {
|
|
261
239
|
DefaultRetention: {
|
|
262
|
-
Mode:
|
|
240
|
+
Mode: 'GOVERNANCE',
|
|
263
241
|
Days: 30
|
|
264
242
|
}
|
|
265
243
|
}
|
|
266
244
|
}
|
|
267
245
|
},
|
|
268
|
-
status:
|
|
246
|
+
status: 'success'
|
|
269
247
|
});
|
|
270
248
|
renderBucketOverview();
|
|
271
|
-
const editButton = screen.getByRole(
|
|
249
|
+
const editButton = screen.getByRole('button', {
|
|
272
250
|
name: /edit default retention/i
|
|
273
251
|
});
|
|
274
252
|
expect(editButton).toBeInTheDocument();
|
|
275
253
|
});
|
|
276
|
-
it(
|
|
254
|
+
it('does not show edit retention button when object lock is disabled', ()=>{
|
|
277
255
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
278
256
|
data: {
|
|
279
257
|
ObjectLockConfiguration: {
|
|
280
|
-
ObjectLockEnabled:
|
|
258
|
+
ObjectLockEnabled: 'Disabled'
|
|
281
259
|
}
|
|
282
260
|
},
|
|
283
|
-
status:
|
|
261
|
+
status: 'success'
|
|
284
262
|
});
|
|
285
263
|
renderBucketOverview();
|
|
286
|
-
const editButton = screen.queryByRole(
|
|
264
|
+
const editButton = screen.queryByRole('button', {
|
|
287
265
|
name: /edit default retention/i
|
|
288
266
|
});
|
|
289
267
|
expect(editButton).not.toBeInTheDocument();
|
|
290
268
|
});
|
|
291
|
-
it(
|
|
269
|
+
it('displays bucket owner from ACL', ()=>{
|
|
292
270
|
mockUseGetBucketAcl.mockReturnValue({
|
|
293
271
|
data: {
|
|
294
272
|
Owner: {
|
|
295
|
-
DisplayName:
|
|
273
|
+
DisplayName: 'bucket-owner'
|
|
296
274
|
},
|
|
297
275
|
Grants: []
|
|
298
276
|
},
|
|
299
|
-
status:
|
|
277
|
+
status: 'success'
|
|
300
278
|
});
|
|
301
279
|
renderBucketOverview();
|
|
302
|
-
expect(screen.getByText(
|
|
280
|
+
expect(screen.getByText('bucket-owner')).toBeInTheDocument();
|
|
303
281
|
});
|
|
304
|
-
it(
|
|
282
|
+
it('shows ACL grantees count', ()=>{
|
|
305
283
|
mockUseGetBucketAcl.mockReturnValue({
|
|
306
284
|
data: {
|
|
307
285
|
Owner: {
|
|
308
|
-
DisplayName:
|
|
286
|
+
DisplayName: 'owner'
|
|
309
287
|
},
|
|
310
288
|
Grants: [
|
|
311
289
|
{
|
|
312
290
|
Grantee: {
|
|
313
|
-
DisplayName:
|
|
291
|
+
DisplayName: 'user1'
|
|
314
292
|
}
|
|
315
293
|
},
|
|
316
294
|
{
|
|
317
295
|
Grantee: {
|
|
318
|
-
DisplayName:
|
|
296
|
+
DisplayName: 'user2'
|
|
319
297
|
}
|
|
320
298
|
},
|
|
321
299
|
{
|
|
322
300
|
Grantee: {
|
|
323
|
-
DisplayName:
|
|
301
|
+
DisplayName: 'user3'
|
|
324
302
|
}
|
|
325
303
|
}
|
|
326
304
|
]
|
|
327
305
|
},
|
|
328
|
-
status:
|
|
306
|
+
status: 'success'
|
|
329
307
|
});
|
|
330
308
|
renderBucketOverview();
|
|
331
|
-
expect(screen.getByText(
|
|
309
|
+
expect(screen.getByText('3 Grantees')).toBeInTheDocument();
|
|
332
310
|
});
|
|
333
|
-
it(
|
|
311
|
+
it('shows single grantee without plural', ()=>{
|
|
334
312
|
mockUseGetBucketAcl.mockReturnValue({
|
|
335
313
|
data: {
|
|
336
314
|
Owner: {
|
|
337
|
-
DisplayName:
|
|
315
|
+
DisplayName: 'owner'
|
|
338
316
|
},
|
|
339
317
|
Grants: [
|
|
340
318
|
{
|
|
341
319
|
Grantee: {
|
|
342
|
-
DisplayName:
|
|
320
|
+
DisplayName: 'user1'
|
|
343
321
|
}
|
|
344
322
|
}
|
|
345
323
|
]
|
|
346
324
|
},
|
|
347
|
-
status:
|
|
325
|
+
status: 'success'
|
|
348
326
|
});
|
|
349
327
|
renderBucketOverview();
|
|
350
|
-
expect(screen.getByText(
|
|
328
|
+
expect(screen.getByText('1 Grantee')).toBeInTheDocument();
|
|
351
329
|
});
|
|
352
|
-
it(
|
|
330
|
+
it('shows CORS enabled when rules exist', ()=>{
|
|
353
331
|
mockUseGetBucketCors.mockReturnValue({
|
|
354
332
|
data: {
|
|
355
333
|
CORSRules: [
|
|
356
334
|
{
|
|
357
335
|
AllowedMethods: [
|
|
358
|
-
|
|
336
|
+
'GET'
|
|
359
337
|
],
|
|
360
338
|
AllowedOrigins: [
|
|
361
|
-
|
|
339
|
+
'*'
|
|
362
340
|
]
|
|
363
341
|
}
|
|
364
342
|
]
|
|
365
343
|
},
|
|
366
|
-
status:
|
|
344
|
+
status: 'success'
|
|
367
345
|
});
|
|
368
346
|
renderBucketOverview();
|
|
369
|
-
expect(screen.getByText(
|
|
347
|
+
expect(screen.getByText('Yes')).toBeInTheDocument();
|
|
370
348
|
});
|
|
371
|
-
it(
|
|
349
|
+
it('shows CORS disabled when no rules exist', ()=>{
|
|
372
350
|
mockUseGetBucketCors.mockReturnValue({
|
|
373
351
|
data: {
|
|
374
352
|
CORSRules: []
|
|
375
353
|
},
|
|
376
|
-
status:
|
|
354
|
+
status: 'success'
|
|
377
355
|
});
|
|
378
356
|
renderBucketOverview();
|
|
379
|
-
const corsValues = screen.getAllByText(
|
|
357
|
+
const corsValues = screen.getAllByText('No');
|
|
380
358
|
expect(corsValues.length).toBeGreaterThan(0);
|
|
381
359
|
});
|
|
382
|
-
it(
|
|
360
|
+
it('detects public bucket from ACL grants', ()=>{
|
|
383
361
|
mockUseGetBucketAcl.mockReturnValue({
|
|
384
362
|
data: {
|
|
385
363
|
Owner: {
|
|
386
|
-
DisplayName:
|
|
364
|
+
DisplayName: 'owner'
|
|
387
365
|
},
|
|
388
366
|
Grants: [
|
|
389
367
|
{
|
|
390
368
|
Grantee: {
|
|
391
|
-
URI:
|
|
369
|
+
URI: 'http://acs.amazonaws.com/groups/global/AllUsers'
|
|
392
370
|
},
|
|
393
|
-
Permission:
|
|
371
|
+
Permission: 'READ'
|
|
394
372
|
}
|
|
395
373
|
]
|
|
396
374
|
},
|
|
397
|
-
status:
|
|
375
|
+
status: 'success'
|
|
398
376
|
});
|
|
399
377
|
renderBucketOverview();
|
|
400
|
-
expect(screen.getByText(
|
|
378
|
+
expect(screen.getByText('Yes')).toBeInTheDocument();
|
|
401
379
|
});
|
|
402
|
-
it(
|
|
380
|
+
it('shows non-public bucket when no public grants', ()=>{
|
|
403
381
|
mockUseGetBucketAcl.mockReturnValue({
|
|
404
382
|
data: {
|
|
405
383
|
Owner: {
|
|
406
|
-
DisplayName:
|
|
384
|
+
DisplayName: 'owner'
|
|
407
385
|
},
|
|
408
386
|
Grants: [
|
|
409
387
|
{
|
|
410
388
|
Grantee: {
|
|
411
|
-
DisplayName:
|
|
389
|
+
DisplayName: 'private-user'
|
|
412
390
|
},
|
|
413
|
-
Permission:
|
|
391
|
+
Permission: 'READ'
|
|
414
392
|
}
|
|
415
393
|
]
|
|
416
394
|
},
|
|
417
|
-
status:
|
|
395
|
+
status: 'success'
|
|
418
396
|
});
|
|
419
397
|
renderBucketOverview();
|
|
420
|
-
const publicValues = screen.getAllByText(
|
|
398
|
+
const publicValues = screen.getAllByText('No');
|
|
421
399
|
expect(publicValues.length).toBeGreaterThan(0);
|
|
422
400
|
});
|
|
423
|
-
it(
|
|
401
|
+
it('shows loading states while data is being fetched', ()=>{
|
|
424
402
|
mockUseGetBucketVersioning.mockReturnValue({
|
|
425
403
|
data: void 0,
|
|
426
|
-
status:
|
|
404
|
+
status: 'pending'
|
|
427
405
|
});
|
|
428
406
|
mockUseGetBucketAcl.mockReturnValue({
|
|
429
407
|
data: void 0,
|
|
430
|
-
status:
|
|
408
|
+
status: 'pending'
|
|
431
409
|
});
|
|
432
410
|
renderBucketOverview();
|
|
433
411
|
const loaders = document.querySelectorAll('[data-testid="loader"], .loader, [class*="loader"]');
|
|
434
412
|
expect(loaders.length).toBeGreaterThan(0);
|
|
435
413
|
});
|
|
436
|
-
it(
|
|
414
|
+
it('shows error states when API calls fail', ()=>{
|
|
437
415
|
mockUseGetBucketVersioning.mockReturnValue({
|
|
438
416
|
data: void 0,
|
|
439
|
-
status:
|
|
417
|
+
status: 'error'
|
|
440
418
|
});
|
|
441
419
|
mockUseGetBucketLocation.mockReturnValue({
|
|
442
420
|
data: void 0,
|
|
443
|
-
status:
|
|
421
|
+
status: 'error'
|
|
444
422
|
});
|
|
445
423
|
renderBucketOverview();
|
|
446
|
-
const errorElements = screen.getAllByText(
|
|
424
|
+
const errorElements = screen.getAllByText('Error');
|
|
447
425
|
expect(errorElements.length).toBeGreaterThan(0);
|
|
448
426
|
});
|
|
449
|
-
it(
|
|
427
|
+
it('handles empty bucket button click', ()=>{
|
|
450
428
|
const onEmptyBucket = jest.fn();
|
|
451
429
|
renderBucketOverview({
|
|
452
430
|
onEmptyBucket,
|
|
453
431
|
isEmptyBucketDisabled: false
|
|
454
432
|
});
|
|
455
|
-
const emptyButton = screen.getByRole(
|
|
433
|
+
const emptyButton = screen.getByRole('button', {
|
|
456
434
|
name: /empty bucket/i
|
|
457
435
|
});
|
|
458
436
|
fireEvent.click(emptyButton);
|
|
459
437
|
expect(onEmptyBucket).toHaveBeenCalled();
|
|
460
438
|
});
|
|
461
|
-
it(
|
|
439
|
+
it('handles delete bucket button click', ()=>{
|
|
462
440
|
const onDeleteBucket = jest.fn();
|
|
463
441
|
renderBucketOverview({
|
|
464
442
|
onDeleteBucket
|
|
465
443
|
});
|
|
466
|
-
const deleteButton = screen.getByRole(
|
|
444
|
+
const deleteButton = screen.getByRole('button', {
|
|
467
445
|
name: /delete bucket/i
|
|
468
446
|
});
|
|
469
447
|
fireEvent.click(deleteButton);
|
|
470
448
|
expect(onDeleteBucket).toHaveBeenCalled();
|
|
471
449
|
});
|
|
472
|
-
it(
|
|
450
|
+
it('disables empty button when specified', ()=>{
|
|
473
451
|
renderBucketOverview({
|
|
474
452
|
isEmptyBucketDisabled: true
|
|
475
453
|
});
|
|
476
|
-
const emptyButton = screen.getByRole(
|
|
454
|
+
const emptyButton = screen.getByRole('button', {
|
|
477
455
|
name: /empty bucket/i
|
|
478
456
|
});
|
|
479
457
|
expect(emptyButton).toBeDisabled();
|
|
480
458
|
});
|
|
481
|
-
it(
|
|
459
|
+
it('disables delete button when specified', ()=>{
|
|
482
460
|
renderBucketOverview({
|
|
483
461
|
isDeleteBucketDisabled: true
|
|
484
462
|
});
|
|
485
|
-
const deleteButton = screen.getByRole(
|
|
463
|
+
const deleteButton = screen.getByRole('button', {
|
|
486
464
|
name: /delete bucket/i
|
|
487
465
|
});
|
|
488
466
|
expect(deleteButton).toBeDisabled();
|
|
489
467
|
});
|
|
490
|
-
it(
|
|
468
|
+
it('renders custom empty button when provided', ()=>{
|
|
491
469
|
const renderEmptyButton = jest.fn(()=>/*#__PURE__*/ jsx("button", {
|
|
492
470
|
children: "Custom Empty Button"
|
|
493
471
|
}));
|
|
494
472
|
renderBucketOverview({
|
|
495
473
|
renderEmptyButton
|
|
496
474
|
});
|
|
497
|
-
expect(screen.getByText(
|
|
498
|
-
expect(renderEmptyButton).toHaveBeenCalledWith(
|
|
475
|
+
expect(screen.getByText('Custom Empty Button')).toBeInTheDocument();
|
|
476
|
+
expect(renderEmptyButton).toHaveBeenCalledWith('test-bucket');
|
|
499
477
|
});
|
|
500
|
-
it(
|
|
478
|
+
it('renders custom delete button when provided', ()=>{
|
|
501
479
|
const renderDeleteButton = jest.fn(()=>/*#__PURE__*/ jsx("button", {
|
|
502
480
|
children: "Custom Delete Button"
|
|
503
481
|
}));
|
|
504
482
|
renderBucketOverview({
|
|
505
483
|
renderDeleteButton
|
|
506
484
|
});
|
|
507
|
-
expect(screen.getByText(
|
|
508
|
-
expect(renderDeleteButton).toHaveBeenCalledWith(
|
|
485
|
+
expect(screen.getByText('Custom Delete Button')).toBeInTheDocument();
|
|
486
|
+
expect(renderDeleteButton).toHaveBeenCalledWith('test-bucket');
|
|
509
487
|
});
|
|
510
|
-
it(
|
|
488
|
+
it('works when no callbacks are provided', ()=>{
|
|
511
489
|
expect(()=>{
|
|
512
490
|
renderBucketOverview();
|
|
513
|
-
const emptyButton = screen.getByRole(
|
|
491
|
+
const emptyButton = screen.getByRole('button', {
|
|
514
492
|
name: /empty bucket/i
|
|
515
493
|
});
|
|
516
|
-
const deleteButton = screen.getByRole(
|
|
494
|
+
const deleteButton = screen.getByRole('button', {
|
|
517
495
|
name: /delete bucket/i
|
|
518
496
|
});
|
|
519
497
|
fireEvent.click(emptyButton);
|
|
520
498
|
fireEvent.click(deleteButton);
|
|
521
499
|
}).not.toThrow();
|
|
522
500
|
});
|
|
523
|
-
it(
|
|
501
|
+
it('handles missing ACL data gracefully', ()=>{
|
|
524
502
|
mockUseGetBucketAcl.mockReturnValue({
|
|
525
503
|
data: void 0,
|
|
526
|
-
status:
|
|
504
|
+
status: 'success'
|
|
527
505
|
});
|
|
528
506
|
renderBucketOverview();
|
|
529
|
-
const naElements = screen.getAllByText(
|
|
507
|
+
const naElements = screen.getAllByText('N/A');
|
|
530
508
|
expect(naElements.length).toBeGreaterThan(0);
|
|
531
509
|
});
|
|
532
|
-
it(
|
|
510
|
+
it('handles missing versioning data gracefully', ()=>{
|
|
533
511
|
mockUseGetBucketVersioning.mockReturnValue({
|
|
534
512
|
data: void 0,
|
|
535
|
-
status:
|
|
513
|
+
status: 'success'
|
|
536
514
|
});
|
|
537
515
|
renderBucketOverview();
|
|
538
|
-
expect(screen.getByText(
|
|
516
|
+
expect(screen.getByText('Inactive')).toBeInTheDocument();
|
|
539
517
|
});
|
|
540
|
-
it(
|
|
518
|
+
it('handles CORS error state', ()=>{
|
|
541
519
|
mockUseGetBucketCors.mockReturnValue({
|
|
542
520
|
data: void 0,
|
|
543
|
-
status:
|
|
521
|
+
status: 'error'
|
|
544
522
|
});
|
|
545
523
|
renderBucketOverview();
|
|
546
|
-
const corsValues = screen.getAllByText(
|
|
524
|
+
const corsValues = screen.getAllByText('No');
|
|
547
525
|
expect(corsValues.length).toBeGreaterThan(0);
|
|
548
526
|
});
|
|
549
|
-
it(
|
|
550
|
-
const notFoundError = new Error(
|
|
551
|
-
notFoundError.name =
|
|
527
|
+
it('handles object lock error state (404 - not configured)', ()=>{
|
|
528
|
+
const notFoundError = new Error('Object Lock configuration does not exist');
|
|
529
|
+
notFoundError.name = 'NoSuchBucketObjectLockConfiguration';
|
|
552
530
|
notFoundError.$metadata = {
|
|
553
531
|
httpStatusCode: 404
|
|
554
532
|
};
|
|
555
533
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
556
534
|
data: void 0,
|
|
557
|
-
status:
|
|
535
|
+
status: 'error',
|
|
558
536
|
error: notFoundError
|
|
559
537
|
});
|
|
560
538
|
renderBucketOverview();
|
|
561
|
-
expect(screen.getByText(
|
|
539
|
+
expect(screen.getByText('Disabled')).toBeInTheDocument();
|
|
562
540
|
});
|
|
563
|
-
it(
|
|
564
|
-
const accessDeniedError = new Error(
|
|
565
|
-
accessDeniedError.name =
|
|
541
|
+
it('handles object lock real error state (non-404)', ()=>{
|
|
542
|
+
const accessDeniedError = new Error('Access Denied');
|
|
543
|
+
accessDeniedError.name = 'AccessDenied';
|
|
566
544
|
accessDeniedError.$metadata = {
|
|
567
545
|
httpStatusCode: 403
|
|
568
546
|
};
|
|
569
547
|
mockUseGetBucketObjectLockConfiguration.mockReturnValue({
|
|
570
548
|
data: void 0,
|
|
571
|
-
status:
|
|
549
|
+
status: 'error',
|
|
572
550
|
error: accessDeniedError
|
|
573
551
|
});
|
|
574
552
|
renderBucketOverview();
|
|
575
|
-
expect(screen.getByText(
|
|
553
|
+
expect(screen.getByText('Error')).toBeInTheDocument();
|
|
576
554
|
});
|
|
577
|
-
describe(
|
|
555
|
+
describe('Bucket Policy', ()=>{
|
|
578
556
|
it("shows 'Configured' when policy exists", ()=>{
|
|
579
557
|
mockUseGetBucketPolicy.mockReturnValue({
|
|
580
558
|
data: {
|
|
581
559
|
Policy: '{"Version":"2012-10-17","Statement":[]}'
|
|
582
560
|
},
|
|
583
561
|
error: null,
|
|
584
|
-
status:
|
|
562
|
+
status: 'success'
|
|
585
563
|
});
|
|
586
564
|
renderBucketOverview();
|
|
587
|
-
expect(screen.getByText(
|
|
565
|
+
expect(screen.getByText('Configured')).toBeInTheDocument();
|
|
588
566
|
});
|
|
589
567
|
it("shows 'Not configured' when no policy exists", ()=>{
|
|
590
568
|
mockUseGetBucketPolicy.mockReturnValue({
|
|
591
569
|
data: void 0,
|
|
592
570
|
error: null,
|
|
593
|
-
status:
|
|
571
|
+
status: 'success'
|
|
594
572
|
});
|
|
595
573
|
renderBucketOverview();
|
|
596
|
-
expect(screen.getByText(
|
|
574
|
+
expect(screen.getByText('Not configured')).toBeInTheDocument();
|
|
597
575
|
});
|
|
598
576
|
it("shows 'Error' when policy fetch fails with non-NoSuchBucketPolicy error", ()=>{
|
|
599
|
-
const genericError = new Error(
|
|
577
|
+
const genericError = new Error('Network error');
|
|
600
578
|
mockUseGetBucketPolicy.mockReturnValue({
|
|
601
579
|
data: void 0,
|
|
602
580
|
error: genericError,
|
|
603
|
-
status:
|
|
581
|
+
status: 'error'
|
|
604
582
|
});
|
|
605
583
|
renderBucketOverview();
|
|
606
|
-
const errorElements = screen.getAllByText(
|
|
584
|
+
const errorElements = screen.getAllByText('Error');
|
|
607
585
|
expect(errorElements.length).toBeGreaterThan(0);
|
|
608
586
|
});
|
|
609
587
|
it("shows 'Not configured' when policy does not exist (NoSuchBucketPolicy)", ()=>{
|
|
610
|
-
const noSuchPolicyError = new Error(
|
|
611
|
-
noSuchPolicyError.name =
|
|
588
|
+
const noSuchPolicyError = new Error('Policy does not exist');
|
|
589
|
+
noSuchPolicyError.name = 'NoSuchBucketPolicy';
|
|
612
590
|
mockUseGetBucketPolicy.mockReturnValue({
|
|
613
591
|
data: void 0,
|
|
614
592
|
error: noSuchPolicyError,
|
|
615
|
-
status:
|
|
593
|
+
status: 'error'
|
|
616
594
|
});
|
|
617
595
|
renderBucketOverview();
|
|
618
|
-
expect(screen.getByText(
|
|
596
|
+
expect(screen.getByText('Not configured')).toBeInTheDocument();
|
|
619
597
|
});
|
|
620
|
-
it(
|
|
598
|
+
it('calls onEditPolicy when edit button is clicked', ()=>{
|
|
621
599
|
const onEditPolicy = jest.fn();
|
|
622
600
|
mockUseGetBucketPolicy.mockReturnValue({
|
|
623
601
|
data: {
|
|
624
602
|
Policy: '{"Version":"2012-10-17","Statement":[]}'
|
|
625
603
|
},
|
|
626
604
|
error: null,
|
|
627
|
-
status:
|
|
605
|
+
status: 'success'
|
|
628
606
|
});
|
|
629
607
|
renderBucketOverview({
|
|
630
608
|
onEditPolicy
|
|
631
609
|
});
|
|
632
|
-
const editButton = screen.getByRole(
|
|
610
|
+
const editButton = screen.getByRole('button', {
|
|
633
611
|
name: /edit/i
|
|
634
612
|
});
|
|
635
613
|
fireEvent.click(editButton);
|
|
636
|
-
expect(onEditPolicy).toHaveBeenCalledWith(
|
|
614
|
+
expect(onEditPolicy).toHaveBeenCalledWith('test-bucket');
|
|
615
|
+
});
|
|
616
|
+
});
|
|
617
|
+
describe('Extra Sections', ()=>{
|
|
618
|
+
it('renders extra sections between General and Data Protection', ()=>{
|
|
619
|
+
const Wrapper = createTestWrapper();
|
|
620
|
+
const extraSections = [
|
|
621
|
+
{
|
|
622
|
+
id: 'custom-section',
|
|
623
|
+
title: 'Custom Section',
|
|
624
|
+
render: ()=>/*#__PURE__*/ jsx("div", {
|
|
625
|
+
children: "Custom content"
|
|
626
|
+
})
|
|
627
|
+
}
|
|
628
|
+
];
|
|
629
|
+
render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
630
|
+
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
631
|
+
children: /*#__PURE__*/ jsxs(BucketOverview, {
|
|
632
|
+
bucketName: "test-bucket",
|
|
633
|
+
children: [
|
|
634
|
+
/*#__PURE__*/ jsx(BucketOverview.Actions, {}),
|
|
635
|
+
/*#__PURE__*/ jsxs(BucketOverview.Sections, {
|
|
636
|
+
children: [
|
|
637
|
+
/*#__PURE__*/ jsx(BucketOverview.GeneralSection, {}),
|
|
638
|
+
extraSections.map((section)=>/*#__PURE__*/ jsx(BucketOverview.Section, {
|
|
639
|
+
title: section.title,
|
|
640
|
+
children: section.render()
|
|
641
|
+
}, section.id)),
|
|
642
|
+
/*#__PURE__*/ jsx(BucketOverview.DataProtectionSection, {}),
|
|
643
|
+
/*#__PURE__*/ jsx(BucketOverview.PermissionsSection, {})
|
|
644
|
+
]
|
|
645
|
+
})
|
|
646
|
+
]
|
|
647
|
+
})
|
|
648
|
+
})
|
|
649
|
+
}));
|
|
650
|
+
expect(screen.getByText('Custom Section')).toBeInTheDocument();
|
|
651
|
+
expect(screen.getByText('Custom content')).toBeInTheDocument();
|
|
652
|
+
});
|
|
653
|
+
it('extra sections have access to BucketOverview context', ()=>{
|
|
654
|
+
const CustomSectionContent = ()=>{
|
|
655
|
+
const { bucketName } = useBucketOverviewContext();
|
|
656
|
+
return /*#__PURE__*/ jsxs("div", {
|
|
657
|
+
children: [
|
|
658
|
+
"Bucket name from context: ",
|
|
659
|
+
bucketName
|
|
660
|
+
]
|
|
661
|
+
});
|
|
662
|
+
};
|
|
663
|
+
const Wrapper = createTestWrapper();
|
|
664
|
+
const extraSections = [
|
|
665
|
+
{
|
|
666
|
+
id: 'context-section',
|
|
667
|
+
title: 'Context Test',
|
|
668
|
+
render: ()=>/*#__PURE__*/ jsx(CustomSectionContent, {})
|
|
669
|
+
}
|
|
670
|
+
];
|
|
671
|
+
render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
672
|
+
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
673
|
+
children: /*#__PURE__*/ jsxs(BucketOverview, {
|
|
674
|
+
bucketName: "my-custom-bucket",
|
|
675
|
+
children: [
|
|
676
|
+
/*#__PURE__*/ jsx(BucketOverview.Actions, {}),
|
|
677
|
+
/*#__PURE__*/ jsxs(BucketOverview.Sections, {
|
|
678
|
+
children: [
|
|
679
|
+
/*#__PURE__*/ jsx(BucketOverview.GeneralSection, {}),
|
|
680
|
+
extraSections.map((section)=>/*#__PURE__*/ jsx(BucketOverview.Section, {
|
|
681
|
+
title: section.title,
|
|
682
|
+
children: section.render()
|
|
683
|
+
}, section.id)),
|
|
684
|
+
/*#__PURE__*/ jsx(BucketOverview.DataProtectionSection, {}),
|
|
685
|
+
/*#__PURE__*/ jsx(BucketOverview.PermissionsSection, {})
|
|
686
|
+
]
|
|
687
|
+
})
|
|
688
|
+
]
|
|
689
|
+
})
|
|
690
|
+
})
|
|
691
|
+
}));
|
|
692
|
+
expect(screen.getByText('Bucket name from context: my-custom-bucket')).toBeInTheDocument();
|
|
637
693
|
});
|
|
638
694
|
});
|
|
639
|
-
describe(
|
|
640
|
-
it(
|
|
695
|
+
describe('Field Overrides', ()=>{
|
|
696
|
+
it('renders slot-based field override', ()=>{
|
|
641
697
|
const Wrapper = createTestWrapper();
|
|
642
|
-
render(/*#__PURE__*/ jsx(
|
|
698
|
+
render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
643
699
|
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
644
700
|
children: /*#__PURE__*/ jsxs(BucketOverview, {
|
|
645
701
|
bucketName: "test-bucket",
|
|
@@ -660,12 +716,12 @@ describe("BucketOverview", ()=>{
|
|
|
660
716
|
})
|
|
661
717
|
})
|
|
662
718
|
}));
|
|
663
|
-
expect(screen.getByText(
|
|
664
|
-
expect(screen.getByText(
|
|
719
|
+
expect(screen.getByText('Custom Location Content')).toBeInTheDocument();
|
|
720
|
+
expect(screen.getByText('test-bucket')).toBeInTheDocument();
|
|
665
721
|
});
|
|
666
|
-
it(
|
|
722
|
+
it('renders render prop field override', ()=>{
|
|
667
723
|
const Wrapper = createTestWrapper();
|
|
668
|
-
render(/*#__PURE__*/ jsx(
|
|
724
|
+
render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
669
725
|
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
670
726
|
children: /*#__PURE__*/ jsxs(BucketOverview, {
|
|
671
727
|
bucketName: "test-bucket",
|
|
@@ -689,14 +745,14 @@ describe("BucketOverview", ()=>{
|
|
|
689
745
|
})
|
|
690
746
|
})
|
|
691
747
|
}));
|
|
692
|
-
expect(screen.getByText(
|
|
748
|
+
expect(screen.getByText('Custom Versioning for test-bucket')).toBeInTheDocument();
|
|
693
749
|
});
|
|
694
|
-
it(
|
|
750
|
+
it('prioritizes slot prop over render prop over default', ()=>{
|
|
695
751
|
const Wrapper = createTestWrapper();
|
|
696
752
|
const renderName = jest.fn(()=>/*#__PURE__*/ jsx("span", {
|
|
697
753
|
children: "Render Prop Name"
|
|
698
754
|
}));
|
|
699
|
-
render(/*#__PURE__*/ jsx(
|
|
755
|
+
render(/*#__PURE__*/ jsx(MemoryRouter, {
|
|
700
756
|
children: /*#__PURE__*/ jsx(Wrapper, {
|
|
701
757
|
children: /*#__PURE__*/ jsxs(BucketOverview, {
|
|
702
758
|
bucketName: "test-bucket",
|
|
@@ -718,7 +774,7 @@ describe("BucketOverview", ()=>{
|
|
|
718
774
|
})
|
|
719
775
|
})
|
|
720
776
|
}));
|
|
721
|
-
expect(screen.getByText(
|
|
777
|
+
expect(screen.getByText('Slot Prop Name')).toBeInTheDocument();
|
|
722
778
|
expect(renderName).not.toHaveBeenCalled();
|
|
723
779
|
});
|
|
724
780
|
});
|