diff --git a/src/react/next-architecture/domain/business/accounts.ts b/src/react/next-architecture/domain/business/accounts.ts index aeb271a2e..036bfbe3d 100644 --- a/src/react/next-architecture/domain/business/accounts.ts +++ b/src/react/next-architecture/domain/business/accounts.ts @@ -1,5 +1,5 @@ import { useMemo } from 'react'; -import { useQuery, useQueryClient } from 'react-query'; +import { useMutation, useQuery, useQueryClient } from 'react-query'; import { STORAGE_ACCOUNT_OWNER_ROLE, STORAGE_MANAGER_ROLE, @@ -68,9 +68,23 @@ export const useAccountsLocationsAndEndpoints = ({ queries.listAccountsLocationAndEndpoints(accountsLocationsEndpointsAdapter), ); + const refetchAccountsLocationsEndpointsMutation = useMutation({ + mutationFn: async () => { + return refetchAccountsLocationsEndpoints().then( + ({ data, status, error }) => { + if (status === 'error') { + throw error; + } + return data; + }, + ); + }, + }); + return { accountsLocationsAndEndpoints, refetchAccountsLocationsEndpoints, + refetchAccountsLocationsEndpointsMutation, ...result, }; }; diff --git a/src/react/ui-elements/Veeam/VeeamTable.test.tsx b/src/react/ui-elements/Veeam/VeeamTable.test.tsx index 30e9a750f..dff03855b 100644 --- a/src/react/ui-elements/Veeam/VeeamTable.test.tsx +++ b/src/react/ui-elements/Veeam/VeeamTable.test.tsx @@ -16,13 +16,27 @@ import { getConfigOverlay } from '../../../js/mock/managementClientMSWHandlers'; import { INSTANCE_ID } from '../../actions/__tests__/utils/testUtil'; import Configuration from './VeeamConfiguration'; import userEvent from '@testing-library/user-event'; +import { rest } from 'msw'; -jest.setTimeout(30_000); +const allFailHandlers = [ + rest.get('*', (req, res, ctx) => { + return res(ctx.status(500), ctx.json({})); + }), + rest.post('*', (req, res, ctx) => { + return res(ctx.status(500), ctx.json({})); + }), + rest.put('*', (req, res, ctx) => res(ctx.status(500))), + rest.patch('*', (req, res, ctx) => res(ctx.status(500))), + rest.delete('*', (req, res, ctx) => res(ctx.status(500))), + rest.head('*', (req, res, ctx) => res(ctx.status(500))), +]; +const goodHandlers = [ + ...getVeeamMutationHandler(), + getConfigOverlay(TEST_API_BASE_URL, INSTANCE_ID), +]; +jest.setTimeout(70_000); describe('VeeamTable', () => { - const server = setupServer( - ...getVeeamMutationHandler(), - getConfigOverlay(TEST_API_BASE_URL, INSTANCE_ID), - ); + const server = setupServer(); beforeAll(() => { server.listen({ onUnhandledRequest: 'error' }); mockOffsetSize(600, 800); @@ -39,9 +53,10 @@ describe('VeeamTable', () => { veeamConfigActionTable: () => screen.getByText('Configure ARTESCA for Veeam'), allRows: () => screen.getAllByRole('row').filter((_, index) => index > 0), + retryButton: () => screen.getByRole('button', { name: /retry/i }), }; - it.only('should render the Veeam table', async () => { + const setupTest = () => { render( { />, { wrapper: NewWrapper() }, ); - + }; + it('should render the Veeam table', async () => { + server.use(...goodHandlers); + setupTest(); //E //type the bucket name in configuration form userEvent.type(selectors.setBucketName(), bucketName); @@ -78,8 +96,13 @@ describe('VeeamTable', () => { expect(cells).toHaveLength(3); expect(cells[0]).toHaveTextContent(`${index + 1}`); expect(cells[1]).toHaveTextContent(actions[index]); - expect(cells[2]).toHaveTextContent(/Pending.../i); - //TODO: Sometimes it's too fast and the status is already success + if (index === 0) { + try { + expect(cells[2]).toHaveTextContent(/Pending.../i); + } catch (error) { + expect(cells[2]).toHaveTextContent(/Success/i); + } + } }); expect(selectors.allRows()).toHaveLength(actions.length); expect(selectors.cancelButton()).toBeDisabled(); @@ -95,5 +118,66 @@ describe('VeeamTable', () => { } }); - it('should retry the failed actions', async () => {}); + it('should retry the failed actions', async () => { + //Setup + server.use(...allFailHandlers); + setupTest(); + //Exercise + userEvent.type(selectors.setBucketName(), bucketName); + await waitFor(() => { + expect(selectors.continueButton()).toBeEnabled(); + }); + userEvent.click(selectors.continueButton()); + + // Veeam action table + await waitFor(() => { + expect(selectors.veeamConfigActionTable()).toBeInTheDocument(); + }); + + //Verify + // initial state + selectors.allRows().forEach((row, index) => { + const cells = within(row).getAllByRole('gridcell'); + expect(cells).toHaveLength(3); + expect(cells[0]).toHaveTextContent(`${index + 1}`); + expect(cells[1]).toHaveTextContent(actions[index]); + + if (index === 0) { + try { + expect(cells[2]).toHaveTextContent(/Pending.../i); + } catch (error) { + expect(cells[2]).toHaveTextContent(/Failed/i); + } + } + }); + server.events.on('response:mocked', ({ status }) => { + if (status !== 500) { + server.resetHandlers(...allFailHandlers); + } + }); + + for (let i = 0; i < actions.length; i++) { + await waitFor( + () => { + expect( + within(selectors.allRows()[i]).getAllByRole('gridcell')[2], + ).toHaveTextContent('Failed'); + }, + { timeout: 5_000 }, + ); + + server.resetHandlers(...goodHandlers); + + userEvent.click(selectors.retryButton()); + + await waitFor( + () => { + expect( + within(selectors.allRows()[i]).getAllByRole('gridcell')[2], + ).toHaveTextContent('Success'); + }, + { timeout: 5_000 }, + ); + } + }); }); diff --git a/src/react/ui-elements/Veeam/useMutationTableData.ts b/src/react/ui-elements/Veeam/useMutationTableData.ts index 5a6811638..8d666c6aa 100644 --- a/src/react/ui-elements/Veeam/useMutationTableData.ts +++ b/src/react/ui-elements/Veeam/useMutationTableData.ts @@ -68,18 +68,12 @@ export const useMutationTableData = ({ const accountsLocationsEndpointsAdapter = useAccountsLocationsEndpointsAdapter(); - const { refetchAccountsLocationsEndpoints } = + const { refetchAccountsLocationsEndpointsMutation } = useAccountsLocationsAndEndpoints({ accountsLocationsEndpointsAdapter }); - const updateConfigOverlayMutation = useMutation({ - mutationFn: async () => { - return refetchAccountsLocationsEndpoints().then(({ data }) => data); - }, - }); - const mutations = [ useCreateAccountMutation(), - updateConfigOverlayMutation, + refetchAccountsLocationsEndpointsMutation, assumeRoleMutation, useCreateBucket(), useCreateIAMUserMutation(), diff --git a/src/react/utils/testUtil.tsx b/src/react/utils/testUtil.tsx index 65f295b73..c14bd2433 100644 --- a/src/react/utils/testUtil.tsx +++ b/src/react/utils/testUtil.tsx @@ -152,6 +152,9 @@ export const queryClient = new QueryClient({ queries: { retry: false, }, + mutations: { + retry: false, + }, }, });