Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DG download "remove all" button disables once pressed #1177 #1184

Merged
merged 3 commits into from Mar 29, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -245,6 +245,37 @@ describe('Download cart table component', () => {
expect(wrapper.exists('[data-testid="no-selections-message"]')).toBe(true);
});

it('disables remove all button while request is processing', async () => {
(removeAllDownloadCartItems as jest.Mock).mockImplementation(() => {
return new Promise((resolve) => setTimeout(resolve, 2000));
});

const wrapper = createWrapper();

await act(async () => {
await flushPromises();
wrapper.update();
await flushPromises();
wrapper.update();
});

await act(async () => {
wrapper.find('button#removeAllButton').simulate('click');
await flushPromises();
wrapper.update();
});
expect(
wrapper.find('button#removeAllButton').prop('disabled')
).toBeTruthy();

setTimeout(() => {
wrapper.update();
expect(wrapper.exists('[data-testid="no-selections-message"]')).toBe(
true
);
}, 2001);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I'm not a fan of. It manually adds a non-mocked timeout to the test to force the wrapper to update and display the correct thing on the DOM. We want to use fake timers to adhere to good testing practice. Any help on this one would be appreciated!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Jest's fake timers and promises inherently don't work well with one another - see https://github.com/ral-facilities/scigateway/blob/169b596d761fc7426136faca946db692849f3f19/src/App.test.tsx#L32 for an example of me working around it. See this issue for info: jestjs/jest#10221. One option is to try using the legacy Jest fake timers, as for example there are a few tests in SG which work with old timers and not with the new ones (like the one I linked). However, the only way I could get things working was to manually wait for real timers. Perhaps using a dedicated sleep function or even just a sleep line of code like await new Promise((r) => setTimeout(r, 2000)); is more semantic, so you use that line then you wrapper.update/assert to your heart's content rather than within the timeout itself?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for that, I'll use that example as a reference for another attempt. I had a go with the legacy timers, to no avail. Perhaps this will help. I'll ping you again when I have something ready for review :)

});

it("removes an item when said item's remove button is clicked", async () => {
const wrapper = createWrapper();

Expand Down
Expand Up @@ -20,6 +20,7 @@ import {
makeStyles,
Theme,
Link,
CircularProgress,
} from '@material-ui/core';
import { RemoveCircle } from '@material-ui/icons';
import {
Expand Down Expand Up @@ -66,6 +67,7 @@ const DownloadCartTable: React.FC<DownloadCartTableProps> = (
const [dataLoaded, setDataLoaded] = React.useState(false);
const [sizesLoaded, setSizesLoaded] = React.useState(true);
const [sizesFinished, setSizesFinished] = React.useState(true);
const [removingAll, setRemovingAll] = React.useState(false);

const fileCountMax = settings.fileCountMax;
const totalSizeMax = settings.totalSizeMax;
Expand Down Expand Up @@ -416,17 +418,24 @@ const DownloadCartTable: React.FC<DownloadCartTableProps> = (
style={{ marginRight: '1em' }}
>
<Grid item>
{/* Request to remove all selections is in progress. To prevent excessive requests, disable button during request */}
<Button
className="tour-download-remove-button"
id="removeAllButton"
variant="contained"
color="primary"
onClick={() =>
disabled={removingAll}
startIcon={removingAll && <CircularProgress size={20} />}
onClick={() => {
setRemovingAll(true);
removeAllDownloadCartItems({
facilityName: settings.facilityName,
downloadApiUrl: settings.downloadApiUrl,
}).then(() => setData([]))
}
}).then(() => {
setData([]);
setRemovingAll(false);
});
}}
>
{t('downloadCart.remove_all')}
</Button>
Expand Down