diff --git a/src/react/databrowser/buckets/details/Overview.tsx b/src/react/databrowser/buckets/details/Overview.tsx index 64ffadfaa..84913136e 100644 --- a/src/react/databrowser/buckets/details/Overview.tsx +++ b/src/react/databrowser/buckets/details/Overview.tsx @@ -29,7 +29,10 @@ import { useWorkflows } from '../../../workflow/Workflows'; import { useCurrentAccount } from '../../../DataServiceRoleProvider'; import { DumbErrorModal } from '../../../ui-elements/ErrorHandlerModal'; import { Bucket } from '../../../next-architecture/domain/entities/bucket'; -import { useDeleteBucket } from '../../../next-architecture/domain/business/buckets'; +import { + useChangeBucketVersionning, + useDeleteBucket, +} from '../../../next-architecture/domain/business/buckets'; function capitalize(string: string) { return string.toLowerCase().replace(/^\w/, (c) => { @@ -108,6 +111,7 @@ function Overview({ bucket, ingestionStates }: Props) { }, [dispatch, bucket.name]); const { mutate: deleteBucket } = useDeleteBucket(); + const { mutate: changeBucketVersionning } = useChangeBucketVersionning(); const workflows = workflowsQuery.data; const attachedWorkflowsCount = @@ -153,6 +157,16 @@ function Overview({ bucket, ingestionStates }: Props) { locations && locations[bucketInfo.locationConstraint]?.locationType; const isBucketHostedOnAzureOrGCP = locationType === 'location-azure-v1' || locationType === 'location-gcp-v1'; + + const updateBucketVersioning = (isVersioning: boolean) => { + changeBucketVersionning({ + Bucket: bucketInfo.name, + VersioningConfiguration: { + Status: isVersioning ? 'Enabled' : 'Disabled', + }, + }); + }; + return ( + onChange={() => { dispatch( toggleBucketVersioning( bucket.name, !bucketInfo.isVersioning, ), - ) - } + ); + updateBucketVersioning(!bucketInfo.isVersioning); + }} /> )} diff --git a/src/react/databrowser/buckets/details/__tests__/Overview.test.tsx b/src/react/databrowser/buckets/details/__tests__/Overview.test.tsx index 99b71ecae..e5bd6128b 100644 --- a/src/react/databrowser/buckets/details/__tests__/Overview.test.tsx +++ b/src/react/databrowser/buckets/details/__tests__/Overview.test.tsx @@ -10,8 +10,12 @@ import { } from '../../../../../js/mock/S3Client'; import Overview from '../Overview'; import { Toggle } from '@scality/core-ui'; -import { reduxMount, reduxRender } from '../../../../utils/testUtil'; -import { screen, waitFor, within } from '@testing-library/react'; +import { + reduxMount, + reduxRender, + zenkoUITestConfig, +} from '../../../../utils/testUtil'; +import { fireEvent, screen, waitFor, within } from '@testing-library/react'; import Immutable from 'immutable'; import userEvent from '@testing-library/user-event'; const BUCKET = { @@ -212,3 +216,99 @@ describe('Overview', () => { expect(versioningToggleItem).toHaveAttribute('disabled'); }); }); + +// +// +// +// +// + +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { + BUCKET_NAME, + INSTANCE_ID, +} from '../../../../actions/__tests__/utils/testUtil'; +import { TEST_API_BASE_URL } from '../../../../utils/testUtil'; +import { + ACCOUNT_ID, + USERS, + getConfigOverlay, + getStorageConsumptionMetricsHandlers, +} from '../../../../../js/mock/managementClientMSWHandlers'; +const mockResponse = + 'Enabled'; +const TEST_ACCOUNT = + USERS.find((user) => user.id === '064609833007')?.userName ?? ''; +const TEST_ACCOUNT_CREATION_DATE = + USERS.find((user) => user.id === '064609833007')?.createDate ?? ''; +const server = setupServer( + rest.post(`${TEST_API_BASE_URL}/`, (req, res, ctx) => { + return res( + ctx.json({ + IsTruncated: false, + Accounts: [ + { + Name: TEST_ACCOUNT, + CreationDate: TEST_ACCOUNT_CREATION_DATE, + Roles: [ + { + Name: 'storage-manager-role', + Arn: 'arn:aws:iam::064609833007:role/scality-internal/storage-manager-role', + }, + ], + }, + ], + }), + ); + }), + rest.post( + `${TEST_API_BASE_URL}/api/v1/instance/${INSTANCE_ID}/account/${ACCOUNT_ID}/bucket/bucket/workflow/replication`, + (req, res, ctx) => { + return res(ctx.json([])); + }, + ), + getConfigOverlay(zenkoUITestConfig.managementEndpoint, INSTANCE_ID), + ...getStorageConsumptionMetricsHandlers( + zenkoUITestConfig.managementEndpoint, + INSTANCE_ID, + ), +); +beforeAll(() => { + server.listen({ onUnhandledRequest: 'error' }); +}); +afterAll(() => server.close()); +afterEach(() => server.resetHandlers()); + +describe('Overview', () => { + it('should call the updateBucketVersioning function when clicking on the toggle versioning button', async () => { + const useUpdateBucketVersioningMock = jest.fn(); + server.use( + rest.put(`${TEST_API_BASE_URL}/${BUCKET_NAME}`, (req, res, ctx) => { + useUpdateBucketVersioningMock(req.body); + return res(ctx.status(200)); + }), + ); + + reduxRender(, { + ...TEST_STATE, + ...{ s3: { bucketInfo: bucketInfoResponseVersioningDisabled } }, + }); + + const versioningToggleItem = screen + .getByRole('checkbox', { + name: /inactive/i, + }) + .querySelector('input'); + + await waitFor(() => { + expect(versioningToggleItem).toBeInTheDocument(); + }); + + versioningToggleItem && fireEvent.click(versioningToggleItem); + + await waitFor(() => { + expect(useUpdateBucketVersioningMock).toHaveBeenCalledWith(mockResponse); + }); + }); +}); diff --git a/src/react/databrowser/objects/__tests__/ObjectList.test.tsx b/src/react/databrowser/objects/__tests__/ObjectList.test.tsx index d8680aaf7..e515041e1 100644 --- a/src/react/databrowser/objects/__tests__/ObjectList.test.tsx +++ b/src/react/databrowser/objects/__tests__/ObjectList.test.tsx @@ -5,21 +5,46 @@ import { SECOND_FORMATTED_OBJECT, } from './utils/testUtil'; import { LIST_OBJECTS_S3_TYPE } from '../../../utils/s3'; -import { checkBox, reduxMount } from '../../../utils/testUtil'; +import { + TEST_API_BASE_URL, + checkBox, + reduxMount, + reduxRender, +} from '../../../utils/testUtil'; import { BUCKET_NAME } from '../../../actions/__tests__/utils/testUtil'; import { List } from 'immutable'; import ObjectList from '../ObjectList'; import router from 'react-router'; -import { waitFor } from '@testing-library/react'; +import { screen, waitFor } from '@testing-library/react'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; + +const server = setupServer( + rest.get(`${TEST_API_BASE_URL}/${BUCKET_NAME}`, (req, res, ctx) => { + if (req.url.searchParams.has('versioning')) { + return res( + ctx.status(200), + ctx.xml( + ` + `, + ), + ); + } + }), +); + describe('ObjectList', () => { beforeAll(() => { jest.spyOn(router, 'useLocation').mockReturnValue({ pathname: '/buckets/test/objects', }); + server.listen({ onUnhandledRequest: 'error' }); }); afterEach(() => { jest.clearAllMocks(); + server.resetHandlers(); }); + afterAll(() => server.close()); it('should render ObjectList with no object', () => { const { component } = reduxMount( { expect(toggle.prop('disabled')).toBe(true); }); }); + + it('should enable versioning toggle after updating bucket version', async () => { + server.use( + rest.get(`${TEST_API_BASE_URL}/${BUCKET_NAME}`, (req, res, ctx) => { + return res( + ctx.status(200), + ctx.xml( + ` + Enabled + `, + ), + ); + }), + ); + + reduxRender( + , + ); + + await waitFor(() => { + expect(screen.getByText('List Versions')).toBeEnabled(); + }); + }); });