@scality/data-browser-library 1.0.0-preview.8 → 1.0.0-preview.9
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/__tests__/BucketCreate.test.d.ts +1 -0
- package/dist/components/__tests__/BucketCreate.test.js +408 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +1 -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 +190 -0
- package/dist/components/__tests__/BucketOverview.test.js +298 -8
- package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +1 -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__/DeleteBucketConfigRuleButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +196 -0
- package/dist/components/__tests__/EmptyBucketButton.test.d.ts +1 -0
- package/dist/components/__tests__/EmptyBucketButton.test.js +302 -0
- package/dist/components/buckets/BucketCreate.d.ts +49 -0
- package/dist/components/buckets/BucketCreate.js +237 -0
- package/dist/components/buckets/BucketDetails.js +62 -10
- package/dist/components/buckets/BucketLifecycleFormPage.d.ts +15 -0
- package/dist/components/buckets/BucketLifecycleFormPage.js +1070 -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 +5 -2
- package/dist/components/buckets/BucketList.js +38 -28
- package/dist/components/buckets/BucketOverview.d.ts +65 -4
- package/dist/components/buckets/BucketOverview.js +261 -179
- package/dist/components/buckets/BucketPage.js +1 -1
- package/dist/components/buckets/BucketReplicationFormPage.d.ts +1 -0
- package/dist/components/buckets/BucketReplicationFormPage.js +834 -0
- package/dist/components/buckets/BucketReplicationList.d.ts +11 -0
- package/dist/components/buckets/BucketReplicationList.js +189 -0
- 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/index.d.ts +8 -1
- package/dist/components/index.js +9 -2
- 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 +158 -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/ui/ArrayFieldActions.d.ts +36 -0
- package/dist/components/ui/ArrayFieldActions.js +38 -0
- package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +16 -0
- package/dist/components/ui/ConfirmDeleteRuleModal.js +43 -0
- package/dist/components/ui/FilterFormSection.d.ts +44 -0
- package/dist/components/ui/FilterFormSection.js +159 -0
- package/dist/config/factory.d.ts +13 -2
- package/dist/config/factory.js +9 -6
- package/dist/hooks/__tests__/useISVBucketDetection.test.d.ts +1 -0
- package/dist/hooks/__tests__/useISVBucketDetection.test.js +188 -0
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +44 -1
- package/dist/hooks/factories/useCreateS3QueryHook.js +22 -1
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +5 -1
- 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/useISVBucketDetection.d.ts +15 -0
- package/dist/hooks/useISVBucketDetection.js +27 -0
- package/dist/hooks/useTableRowSelection.d.ts +9 -0
- package/dist/hooks/useTableRowSelection.js +45 -0
- package/dist/test/testUtils.d.ts +99 -17
- package/dist/test/testUtils.js +64 -16
- package/dist/test/utils/errorHandling.test.js +39 -1
- package/dist/utils/constants.d.ts +12 -0
- package/dist/utils/constants.js +9 -0
- package/dist/utils/errorHandling.d.ts +9 -0
- package/dist/utils/errorHandling.js +6 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/s3RuleUtils.d.ts +53 -0
- package/dist/utils/s3RuleUtils.js +101 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,408 @@
|
|
|
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 } from "react-router-dom";
|
|
5
|
+
import { createMockMutationResult, createTestWrapper } from "../../test/testUtils.js";
|
|
6
|
+
import { BucketCreate } from "../buckets/BucketCreate.js";
|
|
7
|
+
import { useCreateBucket, useSetBucketObjectLockConfiguration, useSetBucketVersioning } from "../../hooks/index.js";
|
|
8
|
+
jest.mock("../../hooks", ()=>({
|
|
9
|
+
useCreateBucket: jest.fn(),
|
|
10
|
+
useSetBucketVersioning: jest.fn(),
|
|
11
|
+
useSetBucketObjectLockConfiguration: jest.fn()
|
|
12
|
+
}));
|
|
13
|
+
const mockUseCreateBucket = jest.mocked(useCreateBucket);
|
|
14
|
+
const mockUseSetBucketVersioning = jest.mocked(useSetBucketVersioning);
|
|
15
|
+
const mockUseSetBucketObjectLockConfiguration = jest.mocked(useSetBucketObjectLockConfiguration);
|
|
16
|
+
const mockNavigate = jest.fn();
|
|
17
|
+
const mockShowToast = jest.fn();
|
|
18
|
+
jest.mock("react-router", ()=>({
|
|
19
|
+
...jest.requireActual("react-router"),
|
|
20
|
+
useNavigate: ()=>mockNavigate
|
|
21
|
+
}));
|
|
22
|
+
jest.mock("@scality/core-ui", ()=>({
|
|
23
|
+
...jest.requireActual("@scality/core-ui"),
|
|
24
|
+
useToast: ()=>({
|
|
25
|
+
showToast: mockShowToast
|
|
26
|
+
})
|
|
27
|
+
}));
|
|
28
|
+
const renderBucketCreate = (props = {})=>{
|
|
29
|
+
const Wrapper = createTestWrapper();
|
|
30
|
+
return render(/*#__PURE__*/ jsx(Wrapper, {
|
|
31
|
+
children: /*#__PURE__*/ jsx(MemoryRouter, {
|
|
32
|
+
children: /*#__PURE__*/ jsx(BucketCreate, {
|
|
33
|
+
...props
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
}));
|
|
37
|
+
};
|
|
38
|
+
const mockMutations = {
|
|
39
|
+
createBucket: jest.fn(),
|
|
40
|
+
setVersioning: jest.fn(),
|
|
41
|
+
setObjectLock: jest.fn()
|
|
42
|
+
};
|
|
43
|
+
const setupMocks = (overrides = {})=>{
|
|
44
|
+
mockUseCreateBucket.mockReturnValue(createMockMutationResult(mockMutations.createBucket, overrides));
|
|
45
|
+
mockUseSetBucketVersioning.mockReturnValue(createMockMutationResult(mockMutations.setVersioning));
|
|
46
|
+
mockUseSetBucketObjectLockConfiguration.mockReturnValue(createMockMutationResult(mockMutations.setObjectLock));
|
|
47
|
+
};
|
|
48
|
+
const fillBucketName = async (name)=>{
|
|
49
|
+
const nameInput = screen.getByLabelText(/bucket name/i);
|
|
50
|
+
await user_event.type(nameInput, name);
|
|
51
|
+
};
|
|
52
|
+
const submitForm = async ()=>{
|
|
53
|
+
await waitFor(()=>{
|
|
54
|
+
const createButton = screen.getByRole("button", {
|
|
55
|
+
name: /^create$/i
|
|
56
|
+
});
|
|
57
|
+
expect(createButton).not.toBeDisabled();
|
|
58
|
+
}, {
|
|
59
|
+
timeout: 3000
|
|
60
|
+
});
|
|
61
|
+
const createButton = screen.getByRole("button", {
|
|
62
|
+
name: /^create$/i
|
|
63
|
+
});
|
|
64
|
+
await user_event.click(createButton);
|
|
65
|
+
};
|
|
66
|
+
describe("BucketCreate", ()=>{
|
|
67
|
+
beforeEach(()=>{
|
|
68
|
+
jest.clearAllMocks();
|
|
69
|
+
setupMocks();
|
|
70
|
+
});
|
|
71
|
+
it("renders form with required fields", ()=>{
|
|
72
|
+
renderBucketCreate();
|
|
73
|
+
expect(screen.getByText("Create a New Bucket")).toBeInTheDocument();
|
|
74
|
+
expect(screen.getByLabelText(/bucket name/i)).toBeInTheDocument();
|
|
75
|
+
expect(screen.getByText("Versioning")).toBeInTheDocument();
|
|
76
|
+
expect(screen.getByText("Object-lock")).toBeInTheDocument();
|
|
77
|
+
});
|
|
78
|
+
it("shows validation error for invalid bucket name with uppercase", async ()=>{
|
|
79
|
+
renderBucketCreate();
|
|
80
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "INVALID");
|
|
81
|
+
await user_event.tab();
|
|
82
|
+
await waitFor(()=>{
|
|
83
|
+
expect(screen.getByText(/bucket names can include only lowercase/i)).toBeInTheDocument();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
it("shows validation error for bucket name starting with hyphen", async ()=>{
|
|
87
|
+
renderBucketCreate();
|
|
88
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "-invalid");
|
|
89
|
+
await user_event.tab();
|
|
90
|
+
await waitFor(()=>{
|
|
91
|
+
expect(screen.getByText(/bucket names can include only lowercase/i)).toBeInTheDocument();
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
it("shows validation error for bucket name ending with hyphen", async ()=>{
|
|
95
|
+
renderBucketCreate();
|
|
96
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "invalid-");
|
|
97
|
+
await user_event.tab();
|
|
98
|
+
await waitFor(()=>{
|
|
99
|
+
expect(screen.getByText(/bucket names can include only lowercase/i)).toBeInTheDocument();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
it("shows validation error for bucket name with adjacent periods", async ()=>{
|
|
103
|
+
renderBucketCreate();
|
|
104
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "test..bucket");
|
|
105
|
+
await user_event.tab();
|
|
106
|
+
await waitFor(()=>{
|
|
107
|
+
expect(screen.getByText(/bucket names cannot contain two adjacent periods/i)).toBeInTheDocument();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
it("shows validation error for bucket name formatted as IP address", async ()=>{
|
|
111
|
+
renderBucketCreate();
|
|
112
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "192.168.1.1");
|
|
113
|
+
await user_event.tab();
|
|
114
|
+
await waitFor(()=>{
|
|
115
|
+
expect(screen.getByText(/bucket names must not be formatted as an ip address/i)).toBeInTheDocument();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
it("shows validation error for bucket name with forbidden prefix", async ()=>{
|
|
119
|
+
renderBucketCreate();
|
|
120
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "xn--test");
|
|
121
|
+
await user_event.tab();
|
|
122
|
+
await waitFor(()=>{
|
|
123
|
+
expect(screen.getByText(/bucket names must not start with/i)).toBeInTheDocument();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it("shows validation error for bucket name with forbidden suffix", async ()=>{
|
|
127
|
+
renderBucketCreate();
|
|
128
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "test-s3alias");
|
|
129
|
+
await user_event.tab();
|
|
130
|
+
await waitFor(()=>{
|
|
131
|
+
expect(screen.getByText(/bucket names must not end with/i)).toBeInTheDocument();
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
it("shows validation error for duplicate bucket name when context provided", async ()=>{
|
|
135
|
+
renderBucketCreate({
|
|
136
|
+
validationContext: {
|
|
137
|
+
existingBuckets: [
|
|
138
|
+
"existing-bucket",
|
|
139
|
+
"another-bucket"
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
await user_event.type(screen.getByLabelText(/bucket name/i), "existing-bucket");
|
|
144
|
+
await user_event.tab();
|
|
145
|
+
await waitFor(()=>{
|
|
146
|
+
expect(screen.getByText(/a bucket with this name already exists/i)).toBeInTheDocument();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
it("accepts valid bucket names with dots and hyphens", async ()=>{
|
|
150
|
+
renderBucketCreate();
|
|
151
|
+
const validNames = [
|
|
152
|
+
"my-bucket-123",
|
|
153
|
+
"my.bucket.name",
|
|
154
|
+
"test-bucket.example",
|
|
155
|
+
"123-bucket-456"
|
|
156
|
+
];
|
|
157
|
+
for (const name of validNames){
|
|
158
|
+
const input = screen.getByLabelText(/bucket name/i);
|
|
159
|
+
await user_event.clear(input);
|
|
160
|
+
await user_event.type(input, name);
|
|
161
|
+
await user_event.tab();
|
|
162
|
+
await waitFor(()=>{
|
|
163
|
+
expect(screen.queryByText(/bucket names must be 3-63 characters/i)).not.toBeInTheDocument();
|
|
164
|
+
expect(screen.queryByText(/bucket names cannot contain/i)).not.toBeInTheDocument();
|
|
165
|
+
expect(screen.queryByText(/bucket names must not/i)).not.toBeInTheDocument();
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
it("allows bucket creation when name is unique", async ()=>{
|
|
170
|
+
renderBucketCreate({
|
|
171
|
+
validationContext: {
|
|
172
|
+
existingBuckets: [
|
|
173
|
+
"existing-bucket",
|
|
174
|
+
"another-bucket"
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
await fillBucketName("new-unique-bucket");
|
|
179
|
+
await waitFor(()=>{
|
|
180
|
+
expect(screen.getByRole("button", {
|
|
181
|
+
name: /^create$/i
|
|
182
|
+
})).not.toBeDisabled();
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
it("disables create button when form is invalid", ()=>{
|
|
186
|
+
renderBucketCreate();
|
|
187
|
+
expect(screen.getByRole("button", {
|
|
188
|
+
name: /^create$/i
|
|
189
|
+
})).toBeDisabled();
|
|
190
|
+
});
|
|
191
|
+
it("enables create button when bucket name is valid", async ()=>{
|
|
192
|
+
renderBucketCreate();
|
|
193
|
+
await fillBucketName("test-bucket");
|
|
194
|
+
await waitFor(()=>{
|
|
195
|
+
expect(screen.getByRole("button", {
|
|
196
|
+
name: /^create$/i
|
|
197
|
+
})).not.toBeDisabled();
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
it("creates bucket with basic configuration", async ()=>{
|
|
201
|
+
renderBucketCreate();
|
|
202
|
+
await fillBucketName("test-bucket");
|
|
203
|
+
await submitForm();
|
|
204
|
+
expect(mockMutations.createBucket).toHaveBeenCalledWith({
|
|
205
|
+
Bucket: "test-bucket",
|
|
206
|
+
ObjectLockEnabledForBucket: void 0
|
|
207
|
+
}, expect.objectContaining({
|
|
208
|
+
onSuccess: expect.any(Function),
|
|
209
|
+
onError: expect.any(Function)
|
|
210
|
+
}));
|
|
211
|
+
});
|
|
212
|
+
it("shows success toast and navigates after bucket creation", async ()=>{
|
|
213
|
+
renderBucketCreate();
|
|
214
|
+
await fillBucketName("my-bucket");
|
|
215
|
+
await submitForm();
|
|
216
|
+
const successCallback = mockMutations.createBucket.mock.calls[0][1].onSuccess;
|
|
217
|
+
successCallback();
|
|
218
|
+
expect(mockShowToast).toHaveBeenCalledWith({
|
|
219
|
+
open: true,
|
|
220
|
+
message: 'Bucket "my-bucket" created successfully',
|
|
221
|
+
status: "success"
|
|
222
|
+
});
|
|
223
|
+
expect(mockNavigate).toHaveBeenCalledWith("/buckets/my-bucket");
|
|
224
|
+
});
|
|
225
|
+
it("shows error toast when bucket creation fails", async ()=>{
|
|
226
|
+
renderBucketCreate();
|
|
227
|
+
await fillBucketName("test-bucket");
|
|
228
|
+
await submitForm();
|
|
229
|
+
const errorCallback = mockMutations.createBucket.mock.calls[0][1].onError;
|
|
230
|
+
const error = new Error("Bucket already exists");
|
|
231
|
+
errorCallback(error);
|
|
232
|
+
expect(mockShowToast).toHaveBeenCalledWith({
|
|
233
|
+
open: true,
|
|
234
|
+
message: "Bucket already exists",
|
|
235
|
+
status: "error"
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
it("enables versioning when requested", async ()=>{
|
|
239
|
+
renderBucketCreate();
|
|
240
|
+
await fillBucketName("test-bucket");
|
|
241
|
+
const versioningCheckbox = screen.getByRole("checkbox", {
|
|
242
|
+
name: /versioning/i
|
|
243
|
+
});
|
|
244
|
+
await user_event.click(versioningCheckbox);
|
|
245
|
+
await submitForm();
|
|
246
|
+
const successCallback = mockMutations.createBucket.mock.calls[0][1].onSuccess;
|
|
247
|
+
successCallback();
|
|
248
|
+
expect(mockMutations.setVersioning).toHaveBeenCalledWith({
|
|
249
|
+
Bucket: "test-bucket",
|
|
250
|
+
VersioningConfiguration: {
|
|
251
|
+
Status: "Enabled"
|
|
252
|
+
}
|
|
253
|
+
}, expect.objectContaining({
|
|
254
|
+
onSuccess: expect.any(Function),
|
|
255
|
+
onError: expect.any(Function)
|
|
256
|
+
}));
|
|
257
|
+
});
|
|
258
|
+
it("disables versioning checkbox when object lock is enabled", async ()=>{
|
|
259
|
+
renderBucketCreate();
|
|
260
|
+
await fillBucketName("test-bucket");
|
|
261
|
+
const objectLockCheckbox = screen.getByRole("checkbox", {
|
|
262
|
+
name: /object-lock/i
|
|
263
|
+
});
|
|
264
|
+
await user_event.click(objectLockCheckbox);
|
|
265
|
+
const versioningCheckbox = screen.getByRole("checkbox", {
|
|
266
|
+
name: /versioning/i
|
|
267
|
+
});
|
|
268
|
+
expect(versioningCheckbox).toBeDisabled();
|
|
269
|
+
expect(screen.getByText(/automatically activated when object-lock is enabled/i)).toBeInTheDocument();
|
|
270
|
+
});
|
|
271
|
+
it("enables versioning automatically when object lock is enabled", async ()=>{
|
|
272
|
+
renderBucketCreate();
|
|
273
|
+
await fillBucketName("test-bucket");
|
|
274
|
+
const objectLockCheckbox = screen.getByRole("checkbox", {
|
|
275
|
+
name: /object-lock/i
|
|
276
|
+
});
|
|
277
|
+
await user_event.click(objectLockCheckbox);
|
|
278
|
+
await submitForm();
|
|
279
|
+
expect(mockMutations.createBucket).toHaveBeenCalledWith(expect.objectContaining({
|
|
280
|
+
ObjectLockEnabledForBucket: true
|
|
281
|
+
}), expect.any(Object));
|
|
282
|
+
const successCallback = mockMutations.createBucket.mock.calls[0][1].onSuccess;
|
|
283
|
+
successCallback();
|
|
284
|
+
expect(mockMutations.setVersioning).not.toHaveBeenCalled();
|
|
285
|
+
});
|
|
286
|
+
it("configures object lock retention when enabled", async ()=>{
|
|
287
|
+
renderBucketCreate();
|
|
288
|
+
await fillBucketName("test-bucket");
|
|
289
|
+
await user_event.click(screen.getByRole("checkbox", {
|
|
290
|
+
name: /object-lock/i
|
|
291
|
+
}));
|
|
292
|
+
await user_event.click(screen.getByRole("checkbox", {
|
|
293
|
+
name: /default retention/i
|
|
294
|
+
}));
|
|
295
|
+
await submitForm();
|
|
296
|
+
const createSuccessCallback = mockMutations.createBucket.mock.calls[0][1].onSuccess;
|
|
297
|
+
createSuccessCallback();
|
|
298
|
+
expect(mockMutations.setVersioning).not.toHaveBeenCalled();
|
|
299
|
+
expect(mockMutations.setObjectLock).toHaveBeenCalledWith({
|
|
300
|
+
Bucket: "test-bucket",
|
|
301
|
+
ObjectLockConfiguration: {
|
|
302
|
+
ObjectLockEnabled: "Enabled",
|
|
303
|
+
Rule: {
|
|
304
|
+
DefaultRetention: {
|
|
305
|
+
Mode: "GOVERNANCE",
|
|
306
|
+
Days: 1,
|
|
307
|
+
Years: void 0
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}, expect.objectContaining({
|
|
312
|
+
onSuccess: expect.any(Function),
|
|
313
|
+
onError: expect.any(Function)
|
|
314
|
+
}));
|
|
315
|
+
});
|
|
316
|
+
it("calls custom onSubmit when provided", async ()=>{
|
|
317
|
+
const customSubmit = jest.fn();
|
|
318
|
+
renderBucketCreate({
|
|
319
|
+
onSubmit: customSubmit
|
|
320
|
+
});
|
|
321
|
+
await fillBucketName("test-bucket");
|
|
322
|
+
await submitForm();
|
|
323
|
+
expect(customSubmit).toHaveBeenCalledWith(expect.objectContaining({
|
|
324
|
+
name: "test-bucket",
|
|
325
|
+
isVersioning: false,
|
|
326
|
+
isObjectLockEnabled: false
|
|
327
|
+
}));
|
|
328
|
+
expect(mockMutations.createBucket).not.toHaveBeenCalled();
|
|
329
|
+
});
|
|
330
|
+
it("calls custom onCancel when provided", ()=>{
|
|
331
|
+
const customCancel = jest.fn();
|
|
332
|
+
renderBucketCreate({
|
|
333
|
+
onCancel: customCancel
|
|
334
|
+
});
|
|
335
|
+
const cancelButton = screen.getByRole("button", {
|
|
336
|
+
name: /cancel/i
|
|
337
|
+
});
|
|
338
|
+
fireEvent.click(cancelButton);
|
|
339
|
+
expect(customCancel).toHaveBeenCalled();
|
|
340
|
+
expect(mockNavigate).not.toHaveBeenCalled();
|
|
341
|
+
});
|
|
342
|
+
it("navigates to buckets list when cancel is clicked without custom handler", ()=>{
|
|
343
|
+
renderBucketCreate();
|
|
344
|
+
const cancelButton = screen.getByRole("button", {
|
|
345
|
+
name: /cancel/i
|
|
346
|
+
});
|
|
347
|
+
fireEvent.click(cancelButton);
|
|
348
|
+
expect(mockNavigate).toHaveBeenCalledWith("/buckets");
|
|
349
|
+
});
|
|
350
|
+
it("renders injected children", ()=>{
|
|
351
|
+
renderBucketCreate({
|
|
352
|
+
children: /*#__PURE__*/ jsx("div", {
|
|
353
|
+
"data-testid": "custom-field",
|
|
354
|
+
children: "Custom Field"
|
|
355
|
+
})
|
|
356
|
+
});
|
|
357
|
+
expect(screen.getByTestId("custom-field")).toBeInTheDocument();
|
|
358
|
+
});
|
|
359
|
+
it("shows loading state during bucket creation", async ()=>{
|
|
360
|
+
renderBucketCreate();
|
|
361
|
+
await fillBucketName("test-bucket");
|
|
362
|
+
await submitForm();
|
|
363
|
+
setupMocks({
|
|
364
|
+
isPending: true
|
|
365
|
+
});
|
|
366
|
+
expect(mockMutations.createBucket).toHaveBeenCalled();
|
|
367
|
+
});
|
|
368
|
+
it("shows error toast when versioning configuration fails", async ()=>{
|
|
369
|
+
renderBucketCreate();
|
|
370
|
+
await fillBucketName("test-bucket");
|
|
371
|
+
await user_event.click(screen.getByRole("checkbox", {
|
|
372
|
+
name: /versioning/i
|
|
373
|
+
}));
|
|
374
|
+
await submitForm();
|
|
375
|
+
const createSuccessCallback = mockMutations.createBucket.mock.calls[0][1].onSuccess;
|
|
376
|
+
createSuccessCallback();
|
|
377
|
+
const versioningErrorCallback = mockMutations.setVersioning.mock.calls[0][1].onError;
|
|
378
|
+
const error = new Error("Failed to enable versioning");
|
|
379
|
+
versioningErrorCallback(error);
|
|
380
|
+
expect(mockShowToast).toHaveBeenCalledWith({
|
|
381
|
+
open: true,
|
|
382
|
+
message: "Failed to enable versioning",
|
|
383
|
+
status: "error"
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
it("shows error toast when object lock configuration fails", async ()=>{
|
|
387
|
+
renderBucketCreate();
|
|
388
|
+
await fillBucketName("test-bucket");
|
|
389
|
+
await user_event.click(screen.getByRole("checkbox", {
|
|
390
|
+
name: /object-lock/i
|
|
391
|
+
}));
|
|
392
|
+
await user_event.click(screen.getByRole("checkbox", {
|
|
393
|
+
name: /default retention/i
|
|
394
|
+
}));
|
|
395
|
+
await submitForm();
|
|
396
|
+
const createSuccessCallback = mockMutations.createBucket.mock.calls[0][1].onSuccess;
|
|
397
|
+
createSuccessCallback();
|
|
398
|
+
expect(mockMutations.setVersioning).not.toHaveBeenCalled();
|
|
399
|
+
const objectLockErrorCallback = mockMutations.setObjectLock.mock.calls[0][1].onError;
|
|
400
|
+
const error = new Error("Failed to configure retention");
|
|
401
|
+
objectLockErrorCallback(error);
|
|
402
|
+
expect(mockShowToast).toHaveBeenCalledWith({
|
|
403
|
+
open: true,
|
|
404
|
+
message: "Failed to configure retention",
|
|
405
|
+
status: "error"
|
|
406
|
+
});
|
|
407
|
+
});
|
|
408
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|