Skip to content

Commit

Permalink
Forbid cleanup of instances in overview pages
Browse files Browse the repository at this point in the history
  • Loading branch information
arbulu89 committed Jul 2, 2024
1 parent 68d85ed commit f53662a
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 5 deletions.
15 changes: 12 additions & 3 deletions assets/js/pages/DatabasesOverview/DatabaseItemOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import React from 'react';
import { DATABASE_TYPE } from '@lib/model/sapSystems';
import InstanceOverview from '@pages/InstanceOverview';

export function DatabaseInstance({ instance, onCleanUpClick }) {
export function DatabaseInstance({ instance, userAbilities, onCleanUpClick }) {
return (
<InstanceOverview
instanceType={DATABASE_TYPE}
instance={instance}
userAbilities={userAbilities}
cleanUpPermittedFor={['cleanup:database_instance']}
onCleanUpClick={onCleanUpClick}
/>
);
Expand All @@ -27,6 +29,7 @@ const databaseInstanceColumns = [
function PlainDatabaseItemOverview({
instances,
asDatabaseLayer = false,
userAbilities,
onCleanUpClick,
}) {
return (
Expand Down Expand Up @@ -59,6 +62,7 @@ function PlainDatabaseItemOverview({
<DatabaseInstance
key={`${instance.host_id}_${instance.instance_number}`}
instance={instance}
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
))}
Expand All @@ -69,21 +73,23 @@ function PlainDatabaseItemOverview({
);
}

function DatabaseLayer({ instances, onCleanUpClick }) {
function DatabaseLayer({ instances, userAbilities, onCleanUpClick }) {
return (
<PlainDatabaseItemOverview
instances={instances}
asDatabaseLayer
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
);
}

function DatabaseInstances({ instances, onCleanUpClick }) {
function DatabaseInstances({ instances, userAbilities, onCleanUpClick }) {
return (
<div className="p-2">
<PlainDatabaseItemOverview
instances={instances}
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
</div>
Expand All @@ -93,18 +99,21 @@ function DatabaseInstances({ instances, onCleanUpClick }) {
function DatabaseItemOverview({
database,
asDatabaseLayer = false,
userAbilities,
onCleanUpClick,
}) {
const { databaseInstances } = database;

return asDatabaseLayer ? (
<DatabaseLayer
instances={databaseInstances}
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
) : (
<DatabaseInstances
instances={databaseInstances}
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
);
Expand Down
2 changes: 2 additions & 0 deletions assets/js/pages/DatabasesOverview/DatabasesOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function DatabasesOverview({
databases,
databaseInstances,
loading,
userAbilities,
onTagAdd,
onTagRemove,
onInstanceCleanUp,
Expand Down Expand Up @@ -116,6 +117,7 @@ function DatabasesOverview({
collapsibleDetailRenderer: (database) => (
<DatabaseItemOverview
database={database}
userAbilities={userAbilities}
onCleanUpClick={(instance, _type) => {
setCleanUpModalOpen(true);
setInstanceToDeregister(instance);
Expand Down
14 changes: 14 additions & 0 deletions assets/js/pages/DatabasesOverview/DatabasesOverview.stories.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ export default {
defaultValue: { summary: false },
},
},
userAbilities: {
control: 'array',
description: 'Current user abilities',
},
onTagAdd: {
action: 'Add tag',
description: 'Called when a new tag is added',
Expand Down Expand Up @@ -110,6 +114,7 @@ export const Databases = {
databases,
databaseInstances: enrichedInstances,
loading: false,
userAbilities: [{ name: 'all', resource: 'all' }],
},
};

Expand All @@ -118,6 +123,7 @@ export const WithSystemReplication = {
databases: [databaseWithSR],
databaseInstances: systemReplicationInstances,
loading: false,
userAbilities: [{ name: 'all', resource: 'all' }],
},
};

Expand All @@ -126,5 +132,13 @@ export const WithAbsentInstances = {
databases: [databaseWithAbsentInstances],
databaseInstances: absentInstance,
loading: false,
userAbilities: [{ name: 'all', resource: 'all' }],
},
};

export const UnauthorizedCleanUp = {
args: {
...WithAbsentInstances.args,
userAbilities: [],
},
};
31 changes: 31 additions & 0 deletions assets/js/pages/DatabasesOverview/DatabasesOverview.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ describe('DatabasesOverview component', () => {
<DatabasesOverview
databases={[database]}
databaseInstances={database.database_instances}
userAbilities={[{ name: 'all', resource: 'all' }]}
onInstanceCleanUp={mockedCleanUp}
/>
);
Expand All @@ -47,6 +48,36 @@ describe('DatabasesOverview component', () => {
database.database_instances[0]
);
});

it('should forbid instance cleanup', async () => {
const user = userEvent.setup();

const database = databaseFactory.build();

database.database_instances[0].absent_at = faker.date
.past()
.toISOString();

renderWithRouter(
<DatabasesOverview
databases={[database]}
databaseInstances={database.database_instances}
userAbilities={[]}
/>
);

const cleanUpButton = screen.getByText('Clean up').closest('button');

expect(cleanUpButton).toBeDisabled();

await user.click(cleanUpButton);

await user.hover(cleanUpButton);

expect(
screen.queryByText('You are not authorized for this action')
).toBeVisible();
});
});

describe('filtering', () => {
Expand Down
3 changes: 3 additions & 0 deletions assets/js/pages/DatabasesOverview/DatabasesOverviewPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React from 'react';
import { useSelector, useDispatch } from 'react-redux';

import { getEnrichedDatabaseInstances } from '@state/selectors/sapSystem';
import { getUserProfile } from '@state/selectors/user';
import {
addTagToDatabase,
removeTagFromDatabase,
Expand All @@ -27,13 +28,15 @@ function DatabasesOverviewPage() {
const enrichedDatabaseInstances = useSelector((state) =>
getEnrichedDatabaseInstances(state)
);
const { abilities } = useSelector(getUserProfile);
const dispatch = useDispatch();

return (
<DatabasesOverview
databases={databases}
databaseInstances={enrichedDatabaseInstances}
loading={loading}
userAbilities={abilities}
onTagAdd={(tag, databaseID) => {
addTag(tag, databaseID);
dispatch(addTagToDatabase({ tags: [{ value: tag }], id: databaseID }));
Expand Down
4 changes: 4 additions & 0 deletions assets/js/pages/InstanceOverview/InstanceOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ function InstanceOverview({
absent_at: absentAt,
deregistering,
},
userAbilities,
cleanUpPermittedFor,
onCleanUpClick,
}) {
const isDatabase = DATABASE_TYPE === instanceType;
Expand Down Expand Up @@ -77,6 +79,8 @@ function InstanceOverview({
type="transparent"
className="jungle-green-500 border-none shadow-none"
cleaning={deregistering}
userAbilities={userAbilities}
permittedFor={cleanUpPermittedFor}
onClick={() => onCleanUpClick(instance, instanceType)}
/>
</div>
Expand Down
30 changes: 30 additions & 0 deletions assets/js/pages/InstanceOverview/InstanceOverview.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ describe('InstanceOverview', () => {
<InstanceOverview
instanceType={APPLICATION_TYPE}
instance={absentInstance}
userAbilities={[{ name: 'all', resource: 'all' }]}
/>
);

Expand Down Expand Up @@ -95,9 +96,38 @@ describe('InstanceOverview', () => {
<InstanceOverview
instanceType={DATABASE_TYPE}
instance={absentInstance}
userAbilities={[{ name: 'all', resource: 'all' }]}
/>
);

expect(screen.getByLabelText('Loading')).toBeInTheDocument();
});

it('should forbid instance cleanup', async () => {
const user = userEvent.setup();

const absentInstance = databaseInstanceFactory.build({
absent_at: faker.date.past().toISOString(),
});

renderWithRouter(
<InstanceOverview
instanceType={DATABASE_TYPE}
instance={absentInstance}
userAbilities={[]}
/>
);

const cleanUpButton = screen.getByText('Clean up').closest('button');

expect(cleanUpButton).toBeDisabled();

await user.click(cleanUpButton);

await user.hover(cleanUpButton);

expect(
screen.queryByText('You are not authorized for this action')
).toBeVisible();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { APPLICATION_TYPE } from '@lib/model/sapSystems';
import DatabaseItemOverview from '@pages/DatabasesOverview/DatabaseItemOverview';
import InstanceOverview from '@pages/InstanceOverview';

function ApplicationInstance({ instance, onCleanUpClick }) {
function ApplicationInstance({ instance, userAbilities, onCleanUpClick }) {
return (
<InstanceOverview
instanceType={APPLICATION_TYPE}
instance={instance}
userAbilities={userAbilities}
cleanUpPermittedFor={['cleanup:application_instance']}
onCleanUpClick={onCleanUpClick}
/>
);
Expand All @@ -24,7 +26,7 @@ const applicationInstanceColumns = [
{ key: 'cleanupButton', cssClass: 'w-48' },
];

function SapSystemItemOverview({ sapSystem, onCleanUpClick }) {
function SapSystemItemOverview({ sapSystem, userAbilities, onCleanUpClick }) {
const { applicationInstances, databaseInstances } = sapSystem;

return (
Expand Down Expand Up @@ -56,6 +58,7 @@ function SapSystemItemOverview({ sapSystem, onCleanUpClick }) {
<ApplicationInstance
key={`${instance.host_id}_${instance.instance_number}`}
instance={instance}
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
))}
Expand All @@ -66,6 +69,7 @@ function SapSystemItemOverview({ sapSystem, onCleanUpClick }) {
<DatabaseItemOverview
database={{ databaseInstances }}
asDatabaseLayer
userAbilities={userAbilities}
onCleanUpClick={onCleanUpClick}
/>
</div>
Expand Down
2 changes: 2 additions & 0 deletions assets/js/pages/SapSystemsOverviewPage/SapSystemsOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function SapSystemsOverview({
applicationInstances,
databaseInstances,
loading,
userAbilities,
onTagAdd,
onTagRemove,
onInstanceCleanUp,
Expand Down Expand Up @@ -106,6 +107,7 @@ function SapSystemsOverview({
collapsibleDetailRenderer: (sapSystem) => (
<SAPSystemItemOverview
sapSystem={sapSystem}
userAbilities={userAbilities}
onCleanUpClick={(instance, type) => {
setCleanUpModalOpen(true);
setInstanceToDeregister(instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ export default {
defaultValue: { summary: false },
},
},
userAbilities: {
control: 'array',
description: 'Current user abilities',
},
onTagAdd: {
action: 'Add tag',
description: 'Called when a new tag is added',
Expand Down Expand Up @@ -115,6 +119,7 @@ export const SapSystems = {
applicationInstances: enrichedApplicationInstances,
databaseInstances: enrichedDatabaseInstances,
loading: false,
userAbilities: [{ name: 'all', resource: 'all' }],
},
};

Expand All @@ -124,5 +129,13 @@ export const WithAbsentInstances = {
applicationInstances: enrichedAbsentApplicationInstances,
databaseInstances: enrichedAbsentDatabaseInstances,
loading: false,
userAbilities: [{ name: 'all', resource: 'all' }],
},
};

export const UnauthorizedCleanUp = {
args: {
...WithAbsentInstances.args,
userAbilities: [],
},
};
Loading

0 comments on commit f53662a

Please sign in to comment.