Skip to content

Commit

Permalink
Merge branch 'bugfix/ARTESCA-11299-prevent-create-a-new-storage-servi…
Browse files Browse the repository at this point in the history
…ce-and-edition-of-the-default' into q/2.2
  • Loading branch information
bert-e committed Jul 2, 2024
2 parents 501942e + 894e452 commit d3d9aeb
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 45 deletions.
17 changes: 11 additions & 6 deletions src/js/mock/managementClientMSWHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,22 @@ export const LOCATIONS = {
name: 'ring-nick',
objectId: '99a06f79-c62c-11ec-b993-7e8a0ab79998',
},
'us-east-1': {
isBuiltin: true,
locationType: 'location-file-v1',
name: 'us-east-1',
objectId: '95dbedf5-9888-11ec-8565-1ac2af7d1e53',
},
[azureblobstorage]: {
locationType: 'location-azure-v1',
name: azureblobstorage,
details: {},
},
'us-east-1': {
details: {
bootstrapList: [
'artesca-storage-service-hdservice-proxy.xcore.svc:18888',
],
repoId: null,
},
locationType: 'location-scality-hdclient-v2',
name: 'us-east-1',
objectId: '22f31240-4bd3-11ee-98b3-1e5b6f897bc7',
},
};

export const ENDPOINTS = [
Expand Down
13 changes: 9 additions & 4 deletions src/react/locations/LocationEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ function LocationEditor() {
} = useAccountsLocationsAndEndpoints({
accountsLocationsEndpointsAdapter,
});
const locationEditing = accountsLocationsAndEndpoints?.locations.find(
const locations = accountsLocationsAndEndpoints?.locations;
const locationEditing = locations?.find(
(location) => location.name === locationName,
);
const capabilities = useSelector(
Expand All @@ -73,9 +74,13 @@ function LocationEditor() {
convertToForm({ ...newLocationDetails(), ...locationEditing }),
);
const selectOptions = useMemo(() => {
//@ts-expect-error fix this when you are working on it
return selectStorageOptions(capabilities, makeLabel, !editingExisting);
}, [capabilities, editingExisting]);
return selectStorageOptions(
capabilities,
locations,
makeLabel,
!editingExisting,
);
}, [capabilities, editingExisting, locations]);
useMemo(() => {
if (locationEditing) {
setLocation(convertToForm(locationEditing));
Expand Down
20 changes: 15 additions & 5 deletions src/react/locations/LocationsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ const ActionButtons = ({
);
};

const isEditButtonDisabled =
rowValues.isBuiltin || rowValues.type === 'location-scality-hdclient-v2';

return (
<div>
<DeleteConfirmation
Expand All @@ -165,11 +168,18 @@ const ActionButtons = ({
onClick={() => history.push(`/locations/${locationName}/edit`)}
type="button"
aria-label="Edit Location"
tooltip={{
overlay: 'Edit Location',
placement: 'top',
}}
disabled={rowValues.isBuiltin}
tooltip={
isEditButtonDisabled
? {
overlay: 'Edit Location is disabled for this location',
placement: 'top',
}
: {
overlay: 'Edit Location',
placement: 'top',
}
}
disabled={isEditButtonDisabled}
/>
<Button
size="inline"
Expand Down
47 changes: 44 additions & 3 deletions src/react/locations/__tests__/LocationEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ import LocationEditor from '../LocationEditor';

import {
fireEvent,
render,
screen,
waitFor,
waitForElementToBeRemoved,
} from '@testing-library/react';
import { notFalsyTypeGuard } from '../../../types/typeGuards';
import {
TEST_API_BASE_URL,
Wrapper,
mockOffsetSize,
reduxRender,
selectClick,
Expand All @@ -17,6 +20,7 @@ import { setupServer } from 'msw/node';
import { getConfigOverlay } from '../../../js/mock/managementClientMSWHandlers';
import { INSTANCE_ID } from '../../actions/__tests__/utils/testUtil';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';

const server = setupServer(getConfigOverlay(TEST_API_BASE_URL, INSTANCE_ID));

Expand Down Expand Up @@ -45,13 +49,11 @@ describe('LocationEditor', () => {
);
await selectClick(selector);
await userEvent.keyboard('{arrowup}');

expect(
container.querySelector('.sc-select__option--is-focused')?.textContent,
).toBe('Storage Service for ARTESCA');
).toBe('Scality ARTESCA S3');

[
'Scality ARTESCA S3',
'Scality RING with S3 Connector',
'Amazon S3',
'Google Cloud Storage',
Expand All @@ -69,4 +71,43 @@ describe('LocationEditor', () => {
).toBe(locationName);
});
});
const selectors = {
loadingLocation: () => screen.getByText('Loading location...'),
locationType: () => screen.getByLabelText(/location type \*/i),
};

it('should hide the artesca storage service if it is already created', async () => {
//S
server.use(
rest.get(
`${TEST_API_BASE_URL}/api/v1/config/overlay/view/${INSTANCE_ID}`,
(_, res, ctx) =>
res(
ctx.json({
locations: {
'us-east-2': {
details: {
bootstrapList: [
'artesca-storage-service-hdservice-proxy.xcore.svc:18888',
],
repoId: null,
},
locationType: 'location-scality-hdclient-v2',
name: 'us-east-2',
objectId: '22f31240-4bd3-11ee-98b3-1e5b6f897bc7',
},
},
}),
),
),
);
render(<LocationEditor />, { wrapper: Wrapper });
await waitForElementToBeRemoved(() => selectors.loadingLocation());
//E
selectClick(selectors.locationType());
//V
await waitFor(() => {
expect(screen.queryByText('Storage Service for ARTESCA')).toBeNull();
});
});
});
65 changes: 65 additions & 0 deletions src/react/locations/__tests__/LocationList.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {
screen,
waitFor,
waitForElementToBeRemoved,
within,
} from '@testing-library/react';
import { setupServer } from 'msw/node';
import { rest } from 'msw';
import {
getConfigOverlay,
getStorageConsumptionMetricsHandlers,
} from '../../../js/mock/managementClientMSWHandlers';
import {
TEST_API_BASE_URL,
mockOffsetSize,
renderWithRouterMatch,
zenkoUITestConfig,
} from '../../utils/testUtil';
import { INSTANCE_ID } from '../../actions/__tests__/utils/testUtil';
import { LocationsList } from '../LocationsList';

const server = setupServer(
getConfigOverlay(TEST_API_BASE_URL, INSTANCE_ID),
...getStorageConsumptionMetricsHandlers(
zenkoUITestConfig.managementEndpoint,
INSTANCE_ID,
),
rest.get(
`${TEST_API_BASE_URL}/api/v1/instance/${INSTANCE_ID}/status`,
(req, res, ctx) => res(ctx.json({})),
),
);

describe('LocationList', () => {
beforeAll(() => {
jest.setTimeout(30_000);
mockOffsetSize(500, 100);
server.listen({ onUnhandledRequest: 'error' });
});
afterEach(() => {
server.resetHandlers();
});
afterAll(() => {
server.close();
});
it('should disable the delete button for default location', async () => {
//S
renderWithRouterMatch(<LocationsList />);
//E
await waitForElementToBeRemoved(() => [
...screen.queryAllByText(/Loading/i),
]);
const defaultArtescaLocationRow = screen.getByRole('row', {
name: /us-east-1 Storage Service for ARTESCA/i,
});
//V
await waitFor(() => {
expect(
within(defaultArtescaLocationRow).getByRole('button', {
name: /Edit Location/i,
}),
).toBeDisabled();
});
});
});
13 changes: 10 additions & 3 deletions src/react/utils/storageOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { InstanceStateSnapshot } from '../../types/stats';
import type { Capabilities, InstanceStateSnapshot } from '../../types/stats';
import type {
LabelFunction,
StorageOptionSelect,
Expand All @@ -8,7 +8,6 @@ import {
JAGUAR_S3_ENDPOINT,
JAGUAR_S3_LOCATION_KEY,
Location as LegacyLocation,
Locations,
ORANGE_S3_ENDPOINT,
ORANGE_S3_LOCATION_KEY,
OUTSCALE_PUBLIC_S3_ENDPOINT,
Expand All @@ -20,6 +19,7 @@ import { LocationForm } from '../../types/location';
import { Location } from '../next-architecture/domain/entities/location';
import { LocationInfo } from '../next-architecture/adapters/accounts-locations/ILocationsAdapter';
import { LocationV1 } from '../../js/managementClient/api';

export function checkSupportsReplicationTarget(
locations: LocationInfo[],
): boolean {
Expand Down Expand Up @@ -104,12 +104,19 @@ export const getLocationTypeShort = (
};

export function selectStorageOptions(
capabilities: Pick<InstanceStateSnapshot, 'capabilities'>,
capabilities: Capabilities,
locations?: LocationInfo[],
labelFn?: LabelFunction,
exceptHidden = true,
): Array<StorageOptionSelect> {
const hdLocation = locations?.find(
(l) => l.type === LocationV1.LocationTypeEnum.ScalityHdclientV2,
);
return Object.keys(storageOptions)
.filter((o) => {
if (hdLocation && o === 'location-scality-hdclient-v2') {
return false;
}
if (exceptHidden) {
const hidden = !!storageOptions[o].hidden;

Expand Down
18 changes: 9 additions & 9 deletions src/react/workflow/__tests__/TransitionForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,15 @@ describe('TransitionForm', () => {
await waitFor(() =>
screen.getByRole('option', {
name: new RegExp(
`${notVersionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${notVersionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
);
await userEvent.click(
screen.getByRole('option', {
name: new RegExp(
`${notVersionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${notVersionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
Expand All @@ -233,15 +233,15 @@ describe('TransitionForm', () => {
await waitFor(() =>
screen.getByRole('option', {
name: new RegExp(
`${versionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${versionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
);
await userEvent.click(
screen.getByRole('option', {
name: new RegExp(
`${versionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${versionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
Expand Down Expand Up @@ -336,15 +336,15 @@ describe('TransitionForm', () => {
await waitFor(() =>
screen.getByRole('option', {
name: new RegExp(
`${notVersionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${notVersionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
);
await userEvent.click(
screen.getByRole('option', {
name: new RegExp(
`${notVersionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${notVersionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
Expand Down Expand Up @@ -384,15 +384,15 @@ describe('TransitionForm', () => {
await waitFor(() =>
screen.getByRole('option', {
name: new RegExp(
`${notVersionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${notVersionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
);
await userEvent.click(
screen.getByRole('option', {
name: new RegExp(
`${notVersionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${notVersionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
Expand Down Expand Up @@ -435,7 +435,7 @@ describe('TransitionForm', () => {
userEvent.click(
screen.getByRole('option', {
name: new RegExp(
`${versionedBucket} \\(us-east-1 / Local Filesystem \\)`,
`${versionedBucket} \\(us-east-1 / Storage Service \\)`,
'i',
),
}),
Expand Down
Loading

0 comments on commit d3d9aeb

Please sign in to comment.