Skip to content

Commit

Permalink
change: add confirmation dialog for trashcan
Browse files Browse the repository at this point in the history
  • Loading branch information
daniele-mng committed Sep 27, 2024
1 parent 40e19d4 commit 4d67f0a
Show file tree
Hide file tree
Showing 6 changed files with 225 additions and 41 deletions.
2 changes: 2 additions & 0 deletions public/locales/gsa-de.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@
"Apps": "Apps",
"Are you sure you want to delete all rows in the page of the table? This action cannot be undone.": "Möchten Sie wirklich alle Zeilen auf der Seite der Tabelle löschen? Diese Aktion kann nicht rückgängig gemacht werden.",
"Are you sure you want to move all rows in the page of the table to the trashcan?": "Möchten Sie wirklich alle Zeilen auf der Seite der Tabelle in den Papierkorb verschieben?",
"Are you sure you want to empty the trash?": "Sind Sie sicher, dass Sie den Pap,ierkorb leeren möchten?",
"An error occurred while emptying the trash, please try again.": "Beim Leeren des Papierkorbs ist ein Fehler aufgetreten, bitte versuchen Sie es erneut.",
"As a short-cut the following steps will be done for you:": "Als Abkürzung wird folgendes durchgeführt:",
"As soon as the scan progress is beyond 1%, you can already jump to the scan report by clicking on the progress bar in the \"Status\" column and review the results collected so far.": "Sobald der Scanfortschritt 1 % überschritten hat, können Sie über die Statusanzeige in der Spalte \"Status\" auf der Seite \"Aufgaben\" die bereits gesammelten Ergebnisse einsehen.",
"Ascending": "Aufsteigend",
Expand Down
6 changes: 6 additions & 0 deletions src/web/components/dialog/confirmationdialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const ConfirmationDialogContent = ({
close,
rightButtonTitle,
onResumeClick,
loading,
}) => {
const handleResume = useCallback(() => {
if (onResumeClick) {
Expand All @@ -34,6 +35,7 @@ const ConfirmationDialogContent = ({
rightButtonTitle={rightButtonTitle}
onLeftButtonClick={close}
onRightButtonClick={handleResume}
loading={loading}
/>
</DialogContent>
);
Expand All @@ -44,6 +46,7 @@ ConfirmationDialogContent.propTypes = {
content: PropTypes.elementOrString,
rightButtonTitle: PropTypes.string,
onResumeClick: PropTypes.func.isRequired,
loading: PropTypes.bool,
};

const ConfirmationDialog = ({
Expand All @@ -53,6 +56,7 @@ const ConfirmationDialog = ({
rightButtonTitle,
onClose,
onResumeClick,
loading,
}) => {
const [_] = useTranslation();

Expand All @@ -65,6 +69,7 @@ const ConfirmationDialog = ({
content={content}
rightButtonTitle={rightButtonTitle}
onResumeClick={onResumeClick}
loading={loading}
/>
)}
</Dialog>
Expand All @@ -78,6 +83,7 @@ ConfirmationDialog.propTypes = {
width: PropTypes.string,
onClose: PropTypes.func.isRequired,
onResumeClick: PropTypes.func.isRequired,
loading: PropTypes.bool,
};

export default ConfirmationDialog;
3 changes: 1 addition & 2 deletions src/web/components/dialog/twobuttonfooter.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/


import React from 'react';

import PropTypes from 'web/utils/proptypes';
Expand All @@ -25,7 +24,7 @@ const DialogTwoButtonFooter = ({
const [_] = useTranslation();
leftButtonTitle = leftButtonTitle || _('Cancel');
return (
<DialogFooterLayout align={['end', 'center']} shrink="0">
<DialogFooterLayout align={['space-between', 'center']} shrink="0">
<Button
data-testid="dialog-close-button"
disabled={isLoading}
Expand Down

This file was deleted.

156 changes: 156 additions & 0 deletions src/web/pages/extras/__tests__/trashcanpage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/* SPDX-FileCopyrightText: 2024 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {describe, test, expect, testing} from '@gsa/testing';

import {userEvent, rendererWith, waitFor} from 'web/utils/testing';

import TrashcanPage from 'web/pages/extras/trashcanpage';
import Capabilities from 'gmp/capabilities/capabilities';

/*
* The following is a workaround for userEvent v14 and fake timers https://github.com/testing-library/react-testing-library/issues/1197
*/

testing.useFakeTimers({
shouldAdvanceTime: true,
});

const gmp = {
trashcan: {
empty: testing.fn().mockResolvedValueOnce(),
get: testing.fn().mockReturnValue(
Promise.resolve({
data: [],
}),
),
},
settings: {
manualUrl: 'http://docs.greenbone.net/GSM-Manual/gos-5/',
},
user: {
renewSession: testing.fn().mockReturnValue(
Promise.resolve({
data: 'foo',
}),
),
},
};

const capabilities = new Capabilities(['everything']);

describe('Trashcan page tests', () => {
test('Should render with empty trashcan button and empty out trash', async () => {
const {render} = rendererWith({
gmp,
capabilities,
store: true,
});

const {getByText, queryByTestId, getByRole} = render(<TrashcanPage />);
expect(queryByTestId('loading')).toBeVisible();
await waitFor(() => {
expect(queryByTestId('loading')).not.toBeInTheDocument();
});
const emptyTrashcanButton = getByRole('button', {
name: /Empty Trash/i,
});

userEvent.click(emptyTrashcanButton);
await waitFor(() => {
expect(
getByText('Are you sure you want to empty the trash?'),
).toBeVisible();
});

const confirmButton = getByRole('button', {name: /Confirm/i});

await userEvent.click(confirmButton);

await waitFor(() => {
expect(gmp.trashcan.empty).toHaveBeenCalled();
});

testing.advanceTimersByTime(1000);

await waitFor(() => {
expect(confirmButton).not.toBeVisible();
});
});

test('Should render with empty trashcan button and handle error case', async () => {
const errorGmp = {
...gmp,
trashcan: {
...gmp.trashcan,
empty: testing
.fn()
.mockRejectedValue(new Error('Failed to empty trash')),
},
};
const {render} = rendererWith({
gmp: errorGmp,
capabilities,
store: true,
});

const {getByText, queryByTestId, getByRole} = render(<TrashcanPage />);
expect(queryByTestId('loading')).toBeVisible();
await waitFor(() => {
expect(queryByTestId('loading')).not.toBeInTheDocument();
});
const emptyTrashcanButton = getByRole('button', {
name: /Empty Trash/i,
});

userEvent.click(emptyTrashcanButton);
await waitFor(() => {
expect(
getByText('Are you sure you want to empty the trash?'),
).toBeVisible();
});

const confirmButton = getByRole('button', {name: /Confirm/i});

await userEvent.click(confirmButton);

expect(errorGmp.trashcan.empty).toHaveBeenCalled();

expect(
getByText(
'An error occurred while emptying the trash, please try again.',
),
).toBeVisible();
});

test('Should render open and close dialog', async () => {
const {render} = rendererWith({
gmp,
capabilities,
store: true,
});

const {getByText, queryByTestId, getByRole} = render(<TrashcanPage />);
expect(queryByTestId('loading')).toBeVisible();
await waitFor(() => {
expect(queryByTestId('loading')).not.toBeInTheDocument();
});
const emptyTrashcanButton = getByRole('button', {
name: /Empty Trash/i,
});

await userEvent.click(emptyTrashcanButton);

expect(
getByText('Are you sure you want to empty the trash?'),
).toBeVisible();

const cancelButton = getByRole('button', {name: /Cancel/i});

await userEvent.click(cancelButton);

expect(cancelButton).not.toBeVisible();
});
});
Loading

0 comments on commit 4d67f0a

Please # to comment.