@scality/data-browser-library 1.0.0-preview.7 → 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/buckets/notifications/BucketNotificationCreatePage.js +8 -8
- 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/setup.js +8 -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
package/dist/hooks/index.d.ts
CHANGED
|
@@ -2,6 +2,10 @@ export { useS3Client } from "./useS3Client";
|
|
|
2
2
|
export type { LoginConfig, LoginMutationResult } from "./useLoginMutation";
|
|
3
3
|
export { useLoginMutation } from "./loginOperations";
|
|
4
4
|
export { useIsBucketEmpty } from "./useIsBucketEmpty";
|
|
5
|
+
export { useEmptyBucket } from "./useEmptyBucket";
|
|
6
|
+
export { useDeleteBucketConfigRule } from "./useDeleteBucketConfigRule";
|
|
7
|
+
export { useTableRowSelection } from "./useTableRowSelection";
|
|
8
|
+
export { useISVBucketStatus } from "./useISVBucketDetection";
|
|
5
9
|
export { useBuckets, useGetBucketLocation, useCreateBucket, useDeleteBucket, } from "./bucketOperations";
|
|
6
10
|
export { useGetBucketAcl, useSetBucketAcl, useGetBucketPolicy, useSetBucketPolicy, useDeleteBucketPolicy, useGetBucketVersioning, useSetBucketVersioning, useGetBucketCors, useSetBucketCors, useDeleteBucketCors, useGetBucketLifecycle, useSetBucketLifecycle, useDeleteBucketLifecycle, useGetBucketNotification, useSetBucketNotification, useGetBucketEncryption, useSetBucketEncryption, useGetBucketTagging, useSetBucketTagging, useDeleteBucketTagging, useGetBucketObjectLockConfiguration, useSetBucketObjectLockConfiguration, useGetBucketReplication, useSetBucketReplication, useDeleteBucketReplication, } from "./bucketConfiguration";
|
|
7
11
|
export { useListObjects, useListObjectVersions, useObjectMetadata, useObjectRetention, useGetObject, usePutObject, useCreateFolder, useUploadObjects, useDeleteObject, useDeleteObjects, useCopyObject, useSetObjectRetention, useObjectLegalHold, useSetObjectLegalHold, useObjectTagging, useSetObjectTagging, useDeleteObjectTagging, useObjectAcl, useSetObjectAcl, useGetObjectAttributes, useGetObjectTorrent, useRestoreObject, useSelectObjectContent, useListMultipartUploads, useSearchObjects, useSearchObjectsVersions, } from "./objectOperations";
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { useS3Client } from "./useS3Client.js";
|
|
2
2
|
import { useLoginMutation } from "./loginOperations.js";
|
|
3
3
|
import { useIsBucketEmpty } from "./useIsBucketEmpty.js";
|
|
4
|
+
import { useEmptyBucket } from "./useEmptyBucket.js";
|
|
5
|
+
import { useDeleteBucketConfigRule } from "./useDeleteBucketConfigRule.js";
|
|
6
|
+
import { useTableRowSelection } from "./useTableRowSelection.js";
|
|
7
|
+
import { useISVBucketStatus } from "./useISVBucketDetection.js";
|
|
4
8
|
import { useBuckets, useCreateBucket, useDeleteBucket, useGetBucketLocation } from "./bucketOperations.js";
|
|
5
9
|
import { useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning } from "./bucketConfiguration.js";
|
|
6
10
|
import { useCopyObject, useCreateFolder, useDeleteObject, useDeleteObjectTagging, useDeleteObjects, useGetObject, useGetObjectAttributes, useGetObjectTorrent, useListMultipartUploads, useListObjectVersions, useListObjects, useObjectAcl, useObjectLegalHold, useObjectMetadata, useObjectRetention, useObjectTagging, usePutObject, useRestoreObject, useSearchObjects, useSearchObjectsVersions, useSelectObjectContent, useSetObjectAcl, useSetObjectLegalHold, useSetObjectRetention, useSetObjectTagging, useUploadObjects } from "./objectOperations.js";
|
|
7
11
|
import { useGetPresignedDownload, useGetPresignedPost, useGetPresignedUpload } from "./presignedOperations.js";
|
|
8
|
-
export { useBuckets, useCopyObject, useCreateBucket, useCreateFolder, useDeleteBucket, useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeleteObject, useDeleteObjectTagging, useDeleteObjects, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketLocation, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetObject, useGetObjectAttributes, useGetObjectTorrent, useGetPresignedDownload, useGetPresignedPost, useGetPresignedUpload, useIsBucketEmpty, useListMultipartUploads, useListObjectVersions, useListObjects, useLoginMutation, useObjectAcl, useObjectLegalHold, useObjectMetadata, useObjectRetention, useObjectTagging, usePutObject, useRestoreObject, useS3Client, useSearchObjects, useSearchObjectsVersions, useSelectObjectContent, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning, useSetObjectAcl, useSetObjectLegalHold, useSetObjectRetention, useSetObjectTagging, useUploadObjects };
|
|
12
|
+
export { useBuckets, useCopyObject, useCreateBucket, useCreateFolder, useDeleteBucket, useDeleteBucketConfigRule, useDeleteBucketCors, useDeleteBucketLifecycle, useDeleteBucketPolicy, useDeleteBucketReplication, useDeleteBucketTagging, useDeleteObject, useDeleteObjectTagging, useDeleteObjects, useEmptyBucket, useGetBucketAcl, useGetBucketCors, useGetBucketEncryption, useGetBucketLifecycle, useGetBucketLocation, useGetBucketNotification, useGetBucketObjectLockConfiguration, useGetBucketPolicy, useGetBucketReplication, useGetBucketTagging, useGetBucketVersioning, useGetObject, useGetObjectAttributes, useGetObjectTorrent, useGetPresignedDownload, useGetPresignedPost, useGetPresignedUpload, useISVBucketStatus, useIsBucketEmpty, useListMultipartUploads, useListObjectVersions, useListObjects, useLoginMutation, useObjectAcl, useObjectLegalHold, useObjectMetadata, useObjectRetention, useObjectTagging, usePutObject, useRestoreObject, useS3Client, useSearchObjects, useSearchObjectsVersions, useSelectObjectContent, useSetBucketAcl, useSetBucketCors, useSetBucketEncryption, useSetBucketLifecycle, useSetBucketNotification, useSetBucketObjectLockConfiguration, useSetBucketPolicy, useSetBucketReplication, useSetBucketTagging, useSetBucketVersioning, useSetObjectAcl, useSetObjectLegalHold, useSetObjectRetention, useSetObjectTagging, useTableRowSelection, useUploadObjects };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
interface BucketCommandInput {
|
|
3
|
+
Bucket: string | undefined;
|
|
4
|
+
}
|
|
5
|
+
interface UseDeleteBucketConfigRuleOptions<TRule extends {
|
|
6
|
+
ID?: string;
|
|
7
|
+
}, TUpdateInput extends BucketCommandInput, TUpdateOutput, TDeleteInput extends BucketCommandInput, TDeleteOutput, TError = unknown> {
|
|
8
|
+
bucketName: string;
|
|
9
|
+
ruleId: string;
|
|
10
|
+
rules: TRule[];
|
|
11
|
+
updateMutation: UseMutationResult<TUpdateOutput, TError, TUpdateInput, unknown>;
|
|
12
|
+
deleteMutation: UseMutationResult<TDeleteOutput, TError, TDeleteInput, unknown>;
|
|
13
|
+
buildUpdateInput: (remainingRules: TRule[]) => Omit<TUpdateInput, "Bucket">;
|
|
14
|
+
successMessage?: string;
|
|
15
|
+
errorMessage?: string;
|
|
16
|
+
onSuccess?: () => void;
|
|
17
|
+
onError?: (error: Error) => void;
|
|
18
|
+
}
|
|
19
|
+
interface UseDeleteBucketConfigRuleReturn {
|
|
20
|
+
isDeleting: boolean;
|
|
21
|
+
deleteRule: () => void;
|
|
22
|
+
}
|
|
23
|
+
export declare function useDeleteBucketConfigRule<TRule extends {
|
|
24
|
+
ID?: string;
|
|
25
|
+
}, TUpdateInput extends BucketCommandInput = BucketCommandInput, TUpdateOutput = unknown, TDeleteInput extends BucketCommandInput = BucketCommandInput, TDeleteOutput = unknown, TError = unknown>({ bucketName, ruleId, rules, updateMutation, deleteMutation, buildUpdateInput, successMessage, errorMessage, onSuccess, onError, }: UseDeleteBucketConfigRuleOptions<TRule, TUpdateInput, TUpdateOutput, TDeleteInput, TDeleteOutput, TError>): UseDeleteBucketConfigRuleReturn;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useToast } from "@scality/core-ui";
|
|
2
|
+
function useDeleteBucketConfigRule({ bucketName, ruleId, rules, updateMutation, deleteMutation, buildUpdateInput, successMessage = "Rule deleted successfully", errorMessage = "Failed to delete rule", onSuccess, onError }) {
|
|
3
|
+
const { showToast } = useToast();
|
|
4
|
+
const { mutate: updateConfig, status: updateStatus } = updateMutation;
|
|
5
|
+
const { mutate: deleteConfig, status: deleteStatus } = deleteMutation;
|
|
6
|
+
const isDeleting = "pending" === updateStatus || "pending" === deleteStatus;
|
|
7
|
+
const deleteRule = ()=>{
|
|
8
|
+
const remainingRules = rules.filter((rule)=>rule.ID !== ruleId);
|
|
9
|
+
const handleSuccess = ()=>{
|
|
10
|
+
showToast({
|
|
11
|
+
open: true,
|
|
12
|
+
message: successMessage,
|
|
13
|
+
status: "success"
|
|
14
|
+
});
|
|
15
|
+
onSuccess?.();
|
|
16
|
+
};
|
|
17
|
+
const handleError = (error)=>{
|
|
18
|
+
const displayMessage = error instanceof Error && error.message ? error.message : errorMessage;
|
|
19
|
+
const errorToReport = error instanceof Error ? error : new Error(displayMessage);
|
|
20
|
+
showToast({
|
|
21
|
+
open: true,
|
|
22
|
+
message: displayMessage,
|
|
23
|
+
status: "error"
|
|
24
|
+
});
|
|
25
|
+
onError?.(errorToReport);
|
|
26
|
+
};
|
|
27
|
+
if (0 === remainingRules.length) deleteConfig({
|
|
28
|
+
Bucket: bucketName
|
|
29
|
+
}, {
|
|
30
|
+
onSuccess: handleSuccess,
|
|
31
|
+
onError: handleError
|
|
32
|
+
});
|
|
33
|
+
else updateConfig({
|
|
34
|
+
Bucket: bucketName,
|
|
35
|
+
...buildUpdateInput(remainingRules)
|
|
36
|
+
}, {
|
|
37
|
+
onSuccess: handleSuccess,
|
|
38
|
+
onError: handleError
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
isDeleting,
|
|
43
|
+
deleteRule
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export { useDeleteBucketConfigRule };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface EmptyBucketResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
deletedCount: number;
|
|
4
|
+
errors: Array<{
|
|
5
|
+
key: string;
|
|
6
|
+
code?: string;
|
|
7
|
+
message?: string;
|
|
8
|
+
}>;
|
|
9
|
+
limitReached: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface UseEmptyBucketOptions {
|
|
12
|
+
maxObjects?: number;
|
|
13
|
+
maxKeysPerList?: number;
|
|
14
|
+
bypassGovernanceRetention?: boolean;
|
|
15
|
+
onProgress?: (deletedCount: number, totalAttempted: number) => void;
|
|
16
|
+
onSuccess?: (result: EmptyBucketResult) => void;
|
|
17
|
+
onError?: (error: Error) => void;
|
|
18
|
+
}
|
|
19
|
+
interface UseEmptyBucketReturn {
|
|
20
|
+
emptyBucket: (bucketName: string) => Promise<EmptyBucketResult | null>;
|
|
21
|
+
isEmptying: boolean;
|
|
22
|
+
error: Error | null;
|
|
23
|
+
result: EmptyBucketResult | null;
|
|
24
|
+
reset: () => void;
|
|
25
|
+
}
|
|
26
|
+
export declare const useEmptyBucket: (options?: UseEmptyBucketOptions) => UseEmptyBucketReturn;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { useCallback, useState } from "react";
|
|
2
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { useS3Client } from "./useS3Client.js";
|
|
4
|
+
import { DeleteObjectsCommand, ListObjectVersionsCommand } from "@aws-sdk/client-s3";
|
|
5
|
+
const useEmptyBucket = (options = {})=>{
|
|
6
|
+
const { maxObjects = 20000, maxKeysPerList = 1000, bypassGovernanceRetention = true, onProgress, onSuccess, onError } = options;
|
|
7
|
+
const [isEmptying, setIsEmptying] = useState(false);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
const [result, setResult] = useState(null);
|
|
10
|
+
const s3Client = useS3Client();
|
|
11
|
+
const queryClient = useQueryClient();
|
|
12
|
+
const emptyBucket = useCallback(async (bucketName)=>{
|
|
13
|
+
setIsEmptying(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
setResult(null);
|
|
16
|
+
try {
|
|
17
|
+
let deletedCount = 0;
|
|
18
|
+
let totalAttempted = 0;
|
|
19
|
+
let keyMarker;
|
|
20
|
+
let versionIdMarker;
|
|
21
|
+
const allErrors = [];
|
|
22
|
+
let limitReached = false;
|
|
23
|
+
while(totalAttempted < maxObjects){
|
|
24
|
+
const listCommand = new ListObjectVersionsCommand({
|
|
25
|
+
Bucket: bucketName,
|
|
26
|
+
MaxKeys: maxKeysPerList,
|
|
27
|
+
KeyMarker: keyMarker,
|
|
28
|
+
VersionIdMarker: versionIdMarker
|
|
29
|
+
});
|
|
30
|
+
const listResponse = await s3Client.send(listCommand);
|
|
31
|
+
const objectsToDelete = [];
|
|
32
|
+
if (listResponse.Versions) objectsToDelete.push(...listResponse.Versions.filter((v)=>v.Key).map((v)=>({
|
|
33
|
+
Key: v.Key,
|
|
34
|
+
VersionId: v.VersionId
|
|
35
|
+
})));
|
|
36
|
+
if (listResponse.DeleteMarkers) objectsToDelete.push(...listResponse.DeleteMarkers.filter((dm)=>dm.Key).map((dm)=>({
|
|
37
|
+
Key: dm.Key,
|
|
38
|
+
VersionId: dm.VersionId
|
|
39
|
+
})));
|
|
40
|
+
if (0 === objectsToDelete.length) break;
|
|
41
|
+
const deleteCommand = new DeleteObjectsCommand({
|
|
42
|
+
Bucket: bucketName,
|
|
43
|
+
Delete: {
|
|
44
|
+
Objects: objectsToDelete
|
|
45
|
+
},
|
|
46
|
+
BypassGovernanceRetention: bypassGovernanceRetention
|
|
47
|
+
});
|
|
48
|
+
const deleteResponse = await s3Client.send(deleteCommand);
|
|
49
|
+
const successCount = deleteResponse.Deleted?.length || 0;
|
|
50
|
+
deletedCount += successCount;
|
|
51
|
+
totalAttempted += objectsToDelete.length;
|
|
52
|
+
if (deleteResponse.Errors) allErrors.push(...deleteResponse.Errors.map((error)=>({
|
|
53
|
+
key: error.Key || "unknown",
|
|
54
|
+
code: error.Code,
|
|
55
|
+
message: error.Message
|
|
56
|
+
})));
|
|
57
|
+
onProgress?.(deletedCount, totalAttempted);
|
|
58
|
+
if (!listResponse.IsTruncated) break;
|
|
59
|
+
if (totalAttempted >= maxObjects) {
|
|
60
|
+
limitReached = true;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
keyMarker = listResponse.NextKeyMarker;
|
|
64
|
+
versionIdMarker = listResponse.NextVersionIdMarker;
|
|
65
|
+
}
|
|
66
|
+
const bucketResult = {
|
|
67
|
+
success: 0 === allErrors.length,
|
|
68
|
+
deletedCount,
|
|
69
|
+
errors: allErrors,
|
|
70
|
+
limitReached
|
|
71
|
+
};
|
|
72
|
+
setResult(bucketResult);
|
|
73
|
+
queryClient.invalidateQueries({
|
|
74
|
+
queryKey: [
|
|
75
|
+
"ListObjects"
|
|
76
|
+
]
|
|
77
|
+
});
|
|
78
|
+
queryClient.invalidateQueries({
|
|
79
|
+
queryKey: [
|
|
80
|
+
"ListObjectVersions"
|
|
81
|
+
]
|
|
82
|
+
});
|
|
83
|
+
onSuccess?.(bucketResult);
|
|
84
|
+
return bucketResult;
|
|
85
|
+
} catch (err) {
|
|
86
|
+
const errorObj = err instanceof Error ? err : new Error("Failed to empty bucket");
|
|
87
|
+
setError(errorObj);
|
|
88
|
+
onError?.(errorObj);
|
|
89
|
+
return null;
|
|
90
|
+
} finally{
|
|
91
|
+
setIsEmptying(false);
|
|
92
|
+
}
|
|
93
|
+
}, [
|
|
94
|
+
s3Client,
|
|
95
|
+
maxObjects,
|
|
96
|
+
maxKeysPerList,
|
|
97
|
+
bypassGovernanceRetention,
|
|
98
|
+
onProgress,
|
|
99
|
+
onSuccess,
|
|
100
|
+
onError,
|
|
101
|
+
queryClient
|
|
102
|
+
]);
|
|
103
|
+
const reset = useCallback(()=>{
|
|
104
|
+
setIsEmptying(false);
|
|
105
|
+
setError(null);
|
|
106
|
+
setResult(null);
|
|
107
|
+
}, []);
|
|
108
|
+
return {
|
|
109
|
+
emptyBucket,
|
|
110
|
+
isEmptying,
|
|
111
|
+
error,
|
|
112
|
+
result,
|
|
113
|
+
reset
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
export { useEmptyBucket };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook to detect if a bucket is managed by any ISV (Veeam or Commvault)
|
|
3
|
+
* Returns comprehensive information about ISV bucket status
|
|
4
|
+
*
|
|
5
|
+
* This hook fetches bucket tags once and derives all ISV-related states from it,
|
|
6
|
+
* avoiding multiple API calls for the same data.
|
|
7
|
+
*/
|
|
8
|
+
export declare const useISVBucketStatus: (bucketName: string) => {
|
|
9
|
+
isVeeamBucket: boolean;
|
|
10
|
+
isCommvaultBucket: boolean;
|
|
11
|
+
isISVManaged: boolean;
|
|
12
|
+
isvApplication: string | undefined;
|
|
13
|
+
isLoading: boolean | undefined;
|
|
14
|
+
bucketTagsStatus: "error" | "success" | "pending";
|
|
15
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { useGetBucketTagging } from "./bucketConfiguration.js";
|
|
2
|
+
import { useFeatures } from "../utils/useFeatures.js";
|
|
3
|
+
import { BUCKET_TAG_APPLICATION, BUCKET_TAG_VEEAM_APPLICATION, COMMVAULT_APPLICATION, VEEAM_BACKUP_REPLICATION, VEEAM_OFFICE_365, VEEAM_OFFICE_365_V8, VEEAM_VBO_APPLICATION } from "../utils/constants.js";
|
|
4
|
+
const useISVBucketStatus = (bucketName)=>{
|
|
5
|
+
const isISVFeatureEnabled = useFeatures("ISV");
|
|
6
|
+
const { data: bucketTags, status: bucketTagsStatus } = useGetBucketTagging({
|
|
7
|
+
Bucket: bucketName
|
|
8
|
+
}, {
|
|
9
|
+
enabled: isISVFeatureEnabled
|
|
10
|
+
});
|
|
11
|
+
const veeamTagApplication = bucketTags?.TagSet?.find((tag)=>tag.Key === BUCKET_TAG_VEEAM_APPLICATION)?.Value;
|
|
12
|
+
const ISVApplicationTag = bucketTags?.TagSet?.find((tag)=>tag.Key === BUCKET_TAG_APPLICATION)?.Value;
|
|
13
|
+
const isVeeamBucket = veeamTagApplication === VEEAM_BACKUP_REPLICATION || veeamTagApplication === VEEAM_OFFICE_365 || veeamTagApplication === VEEAM_OFFICE_365_V8;
|
|
14
|
+
const isISVBucketTagAsVeeam = ISVApplicationTag === VEEAM_BACKUP_REPLICATION || ISVApplicationTag === VEEAM_VBO_APPLICATION;
|
|
15
|
+
const isCommvaultBucket = ISVApplicationTag === COMMVAULT_APPLICATION;
|
|
16
|
+
const isVeeam = isVeeamBucket || isISVBucketTagAsVeeam;
|
|
17
|
+
const isISVManaged = isVeeam || isCommvaultBucket;
|
|
18
|
+
return {
|
|
19
|
+
isVeeamBucket: isVeeam,
|
|
20
|
+
isCommvaultBucket,
|
|
21
|
+
isISVManaged,
|
|
22
|
+
isvApplication: isCommvaultBucket ? "Commvault" : isVeeam ? "Veeam" : void 0,
|
|
23
|
+
isLoading: isISVFeatureEnabled && "pending" === bucketTagsStatus,
|
|
24
|
+
bucketTagsStatus
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export { useISVBucketStatus };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
function useTableRowSelection(tableData, autoSelectFirst = true) {
|
|
3
|
+
const [selectedRuleId, setSelectedRuleId] = useState(null);
|
|
4
|
+
useEffect(()=>{
|
|
5
|
+
if (0 === tableData.length) {
|
|
6
|
+
if (null !== selectedRuleId) setSelectedRuleId(null);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (!autoSelectFirst) {
|
|
10
|
+
if (null !== selectedRuleId) {
|
|
11
|
+
const stillExists = tableData.some((row)=>row.ID === selectedRuleId);
|
|
12
|
+
if (!stillExists) setSelectedRuleId(null);
|
|
13
|
+
}
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (null === selectedRuleId) {
|
|
17
|
+
const firstRowId = tableData[0]?.ID;
|
|
18
|
+
if (firstRowId) setSelectedRuleId(firstRowId);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const stillExists = tableData.some((row)=>row.ID === selectedRuleId);
|
|
22
|
+
if (!stillExists) {
|
|
23
|
+
const firstRowId = tableData[0]?.ID;
|
|
24
|
+
firstRowId ? setSelectedRuleId(firstRowId) : setSelectedRuleId(null);
|
|
25
|
+
}
|
|
26
|
+
}, [
|
|
27
|
+
autoSelectFirst,
|
|
28
|
+
tableData,
|
|
29
|
+
selectedRuleId
|
|
30
|
+
]);
|
|
31
|
+
const onRowSelected = useCallback((row)=>{
|
|
32
|
+
if (row.original.ID && row.original.ID !== selectedRuleId) setSelectedRuleId(row.original.ID);
|
|
33
|
+
}, [
|
|
34
|
+
selectedRuleId
|
|
35
|
+
]);
|
|
36
|
+
const clearSelection = useCallback(()=>{
|
|
37
|
+
setSelectedRuleId(null);
|
|
38
|
+
}, []);
|
|
39
|
+
return {
|
|
40
|
+
selectedId: selectedRuleId,
|
|
41
|
+
onRowSelected,
|
|
42
|
+
clearSelection
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export { useTableRowSelection };
|
package/dist/test/setup.js
CHANGED
|
@@ -57,6 +57,14 @@ jest.mock("pretty-bytes", ()=>({
|
|
|
57
57
|
return `${Math.round(num)} ${sizes[i]}`;
|
|
58
58
|
}
|
|
59
59
|
}));
|
|
60
|
+
jest.mock("joi", ()=>{
|
|
61
|
+
const Joi = jest.requireActual("joi");
|
|
62
|
+
return {
|
|
63
|
+
__esModule: true,
|
|
64
|
+
default: Joi,
|
|
65
|
+
...Joi
|
|
66
|
+
};
|
|
67
|
+
});
|
|
60
68
|
if (!File.prototype.arrayBuffer) File.prototype.arrayBuffer = function() {
|
|
61
69
|
return new Promise((resolve)=>{
|
|
62
70
|
const reader = new FileReader();
|
package/dist/test/testUtils.d.ts
CHANGED
|
@@ -1,13 +1,49 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Test utilities for data-browser-library
|
|
3
|
+
*
|
|
4
|
+
* This file provides common utilities for testing:
|
|
5
|
+
* - Test configuration and credentials
|
|
6
|
+
* - Mock setup utilities (S3, DOM, etc.)
|
|
7
|
+
* - React Testing Library wrappers
|
|
8
|
+
* - React Query wrappers
|
|
9
|
+
* - Global configuration utilities
|
|
10
|
+
* - Factory pattern validation utilities
|
|
11
|
+
* - Form testing helpers
|
|
12
|
+
*/
|
|
2
13
|
import React from "react";
|
|
14
|
+
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
3
15
|
import { S3BrowserConfig, S3Credentials } from "../types";
|
|
16
|
+
import type { S3Configuration, DevelopmentConfiguration } from "../config/types";
|
|
17
|
+
/**
|
|
18
|
+
* Default S3 configuration for tests
|
|
19
|
+
*/
|
|
4
20
|
export declare const testConfig: S3BrowserConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Default S3 credentials for tests
|
|
23
|
+
*/
|
|
5
24
|
export declare const testCredentials: S3Credentials;
|
|
25
|
+
/**
|
|
26
|
+
* Mock S3 client for tests
|
|
27
|
+
*/
|
|
6
28
|
export declare const mockS3Client: {
|
|
7
29
|
send: jest.Mock<any, any, any>;
|
|
8
30
|
};
|
|
9
31
|
export declare const MockedS3Client: jest.MockedClass<typeof S3Client>;
|
|
10
32
|
export declare const MockedPutObjectCommand: jest.MockedClass<typeof PutObjectCommand>;
|
|
33
|
+
/**
|
|
34
|
+
* Sets up S3 mocks for testing
|
|
35
|
+
*/
|
|
36
|
+
export declare const setupS3Mocks: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Common mock setup that should be run before each test
|
|
39
|
+
*/
|
|
40
|
+
export declare const setupCommonMocks: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Mocks DOM measurements APIs for virtualization and layout testing
|
|
43
|
+
* AutoSizer uses offsetWidth and offsetHeight which Jest/JSDom doesn't support
|
|
44
|
+
* @param width - The mock width in pixels
|
|
45
|
+
* @param height - The mock height in pixels
|
|
46
|
+
*/
|
|
11
47
|
export declare function mockOffsetSize(width: number, height: number): void;
|
|
12
48
|
/**
|
|
13
49
|
* Creates a simple QueryClient wrapper for tests that don't need DataBrowser context
|
|
@@ -33,18 +69,6 @@ export declare const renderHookWithWrapper: <TProps, TResult>(hook: (props: TPro
|
|
|
33
69
|
* Creates a test File object
|
|
34
70
|
*/
|
|
35
71
|
export declare const createTestFile: (name: string, content: string, type?: string) => File;
|
|
36
|
-
/**
|
|
37
|
-
* Sets up S3 mocks for testing
|
|
38
|
-
*/
|
|
39
|
-
export declare const setupS3Mocks: () => void;
|
|
40
|
-
/**
|
|
41
|
-
* Common mock setup that should be run before each test
|
|
42
|
-
*/
|
|
43
|
-
export declare const setupCommonMocks: () => void;
|
|
44
|
-
/**
|
|
45
|
-
* Configuration test utilities for overriding build-time globals
|
|
46
|
-
*/
|
|
47
|
-
import type { S3Configuration, DevelopmentConfiguration } from "../config/types";
|
|
48
72
|
type GlobalConfigOverrides = {
|
|
49
73
|
s3?: Partial<S3Configuration>;
|
|
50
74
|
dev?: Partial<DevelopmentConfiguration>;
|
|
@@ -67,16 +91,74 @@ export declare const resetGlobalConfig: () => void;
|
|
|
67
91
|
* Test helper for running tests with specific global configuration
|
|
68
92
|
*/
|
|
69
93
|
export declare const withGlobalConfig: (overrides: GlobalConfigOverrides, testFn: () => void | Promise<void>) => () => Promise<void>;
|
|
70
|
-
/**
|
|
71
|
-
* Validates that a hook follows the expected factory pattern
|
|
72
|
-
*/
|
|
73
|
-
export declare const validateFactoryHook: (hook: any, operationName: string) => void;
|
|
74
94
|
/**
|
|
75
95
|
* Creates a factory test error
|
|
76
96
|
*/
|
|
77
97
|
export declare const createFactoryTestError: (testContext: string, operationName: string, details?: string) => Error;
|
|
98
|
+
/**
|
|
99
|
+
* Validates that a hook follows the expected factory pattern
|
|
100
|
+
*/
|
|
101
|
+
export declare const validateFactoryHook: (hook: any, operationName: string) => void;
|
|
78
102
|
/**
|
|
79
103
|
* Validates that a hook result has expected React Query properties
|
|
80
104
|
*/
|
|
81
105
|
export declare const validateHookResult: (result: any, hookType: "query" | "mutation" | "infiniteQuery") => void;
|
|
106
|
+
/**
|
|
107
|
+
* Creates a mock UseMutationResult for testing React Query mutations
|
|
108
|
+
*
|
|
109
|
+
* This helper provides a complete mock object that matches the UseMutationResult type
|
|
110
|
+
* from @tanstack/react-query, eliminating the need for 'as any' type assertions.
|
|
111
|
+
*
|
|
112
|
+
* @param mutate - The mocked mutate function (usually jest.fn())
|
|
113
|
+
* @param overrides - Optional overrides for any properties (e.g., { isPending: true })
|
|
114
|
+
* @returns A complete UseMutationResult mock object
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* const mockCreateBucket = jest.fn();
|
|
119
|
+
* const mockResult = createMockMutationResult(mockCreateBucket, { isPending: true });
|
|
120
|
+
* mockUseCreateBucket.mockReturnValue(mockResult);
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare const createMockMutationResult: (mutate: jest.Mock, overrides?: {}) => {
|
|
124
|
+
mutate: jest.Mock<any, any, any>;
|
|
125
|
+
mutateAsync: jest.Mock<any, any, any>;
|
|
126
|
+
reset: jest.Mock<any, any, any>;
|
|
127
|
+
isPending: false;
|
|
128
|
+
isIdle: true;
|
|
129
|
+
isError: false;
|
|
130
|
+
isSuccess: false;
|
|
131
|
+
status: "idle";
|
|
132
|
+
data: undefined;
|
|
133
|
+
error: null;
|
|
134
|
+
variables: undefined;
|
|
135
|
+
context: undefined;
|
|
136
|
+
failureCount: number;
|
|
137
|
+
failureReason: null;
|
|
138
|
+
isPaused: false;
|
|
139
|
+
submittedAt: number;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Finds a Toggle input element by its label text
|
|
143
|
+
* Traverses the DOM to locate the associated checkbox input
|
|
144
|
+
* @param labelText - The text content of the label
|
|
145
|
+
* @returns The toggle input element or null if not found
|
|
146
|
+
*/
|
|
147
|
+
export declare const findToggleByLabel: (labelText: string) => HTMLInputElement | null;
|
|
148
|
+
/**
|
|
149
|
+
* Waits for a submit button to be enabled and clicks it
|
|
150
|
+
* @param buttonName - The type of button to click ("create" or "save")
|
|
151
|
+
*/
|
|
152
|
+
export declare const submitForm: (buttonName?: "create" | "save") => Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Sets up a mock mutation to simulate successful form submission
|
|
155
|
+
* @param mockMutate - The jest mock function for the mutation
|
|
156
|
+
*/
|
|
157
|
+
export declare const mockSuccessSubmit: (mockMutate: jest.Mock) => void;
|
|
158
|
+
/**
|
|
159
|
+
* Sets up a mock mutation to simulate failed form submission
|
|
160
|
+
* @param mockMutate - The jest mock function for the mutation
|
|
161
|
+
* @param errorMessage - The error message to return (default: "Network Error")
|
|
162
|
+
*/
|
|
163
|
+
export declare const mockErrorSubmit: (mockMutate: jest.Mock, errorMessage?: string) => void;
|
|
82
164
|
export { setupMswServer, overrideHandlers } from "./msw";
|
package/dist/test/testUtils.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
2
3
|
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
3
4
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
4
|
-
import { renderHook } from "@testing-library/react";
|
|
5
|
-
import "react";
|
|
6
|
-
import { DataBrowserProvider } from "../components/providers/DataBrowserProvider.js";
|
|
5
|
+
import { fireEvent, renderHook, screen, waitFor } from "@testing-library/react";
|
|
7
6
|
import { coreUIAvailableThemes } from "@scality/core-ui/dist/style/theme";
|
|
8
7
|
import { CoreUiThemeProvider } from "@scality/core-ui/dist/next";
|
|
9
8
|
import { ToastProvider } from "@scality/core-ui";
|
|
9
|
+
import { DataBrowserProvider } from "../components/providers/DataBrowserProvider.js";
|
|
10
10
|
import { overrideHandlers, setupMswServer } from "./msw/index.js";
|
|
11
11
|
var __webpack_require__ = {};
|
|
12
12
|
(()=>{
|
|
@@ -34,6 +34,17 @@ const mockS3Client = {
|
|
|
34
34
|
};
|
|
35
35
|
const MockedS3Client = S3Client;
|
|
36
36
|
const MockedPutObjectCommand = PutObjectCommand;
|
|
37
|
+
const setupS3Mocks = ()=>{
|
|
38
|
+
jest.clearAllMocks();
|
|
39
|
+
MockedS3Client.mockImplementation(()=>mockS3Client);
|
|
40
|
+
MockedPutObjectCommand.mockImplementation((input)=>({
|
|
41
|
+
input,
|
|
42
|
+
resolveMiddleware: jest.fn()
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
const setupCommonMocks = ()=>{
|
|
46
|
+
setupS3Mocks();
|
|
47
|
+
};
|
|
37
48
|
function mockOffsetSize(width, height) {
|
|
38
49
|
__webpack_require__.g.ResizeObserver = jest.fn().mockImplementation(()=>({
|
|
39
50
|
observe: jest.fn(),
|
|
@@ -149,17 +160,6 @@ const createTestFile = (name, content, type = "text/plain")=>new File([
|
|
|
149
160
|
], name, {
|
|
150
161
|
type
|
|
151
162
|
});
|
|
152
|
-
const setupS3Mocks = ()=>{
|
|
153
|
-
jest.clearAllMocks();
|
|
154
|
-
MockedS3Client.mockImplementation(()=>mockS3Client);
|
|
155
|
-
MockedPutObjectCommand.mockImplementation((input)=>({
|
|
156
|
-
input,
|
|
157
|
-
resolveMiddleware: jest.fn()
|
|
158
|
-
}));
|
|
159
|
-
};
|
|
160
|
-
const setupCommonMocks = ()=>{
|
|
161
|
-
setupS3Mocks();
|
|
162
|
-
};
|
|
163
163
|
const overrideGlobalConfig = (overrides)=>{
|
|
164
164
|
const currentS3 = globalThis.__S3_CONFIG__;
|
|
165
165
|
const currentDev = globalThis.__DEV_CONFIG__;
|
|
@@ -201,10 +201,10 @@ const withGlobalConfig = (overrides, testFn)=>async ()=>{
|
|
|
201
201
|
resetGlobalConfig();
|
|
202
202
|
}
|
|
203
203
|
};
|
|
204
|
+
const createFactoryTestError = (testContext, operationName, details)=>new Error(`Factory Test Failure [${testContext}]: ${operationName} - ${details || "Unknown error"}. Check factory implementation and hook usage patterns.`);
|
|
204
205
|
const validateFactoryHook = (hook, operationName)=>{
|
|
205
206
|
if ("function" != typeof hook) throw createFactoryTestError("Factory Validation", operationName, "hook should be a function - check if useCreate*Hook factory is properly returning a hook function");
|
|
206
207
|
};
|
|
207
|
-
const createFactoryTestError = (testContext, operationName, details)=>new Error(`Factory Test Failure [${testContext}]: ${operationName} - ${details || "Unknown error"}. Check factory implementation and hook usage patterns.`);
|
|
208
208
|
const validateHookResult = (result, hookType)=>{
|
|
209
209
|
const commonProps = [
|
|
210
210
|
"isError",
|
|
@@ -233,4 +233,52 @@ const validateHookResult = (result, hookType)=>{
|
|
|
233
233
|
];
|
|
234
234
|
for (const prop of expectedProps)if (!(prop in result)) throw createFactoryTestError("Hook Validation", hookType, `Missing property '${prop}' - check if factory is returning proper React Query hook result`);
|
|
235
235
|
};
|
|
236
|
-
|
|
236
|
+
const createMockMutationResult = (mutate, overrides = {})=>({
|
|
237
|
+
mutate,
|
|
238
|
+
mutateAsync: jest.fn(),
|
|
239
|
+
reset: jest.fn(),
|
|
240
|
+
isPending: false,
|
|
241
|
+
isIdle: true,
|
|
242
|
+
isError: false,
|
|
243
|
+
isSuccess: false,
|
|
244
|
+
status: "idle",
|
|
245
|
+
data: void 0,
|
|
246
|
+
error: null,
|
|
247
|
+
variables: void 0,
|
|
248
|
+
context: void 0,
|
|
249
|
+
failureCount: 0,
|
|
250
|
+
failureReason: null,
|
|
251
|
+
isPaused: false,
|
|
252
|
+
submittedAt: 0,
|
|
253
|
+
...overrides
|
|
254
|
+
});
|
|
255
|
+
const findToggleByLabel = (labelText)=>{
|
|
256
|
+
const label = screen.getByText(labelText);
|
|
257
|
+
let current = label.parentElement;
|
|
258
|
+
while(current && !current.querySelector('input[type="checkbox"]'))current = current.parentElement;
|
|
259
|
+
return current?.querySelector('input[type="checkbox"]');
|
|
260
|
+
};
|
|
261
|
+
const submitForm = async (buttonName = "create")=>{
|
|
262
|
+
await waitFor(()=>{
|
|
263
|
+
const button = screen.getByRole("button", {
|
|
264
|
+
name: "create" === buttonName ? /create/i : /save/i
|
|
265
|
+
});
|
|
266
|
+
expect(button).toBeEnabled();
|
|
267
|
+
});
|
|
268
|
+
const button = screen.getByRole("button", {
|
|
269
|
+
name: "create" === buttonName ? /create/i : /save/i
|
|
270
|
+
});
|
|
271
|
+
fireEvent.click(button);
|
|
272
|
+
};
|
|
273
|
+
const mockSuccessSubmit = (mockMutate)=>{
|
|
274
|
+
mockMutate.mockImplementation((_, options)=>{
|
|
275
|
+
options?.onSuccess?.();
|
|
276
|
+
});
|
|
277
|
+
};
|
|
278
|
+
const mockErrorSubmit = (mockMutate, errorMessage = "Network Error")=>{
|
|
279
|
+
const error = new Error(errorMessage);
|
|
280
|
+
mockMutate.mockImplementation((_, options)=>{
|
|
281
|
+
options?.onError?.(error);
|
|
282
|
+
});
|
|
283
|
+
};
|
|
284
|
+
export { MockedPutObjectCommand, MockedS3Client, createFactoryTestError, createMockMutationResult, createQueryWrapper, createTestFile, createTestWrapper, findToggleByLabel, mockErrorSubmit, mockOffsetSize, mockS3Client, mockSuccessSubmit, overrideGlobalConfig, overrideHandlers, renderHookWithWrapper, resetGlobalConfig, setupCommonMocks, setupMswServer, setupS3Mocks, submitForm, testConfig, testCredentials, validateFactoryHook, validateHookResult, withGlobalConfig };
|