@scality/data-browser-library 1.0.0-preview.2
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/Editor.d.ts +12 -0
- package/dist/components/Editor.js +28 -0
- package/dist/components/__tests__/BucketList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketList.test.js +225 -0
- package/dist/components/__tests__/BucketOverview.test.d.ts +1 -0
- package/dist/components/__tests__/BucketOverview.test.js +479 -0
- package/dist/components/__tests__/BucketPolicyPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketPolicyPage.test.js +213 -0
- package/dist/components/__tests__/CreateFolderButton.test.d.ts +1 -0
- package/dist/components/__tests__/CreateFolderButton.test.js +147 -0
- package/dist/components/__tests__/DeleteBucketButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteBucketButton.test.js +272 -0
- package/dist/components/__tests__/DeleteObjectButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteObjectButton.test.js +302 -0
- package/dist/components/__tests__/MetadataSearch.test.d.ts +1 -0
- package/dist/components/__tests__/MetadataSearch.test.js +201 -0
- package/dist/components/__tests__/ObjectList.test.d.ts +1 -0
- package/dist/components/__tests__/ObjectList.test.js +283 -0
- package/dist/components/__tests__/UploadButton.test.d.ts +1 -0
- package/dist/components/__tests__/UploadButton.test.js +144 -0
- package/dist/components/buckets/BucketDetails.d.ts +1 -0
- package/dist/components/buckets/BucketDetails.js +51 -0
- package/dist/components/buckets/BucketList.d.ts +12 -0
- package/dist/components/buckets/BucketList.js +136 -0
- package/dist/components/buckets/BucketLocation.d.ts +3 -0
- package/dist/components/buckets/BucketLocation.js +16 -0
- package/dist/components/buckets/BucketOverview.d.ts +14 -0
- package/dist/components/buckets/BucketOverview.js +209 -0
- package/dist/components/buckets/BucketPage.d.ts +2 -0
- package/dist/components/buckets/BucketPage.js +47 -0
- package/dist/components/buckets/BucketPolicyButton.d.ts +7 -0
- package/dist/components/buckets/BucketPolicyButton.js +18 -0
- package/dist/components/buckets/BucketPolicyPage.d.ts +1 -0
- package/dist/components/buckets/BucketPolicyPage.js +205 -0
- package/dist/components/buckets/DeleteBucketButton.d.ts +8 -0
- package/dist/components/buckets/DeleteBucketButton.js +78 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/components/index.js +13 -0
- package/dist/components/layouts/BrowserPageLayout.d.ts +9 -0
- package/dist/components/layouts/BrowserPageLayout.js +46 -0
- package/dist/components/objects/CreateFolderButton.d.ts +29 -0
- package/dist/components/objects/CreateFolderButton.js +118 -0
- package/dist/components/objects/DeleteObjectButton.d.ts +8 -0
- package/dist/components/objects/DeleteObjectButton.js +191 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.js +323 -0
- package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +3 -0
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +193 -0
- package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +3 -0
- package/dist/components/objects/ObjectDetails/ObjectTags.js +300 -0
- package/dist/components/objects/ObjectDetails/index.d.ts +9 -0
- package/dist/components/objects/ObjectDetails/index.js +49 -0
- package/dist/components/objects/ObjectList.d.ts +40 -0
- package/dist/components/objects/ObjectList.js +407 -0
- package/dist/components/objects/ObjectPage.d.ts +1 -0
- package/dist/components/objects/ObjectPage.js +43 -0
- package/dist/components/objects/UploadButton.d.ts +34 -0
- package/dist/components/objects/UploadButton.js +229 -0
- package/dist/components/providers/DataBrowserProvider.d.ts +20 -0
- package/dist/components/providers/DataBrowserProvider.js +42 -0
- package/dist/components/search/MetadataSearch.d.ts +5 -0
- package/dist/components/search/MetadataSearch.js +162 -0
- package/dist/components/search/SearchHints.d.ts +8 -0
- package/dist/components/search/SearchHints.js +21 -0
- package/dist/components/ui/DeleteObjectModalContent.d.ts +5 -0
- package/dist/components/ui/DeleteObjectModalContent.js +71 -0
- package/dist/components/ui/Search.elements.d.ts +17 -0
- package/dist/components/ui/Search.elements.js +59 -0
- package/dist/components/ui/Table.elements.d.ts +36 -0
- package/dist/components/ui/Table.elements.js +87 -0
- package/dist/config/factory.d.ts +52 -0
- package/dist/config/factory.js +70 -0
- package/dist/config/types.d.ts +46 -0
- package/dist/config/types.js +0 -0
- package/dist/hooks/__tests__/useIsBucketEmpty.test.d.ts +1 -0
- package/dist/hooks/__tests__/useIsBucketEmpty.test.js +122 -0
- package/dist/hooks/bucketConfiguration.d.ts +147 -0
- package/dist/hooks/bucketConfiguration.js +59 -0
- package/dist/hooks/bucketOperations.d.ts +36 -0
- package/dist/hooks/bucketOperations.js +12 -0
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +276 -0
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +259 -0
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +166 -0
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +200 -0
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +136 -0
- package/dist/hooks/factories/index.d.ts +18 -0
- package/dist/hooks/factories/index.js +5 -0
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +13 -0
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +76 -0
- package/dist/hooks/factories/useCreateS3LoginHook.d.ts +8 -0
- package/dist/hooks/factories/useCreateS3LoginHook.js +22 -0
- package/dist/hooks/factories/useCreateS3MutationHook.d.ts +5 -0
- package/dist/hooks/factories/useCreateS3MutationHook.js +50 -0
- package/dist/hooks/factories/useCreateS3QueryHook.d.ts +3 -0
- package/dist/hooks/factories/useCreateS3QueryHook.js +30 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/loginOperations.d.ts +21 -0
- package/dist/hooks/loginOperations.js +9 -0
- package/dist/hooks/objectOperations.d.ts +190 -0
- package/dist/hooks/objectOperations.js +66 -0
- package/dist/hooks/presignedOperations.d.ts +73 -0
- package/dist/hooks/presignedOperations.js +72 -0
- package/dist/hooks/useIsBucketEmpty.d.ts +7 -0
- package/dist/hooks/useIsBucketEmpty.js +36 -0
- package/dist/hooks/useLoginMutation.d.ts +21 -0
- package/dist/hooks/useLoginMutation.js +9 -0
- package/dist/hooks/useS3Client.d.ts +1 -0
- package/dist/hooks/useS3Client.js +13 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/schemas/bucketPolicySchema.json +321 -0
- package/dist/test/msw/handlers/deleteBucket.d.ts +1 -0
- package/dist/test/msw/handlers/deleteBucket.js +14 -0
- package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -0
- package/dist/test/msw/handlers/getBucketAcl.js +96 -0
- package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -0
- package/dist/test/msw/handlers/getBucketLocation.js +23 -0
- package/dist/test/msw/handlers/getBucketPolicy.d.ts +11 -0
- package/dist/test/msw/handlers/getBucketPolicy.js +72 -0
- package/dist/test/msw/handlers/headObject.d.ts +1 -0
- package/dist/test/msw/handlers/headObject.js +17 -0
- package/dist/test/msw/handlers/listBuckets.d.ts +1 -0
- package/dist/test/msw/handlers/listBuckets.js +24 -0
- package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -0
- package/dist/test/msw/handlers/listObjectVersions.js +83 -0
- package/dist/test/msw/handlers/listObjects.d.ts +1 -0
- package/dist/test/msw/handlers/listObjects.js +66 -0
- package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -0
- package/dist/test/msw/handlers/objectLegalHold.js +24 -0
- package/dist/test/msw/handlers/objectRetention.d.ts +1 -0
- package/dist/test/msw/handlers/objectRetention.js +27 -0
- package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -0
- package/dist/test/msw/handlers/putBucketAcl.js +18 -0
- package/dist/test/msw/handlers/putObject.d.ts +1 -0
- package/dist/test/msw/handlers/putObject.js +16 -0
- package/dist/test/msw/handlers.d.ts +4 -0
- package/dist/test/msw/handlers.js +109 -0
- package/dist/test/msw/index.d.ts +2 -0
- package/dist/test/msw/index.js +3 -0
- package/dist/test/msw/server.d.ts +4 -0
- package/dist/test/msw/server.js +20 -0
- package/dist/test/msw/utils.d.ts +2 -0
- package/dist/test/msw/utils.js +13 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +82 -0
- package/dist/test/testUtils.d.ts +82 -0
- package/dist/test/testUtils.js +236 -0
- package/dist/test/utils/errorHandling.test.d.ts +1 -0
- package/dist/test/utils/errorHandling.test.js +385 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.js +0 -0
- package/dist/utils/deletion/index.d.ts +2 -0
- package/dist/utils/deletion/index.js +2 -0
- package/dist/utils/deletion/messages.d.ts +5 -0
- package/dist/utils/deletion/messages.js +29 -0
- package/dist/utils/deletion/types.d.ts +11 -0
- package/dist/utils/deletion/types.js +0 -0
- package/dist/utils/errorHandling.d.ts +54 -0
- package/dist/utils/errorHandling.js +79 -0
- package/dist/utils/hooks.d.ts +2 -0
- package/dist/utils/hooks.js +26 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/proxyMiddleware.d.ts +18 -0
- package/dist/utils/proxyMiddleware.js +56 -0
- package/dist/utils/s3Client.d.ts +5 -0
- package/dist/utils/s3Client.js +35 -0
- package/dist/utils/useFeatures.d.ts +1 -0
- package/dist/utils/useFeatures.js +7 -0
- package/package.json +79 -0
|
@@ -0,0 +1,147 @@
|
|
|
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 { createTestWrapper } from "../../test/testUtils.js";
|
|
5
|
+
import { CreateFolderButton } from "../objects/CreateFolderButton.js";
|
|
6
|
+
describe("CreateFolderButton", ()=>{
|
|
7
|
+
const defaultProps = {
|
|
8
|
+
bucket: "test-bucket",
|
|
9
|
+
prefix: "test-prefix"
|
|
10
|
+
};
|
|
11
|
+
const renderCreateFolderButton = (props = {})=>{
|
|
12
|
+
const Wrapper = createTestWrapper();
|
|
13
|
+
return render(/*#__PURE__*/ jsx(Wrapper, {
|
|
14
|
+
children: /*#__PURE__*/ jsx(CreateFolderButton, {
|
|
15
|
+
...defaultProps,
|
|
16
|
+
...props
|
|
17
|
+
})
|
|
18
|
+
}));
|
|
19
|
+
};
|
|
20
|
+
it("renders button with default label", ()=>{
|
|
21
|
+
renderCreateFolderButton();
|
|
22
|
+
expect(screen.getByRole("button", {
|
|
23
|
+
name: /folder/i
|
|
24
|
+
})).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
it("renders button with custom label", ()=>{
|
|
27
|
+
renderCreateFolderButton({
|
|
28
|
+
label: "Add New Folder"
|
|
29
|
+
});
|
|
30
|
+
expect(screen.getByRole("button", {
|
|
31
|
+
name: /add new folder/i
|
|
32
|
+
})).toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
it("opens modal when button is clicked", async ()=>{
|
|
35
|
+
renderCreateFolderButton();
|
|
36
|
+
fireEvent.click(screen.getByRole("button", {
|
|
37
|
+
name: /folder/i
|
|
38
|
+
}));
|
|
39
|
+
await waitFor(()=>{
|
|
40
|
+
expect(screen.getByText("Create a folder")).toBeInTheDocument();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
it("closes modal when cancel button is clicked", async ()=>{
|
|
44
|
+
renderCreateFolderButton();
|
|
45
|
+
fireEvent.click(screen.getByRole("button", {
|
|
46
|
+
name: /folder/i
|
|
47
|
+
}));
|
|
48
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
49
|
+
fireEvent.click(screen.getByRole("button", {
|
|
50
|
+
name: /cancel/i
|
|
51
|
+
}));
|
|
52
|
+
await waitFor(()=>{
|
|
53
|
+
expect(screen.queryByText("Create a folder")).not.toBeInTheDocument();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
it("disables save button when folder name is empty", async ()=>{
|
|
57
|
+
renderCreateFolderButton();
|
|
58
|
+
fireEvent.click(screen.getByRole("button", {
|
|
59
|
+
name: /folder/i
|
|
60
|
+
}));
|
|
61
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
62
|
+
expect(screen.getByRole("button", {
|
|
63
|
+
name: /save/i
|
|
64
|
+
})).toBeDisabled();
|
|
65
|
+
});
|
|
66
|
+
it("enables save button when valid folder name is entered", async ()=>{
|
|
67
|
+
renderCreateFolderButton();
|
|
68
|
+
fireEvent.click(screen.getByRole("button", {
|
|
69
|
+
name: /folder/i
|
|
70
|
+
}));
|
|
71
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
72
|
+
await user_event.type(screen.getByRole("textbox"), "valid-folder");
|
|
73
|
+
expect(screen.getByRole("button", {
|
|
74
|
+
name: /save/i
|
|
75
|
+
})).toBeEnabled();
|
|
76
|
+
});
|
|
77
|
+
it("disables save button and shows error when folder name starts with slash", async ()=>{
|
|
78
|
+
renderCreateFolderButton();
|
|
79
|
+
fireEvent.click(screen.getByRole("button", {
|
|
80
|
+
name: /folder/i
|
|
81
|
+
}));
|
|
82
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
83
|
+
await user_event.type(screen.getByRole("textbox"), "/invalid-folder");
|
|
84
|
+
expect(screen.getByRole("button", {
|
|
85
|
+
name: /save/i
|
|
86
|
+
})).toBeDisabled();
|
|
87
|
+
});
|
|
88
|
+
it("triggers mutation when save is clicked with valid folder name", async ()=>{
|
|
89
|
+
renderCreateFolderButton();
|
|
90
|
+
fireEvent.click(screen.getByRole("button", {
|
|
91
|
+
name: /folder/i
|
|
92
|
+
}));
|
|
93
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
94
|
+
await user_event.type(screen.getByRole("textbox"), "test-folder");
|
|
95
|
+
const saveButton = screen.getByRole("button", {
|
|
96
|
+
name: /save/i
|
|
97
|
+
});
|
|
98
|
+
expect(saveButton).toBeEnabled();
|
|
99
|
+
fireEvent.click(saveButton);
|
|
100
|
+
expect(screen.getByText("Create a folder")).toBeInTheDocument();
|
|
101
|
+
});
|
|
102
|
+
it("clears folder name when modal is closed", async ()=>{
|
|
103
|
+
renderCreateFolderButton();
|
|
104
|
+
fireEvent.click(screen.getByRole("button", {
|
|
105
|
+
name: /folder/i
|
|
106
|
+
}));
|
|
107
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
108
|
+
await user_event.type(screen.getByRole("textbox"), "test-folder");
|
|
109
|
+
fireEvent.click(screen.getByRole("button", {
|
|
110
|
+
name: /cancel/i
|
|
111
|
+
}));
|
|
112
|
+
await waitFor(()=>{
|
|
113
|
+
expect(screen.queryByText("Create a folder")).not.toBeInTheDocument();
|
|
114
|
+
});
|
|
115
|
+
fireEvent.click(screen.getByRole("button", {
|
|
116
|
+
name: /folder/i
|
|
117
|
+
}));
|
|
118
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
119
|
+
expect(screen.getByRole("textbox")).toHaveValue("");
|
|
120
|
+
});
|
|
121
|
+
it("shows info message about folder creation", async ()=>{
|
|
122
|
+
renderCreateFolderButton();
|
|
123
|
+
fireEvent.click(screen.getByRole("button", {
|
|
124
|
+
name: /folder/i
|
|
125
|
+
}));
|
|
126
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
127
|
+
expect(screen.getByText("Creating a folder")).toBeInTheDocument();
|
|
128
|
+
expect(screen.getByText(/ensure the folder name does not begin with a slash/i)).toBeInTheDocument();
|
|
129
|
+
});
|
|
130
|
+
it("handles folder name validation correctly", async ()=>{
|
|
131
|
+
renderCreateFolderButton();
|
|
132
|
+
fireEvent.click(screen.getByRole("button", {
|
|
133
|
+
name: /folder/i
|
|
134
|
+
}));
|
|
135
|
+
await waitFor(()=>screen.getByText("Create a folder"));
|
|
136
|
+
const input = screen.getByRole("textbox");
|
|
137
|
+
const saveButton = screen.getByRole("button", {
|
|
138
|
+
name: /save/i
|
|
139
|
+
});
|
|
140
|
+
expect(saveButton).toBeDisabled();
|
|
141
|
+
await user_event.type(input, "valid-folder");
|
|
142
|
+
expect(saveButton).toBeEnabled();
|
|
143
|
+
await user_event.clear(input);
|
|
144
|
+
await user_event.type(input, "/invalid");
|
|
145
|
+
expect(saveButton).toBeDisabled();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
3
|
+
import { createTestWrapper } from "../../test/testUtils.js";
|
|
4
|
+
import { DeleteBucketButton } from "../buckets/DeleteBucketButton.js";
|
|
5
|
+
import { useIsBucketEmpty } from "../../hooks/useIsBucketEmpty.js";
|
|
6
|
+
import { useDeleteBucket } from "../../hooks/bucketOperations.js";
|
|
7
|
+
jest.mock("../../hooks/useIsBucketEmpty");
|
|
8
|
+
jest.mock("../../hooks/bucketOperations");
|
|
9
|
+
const mockUseIsBucketEmpty = jest.mocked(useIsBucketEmpty);
|
|
10
|
+
const mockUseDeleteBucket = jest.mocked(useDeleteBucket);
|
|
11
|
+
const renderDeleteBucketButton = (props = {})=>{
|
|
12
|
+
const Wrapper = createTestWrapper();
|
|
13
|
+
return render(/*#__PURE__*/ jsx(Wrapper, {
|
|
14
|
+
children: /*#__PURE__*/ jsx(DeleteBucketButton, {
|
|
15
|
+
bucketName: "test-bucket",
|
|
16
|
+
...props
|
|
17
|
+
})
|
|
18
|
+
}));
|
|
19
|
+
};
|
|
20
|
+
const mockDeleteBucket = jest.fn();
|
|
21
|
+
const mockHookDefaults = ()=>{
|
|
22
|
+
mockUseIsBucketEmpty.mockReturnValue({
|
|
23
|
+
isEmpty: true,
|
|
24
|
+
isLoading: false,
|
|
25
|
+
error: null
|
|
26
|
+
});
|
|
27
|
+
mockUseDeleteBucket.mockReturnValue({
|
|
28
|
+
mutate: mockDeleteBucket,
|
|
29
|
+
status: "idle"
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
describe("DeleteBucketButton", ()=>{
|
|
33
|
+
beforeEach(()=>{
|
|
34
|
+
jest.clearAllMocks();
|
|
35
|
+
mockHookDefaults();
|
|
36
|
+
});
|
|
37
|
+
it("renders delete button with correct label", ()=>{
|
|
38
|
+
renderDeleteBucketButton();
|
|
39
|
+
expect(screen.getByRole("button", {
|
|
40
|
+
name: /delete bucket/i
|
|
41
|
+
})).toBeInTheDocument();
|
|
42
|
+
});
|
|
43
|
+
it("enables button when bucket is empty", ()=>{
|
|
44
|
+
mockUseIsBucketEmpty.mockReturnValue({
|
|
45
|
+
isEmpty: true,
|
|
46
|
+
isLoading: false,
|
|
47
|
+
error: null
|
|
48
|
+
});
|
|
49
|
+
renderDeleteBucketButton();
|
|
50
|
+
const button = screen.getByRole("button", {
|
|
51
|
+
name: /delete bucket/i
|
|
52
|
+
});
|
|
53
|
+
expect(button).not.toBeDisabled();
|
|
54
|
+
});
|
|
55
|
+
it("disables button when bucket is not empty", ()=>{
|
|
56
|
+
mockUseIsBucketEmpty.mockReturnValue({
|
|
57
|
+
isEmpty: false,
|
|
58
|
+
isLoading: false,
|
|
59
|
+
error: null
|
|
60
|
+
});
|
|
61
|
+
renderDeleteBucketButton();
|
|
62
|
+
const button = screen.getByRole("button", {
|
|
63
|
+
name: /delete bucket/i
|
|
64
|
+
});
|
|
65
|
+
expect(button).toBeDisabled();
|
|
66
|
+
});
|
|
67
|
+
it("disables button when checking if bucket is empty", ()=>{
|
|
68
|
+
mockUseIsBucketEmpty.mockReturnValue({
|
|
69
|
+
isEmpty: null,
|
|
70
|
+
isLoading: true,
|
|
71
|
+
error: null
|
|
72
|
+
});
|
|
73
|
+
renderDeleteBucketButton();
|
|
74
|
+
const button = screen.getByRole("button", {
|
|
75
|
+
name: /delete bucket/i
|
|
76
|
+
});
|
|
77
|
+
expect(button).toBeDisabled();
|
|
78
|
+
});
|
|
79
|
+
it("disables button when disabled prop is true", ()=>{
|
|
80
|
+
renderDeleteBucketButton({
|
|
81
|
+
disabled: true
|
|
82
|
+
});
|
|
83
|
+
const button = screen.getByRole("button", {
|
|
84
|
+
name: /delete bucket/i
|
|
85
|
+
});
|
|
86
|
+
expect(button).toBeDisabled();
|
|
87
|
+
});
|
|
88
|
+
it("shows tooltip when bucket is not empty", ()=>{
|
|
89
|
+
mockUseIsBucketEmpty.mockReturnValue({
|
|
90
|
+
isEmpty: false,
|
|
91
|
+
isLoading: false,
|
|
92
|
+
error: null
|
|
93
|
+
});
|
|
94
|
+
renderDeleteBucketButton();
|
|
95
|
+
expect(screen.getByRole("button", {
|
|
96
|
+
name: /delete bucket/i
|
|
97
|
+
})).toBeInTheDocument();
|
|
98
|
+
});
|
|
99
|
+
it("shows checking tooltip when loading", ()=>{
|
|
100
|
+
mockUseIsBucketEmpty.mockReturnValue({
|
|
101
|
+
isEmpty: null,
|
|
102
|
+
isLoading: true,
|
|
103
|
+
error: null
|
|
104
|
+
});
|
|
105
|
+
renderDeleteBucketButton();
|
|
106
|
+
expect(screen.getByRole("button", {
|
|
107
|
+
name: /delete bucket/i
|
|
108
|
+
})).toBeInTheDocument();
|
|
109
|
+
});
|
|
110
|
+
it("opens confirmation modal when button is clicked", ()=>{
|
|
111
|
+
renderDeleteBucketButton();
|
|
112
|
+
const button = screen.getByRole("button", {
|
|
113
|
+
name: /delete bucket/i
|
|
114
|
+
});
|
|
115
|
+
fireEvent.click(button);
|
|
116
|
+
expect(screen.getByText("Confirmation")).toBeInTheDocument();
|
|
117
|
+
expect(screen.getByText(/are you sure you want to delete bucket: test-bucket/i)).toBeInTheDocument();
|
|
118
|
+
});
|
|
119
|
+
it("shows cancel and delete buttons in modal", ()=>{
|
|
120
|
+
renderDeleteBucketButton();
|
|
121
|
+
const button = screen.getByRole("button", {
|
|
122
|
+
name: /delete bucket/i
|
|
123
|
+
});
|
|
124
|
+
fireEvent.click(button);
|
|
125
|
+
expect(screen.getByRole("button", {
|
|
126
|
+
name: /cancel/i
|
|
127
|
+
})).toBeInTheDocument();
|
|
128
|
+
expect(screen.getByRole("button", {
|
|
129
|
+
name: /^delete$/i
|
|
130
|
+
})).toBeInTheDocument();
|
|
131
|
+
});
|
|
132
|
+
it("closes modal when cancel is clicked", ()=>{
|
|
133
|
+
renderDeleteBucketButton();
|
|
134
|
+
const deleteButton = screen.getByRole("button", {
|
|
135
|
+
name: /delete bucket/i
|
|
136
|
+
});
|
|
137
|
+
fireEvent.click(deleteButton);
|
|
138
|
+
const cancelButton = screen.getByRole("button", {
|
|
139
|
+
name: /cancel/i
|
|
140
|
+
});
|
|
141
|
+
fireEvent.click(cancelButton);
|
|
142
|
+
expect(screen.queryByText("Confirmation")).not.toBeInTheDocument();
|
|
143
|
+
});
|
|
144
|
+
it("calls delete mutation when delete is confirmed", ()=>{
|
|
145
|
+
renderDeleteBucketButton();
|
|
146
|
+
const deleteButton = screen.getByRole("button", {
|
|
147
|
+
name: /delete bucket/i
|
|
148
|
+
});
|
|
149
|
+
fireEvent.click(deleteButton);
|
|
150
|
+
const confirmButton = screen.getByRole("button", {
|
|
151
|
+
name: /^delete$/i
|
|
152
|
+
});
|
|
153
|
+
fireEvent.click(confirmButton);
|
|
154
|
+
expect(mockDeleteBucket).toHaveBeenCalledWith({
|
|
155
|
+
Bucket: "test-bucket"
|
|
156
|
+
}, expect.objectContaining({
|
|
157
|
+
onSuccess: expect.any(Function),
|
|
158
|
+
onError: expect.any(Function)
|
|
159
|
+
}));
|
|
160
|
+
});
|
|
161
|
+
it("calls onDeleteSuccess callback when delete succeeds", ()=>{
|
|
162
|
+
const onDeleteSuccess = jest.fn();
|
|
163
|
+
renderDeleteBucketButton({
|
|
164
|
+
onDeleteSuccess
|
|
165
|
+
});
|
|
166
|
+
const deleteButton = screen.getByRole("button", {
|
|
167
|
+
name: /delete bucket/i
|
|
168
|
+
});
|
|
169
|
+
fireEvent.click(deleteButton);
|
|
170
|
+
const confirmButton = screen.getByRole("button", {
|
|
171
|
+
name: /^delete$/i
|
|
172
|
+
});
|
|
173
|
+
fireEvent.click(confirmButton);
|
|
174
|
+
const successCallback = mockDeleteBucket.mock.calls[0][1].onSuccess;
|
|
175
|
+
successCallback();
|
|
176
|
+
expect(onDeleteSuccess).toHaveBeenCalledWith("test-bucket");
|
|
177
|
+
});
|
|
178
|
+
it("calls onDeleteError callback when delete fails", ()=>{
|
|
179
|
+
const onDeleteError = jest.fn();
|
|
180
|
+
const testError = new Error("Delete failed");
|
|
181
|
+
renderDeleteBucketButton({
|
|
182
|
+
onDeleteError
|
|
183
|
+
});
|
|
184
|
+
const deleteButton = screen.getByRole("button", {
|
|
185
|
+
name: /delete bucket/i
|
|
186
|
+
});
|
|
187
|
+
fireEvent.click(deleteButton);
|
|
188
|
+
const confirmButton = screen.getByRole("button", {
|
|
189
|
+
name: /^delete$/i
|
|
190
|
+
});
|
|
191
|
+
fireEvent.click(confirmButton);
|
|
192
|
+
const errorCallback = mockDeleteBucket.mock.calls[0][1].onError;
|
|
193
|
+
errorCallback(testError);
|
|
194
|
+
expect(onDeleteError).toHaveBeenCalledWith(testError);
|
|
195
|
+
});
|
|
196
|
+
it("handles non-Error objects in onError callback", ()=>{
|
|
197
|
+
const onDeleteError = jest.fn();
|
|
198
|
+
renderDeleteBucketButton({
|
|
199
|
+
onDeleteError
|
|
200
|
+
});
|
|
201
|
+
const deleteButton = screen.getByRole("button", {
|
|
202
|
+
name: /delete bucket/i
|
|
203
|
+
});
|
|
204
|
+
fireEvent.click(deleteButton);
|
|
205
|
+
const confirmButton = screen.getByRole("button", {
|
|
206
|
+
name: /^delete$/i
|
|
207
|
+
});
|
|
208
|
+
fireEvent.click(confirmButton);
|
|
209
|
+
const errorCallback = mockDeleteBucket.mock.calls[0][1].onError;
|
|
210
|
+
errorCallback("string error");
|
|
211
|
+
expect(onDeleteError).toHaveBeenCalledWith(new Error("Delete failed"));
|
|
212
|
+
});
|
|
213
|
+
it("closes modal when delete succeeds", async ()=>{
|
|
214
|
+
renderDeleteBucketButton();
|
|
215
|
+
const deleteButton = screen.getByRole("button", {
|
|
216
|
+
name: /delete bucket/i
|
|
217
|
+
});
|
|
218
|
+
fireEvent.click(deleteButton);
|
|
219
|
+
expect(screen.getByText("Confirmation")).toBeInTheDocument();
|
|
220
|
+
const confirmButton = screen.getByRole("button", {
|
|
221
|
+
name: /^delete$/i
|
|
222
|
+
});
|
|
223
|
+
fireEvent.click(confirmButton);
|
|
224
|
+
const successCallback = mockDeleteBucket.mock.calls[0][1].onSuccess;
|
|
225
|
+
successCallback();
|
|
226
|
+
await waitFor(()=>{
|
|
227
|
+
expect(screen.queryByText("Confirmation")).not.toBeInTheDocument();
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
it("shows loading state in delete button when deletion is pending", ()=>{
|
|
231
|
+
mockUseDeleteBucket.mockReturnValue({
|
|
232
|
+
mutate: mockDeleteBucket,
|
|
233
|
+
status: "pending"
|
|
234
|
+
});
|
|
235
|
+
renderDeleteBucketButton();
|
|
236
|
+
const deleteButton = screen.getByRole("button", {
|
|
237
|
+
name: /delete bucket/i
|
|
238
|
+
});
|
|
239
|
+
fireEvent.click(deleteButton);
|
|
240
|
+
const confirmButton = screen.getByRole("button", {
|
|
241
|
+
name: /^delete$/i
|
|
242
|
+
});
|
|
243
|
+
expect(confirmButton).toBeDisabled();
|
|
244
|
+
});
|
|
245
|
+
it("works without optional callbacks", ()=>{
|
|
246
|
+
expect(()=>{
|
|
247
|
+
renderDeleteBucketButton();
|
|
248
|
+
const deleteButton = screen.getByRole("button", {
|
|
249
|
+
name: /delete bucket/i
|
|
250
|
+
});
|
|
251
|
+
fireEvent.click(deleteButton);
|
|
252
|
+
const confirmButton = screen.getByRole("button", {
|
|
253
|
+
name: /^delete$/i
|
|
254
|
+
});
|
|
255
|
+
fireEvent.click(confirmButton);
|
|
256
|
+
const successCallback = mockDeleteBucket.mock.calls[0][1].onSuccess;
|
|
257
|
+
const errorCallback = mockDeleteBucket.mock.calls[0][1].onError;
|
|
258
|
+
successCallback();
|
|
259
|
+
errorCallback(new Error("test"));
|
|
260
|
+
}).not.toThrow();
|
|
261
|
+
});
|
|
262
|
+
it("displays correct bucket name in confirmation message", ()=>{
|
|
263
|
+
renderDeleteBucketButton({
|
|
264
|
+
bucketName: "my-special-bucket"
|
|
265
|
+
});
|
|
266
|
+
const deleteButton = screen.getByRole("button", {
|
|
267
|
+
name: /delete bucket/i
|
|
268
|
+
});
|
|
269
|
+
fireEvent.click(deleteButton);
|
|
270
|
+
expect(screen.getByText(/are you sure you want to delete bucket: my-special-bucket/i)).toBeInTheDocument();
|
|
271
|
+
});
|
|
272
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|