{
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -32,52 +27,49 @@ describe('ButtonCopyToClipboard', () => {
});
it('renders tooltip after clicking button', async () => {
- const { getByTestId, getByRole, queryByRole } = render(
);
- expect(queryByRole('tooltip')).toBeNull();
+ render(
);
+ expect(screen.queryByRole('tooltip')).toBeNull();
- const btn = getByTestId('ctcBtn');
- fireEvent.click(btn);
+ const btn = screen.getByTestId('ctcBtn');
+ userEvent.click(btn);
- await waitFor(() => {
- expect(clipboardWriteTextMock).toHaveBeenCalledTimes(1);
- expect(clipboardWriteTextMock).toHaveBeenCalledWith('Text to copy');
- });
+ expect(clipboardWriteTextMock).toHaveBeenCalledTimes(1);
+ expect(clipboardWriteTextMock).toHaveBeenCalledWith('Text to copy');
- waitFor(() => {
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
- });
-
- it('hides tooltip after 2 seconds', async () => {
- const { getByTestId, getByRole, queryByRole } = render(
);
- expect(queryByRole('tooltip')).toBeNull();
-
- const btn = getByTestId('ctcBtn');
- fireEvent.click(btn);
-
- await waitFor(() => {
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
-
- waitFor(() => {
- expect(setTimeout).toHaveBeenCalledTimes(2);
- expect(setTimeout).toHaveBeenLastCalledWith(expect.any(Function), 2000);
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
});
it('renders tooltip after clicking button when navidator.clipboard is undefined', async () => {
(navigator as any).clipboard = null;
- const { getByTestId, getByRole, queryByRole } = render(
);
- expect(queryByRole('tooltip')).toBeNull();
+ render(
);
+ expect(screen.queryByRole('tooltip')).toBeNull();
- const btn = getByTestId('ctcBtn');
- fireEvent.click(btn);
+ const btn = screen.getByTestId('ctcBtn');
+ userEvent.click(btn);
- await waitFor(() => {
- expect(copyToClipboardMock).toHaveBeenCalledTimes(1);
- expect(copyToClipboardMock).toHaveBeenCalledWith('copy');
+ await waitFor(() => expect(copyToClipboardMock).toHaveBeenCalledWith('copy'));
+ expect(copyToClipboardMock).toHaveBeenCalledTimes(1);
+
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+ });
+
+ it('hides tooltip after 2 seconds', async () => {
+ jest.useFakeTimers();
+
+ render(
);
+ expect(screen.queryByRole('tooltip')).toBeNull();
+
+ const btn = screen.getByTestId('ctcBtn');
+ userEvent.click(btn);
+
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+
+ act(() => {
+ jest.advanceTimersByTime(2000);
});
- expect(getByRole('tooltip')).toBeInTheDocument();
+ expect(screen.queryByRole('tooltip')).toBeNull();
+
+ jest.useRealTimers();
});
});
diff --git a/web/src/layout/common/ElementWithTooltip.test.tsx b/web/src/layout/common/ElementWithTooltip.test.tsx
index 19e9a8c2..564d09f9 100644
--- a/web/src/layout/common/ElementWithTooltip.test.tsx
+++ b/web/src/layout/common/ElementWithTooltip.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { act, render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import ElementWithTooltip from './ElementWithTooltip';
@@ -11,13 +12,7 @@ const defaultProps = {
};
describe('ElementWithTooltip', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -37,48 +32,52 @@ describe('ElementWithTooltip', () => {
expect(container).toBeEmptyDOMElement();
});
- it('displays tootltip', async () => {
- const { getByTestId, getByText, getByRole } = render(
);
+ it('displays tooltip', async () => {
+ jest.useFakeTimers();
- const badge = getByTestId('elementWithTooltip');
- fireEvent.mouseEnter(badge);
+ render(
);
- await waitFor(() => {
- expect(getByText(defaultProps.tooltipMessage)).toBeInTheDocument();
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
+ const badge = screen.getByTestId('elementWithTooltip');
+ userEvent.hover(badge);
+
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+ expect(screen.getByText(defaultProps.tooltipMessage)).toBeInTheDocument();
+
+ jest.useRealTimers();
});
- it('hides tootltip on mouse leave', async () => {
- const { getByTestId, getByText, getByRole, queryByRole } = render(
);
+ it('hides tooltip on mouse leave', async () => {
+ jest.useFakeTimers();
- const badge = getByTestId('elementWithTooltip');
- fireEvent.mouseEnter(badge);
+ render(
);
- await waitFor(() => {
- expect(getByText(defaultProps.tooltipMessage)).toBeInTheDocument();
- expect(getByRole('tooltip')).toBeInTheDocument();
+ const badge = screen.getByTestId('elementWithTooltip');
+ userEvent.hover(badge);
+
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+ expect(screen.getByText(defaultProps.tooltipMessage)).toBeInTheDocument();
+
+ userEvent.unhover(badge);
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
- fireEvent.mouseLeave(badge);
+ expect(screen.queryByRole('tooltip')).toBeNull();
- await waitFor(() => {
- expect(queryByRole('tooltip')).toBeNull();
- });
+ jest.useRealTimers();
});
- it('does not display tootltip when visibleTooltip is false', () => {
+ it('does not display tooltip when visibleTooltip is false', () => {
const props = {
...defaultProps,
visibleTooltip: false,
};
- const { getByTestId, queryByRole } = render(
);
+ render(
);
- const badge = getByTestId('elementWithTooltip');
- fireEvent.mouseEnter(badge);
+ const badge = screen.getByTestId('elementWithTooltip');
+ userEvent.hover(badge);
- waitFor(() => {
- expect(queryByRole('tooltip')).toBeNull();
- });
+ expect(screen.queryByRole('tooltip')).toBeNull();
});
});
diff --git a/web/src/layout/common/OfficialBadge.test.tsx b/web/src/layout/common/OfficialBadge.test.tsx
index 55b9e721..64468de7 100644
--- a/web/src/layout/common/OfficialBadge.test.tsx
+++ b/web/src/layout/common/OfficialBadge.test.tsx
@@ -1,16 +1,11 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import OfficialBadge from './OfficialBadge';
describe('OfficialBadge', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -20,33 +15,31 @@ describe('OfficialBadge', () => {
});
it('renders label', async () => {
- const { getByTestId, getByText, getByRole } = render(
);
- expect(getByText('Official')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('Official')).toBeInTheDocument();
- const badge = getByTestId('elementWithTooltip');
+ const badge = screen.getByTestId('elementWithTooltip');
expect(badge).toBeInTheDocument();
- fireEvent.mouseEnter(badge);
+ userEvent.hover(badge);
- await waitFor(() => {
- expect(
- getByText('The publisher owns the software deployed by the packages in this repository')
- ).toBeInTheDocument();
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+
+ expect(
+ screen.getByText('The publisher owns the software deployed by the packages in this repository')
+ ).toBeInTheDocument();
});
it('renders label for package', async () => {
- const { getByTestId, getByText, getByRole } = render(
);
- expect(getByText('Official')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('Official')).toBeInTheDocument();
- const badge = getByTestId('elementWithTooltip');
+ const badge = screen.getByTestId('elementWithTooltip');
expect(badge).toBeInTheDocument();
- fireEvent.mouseEnter(badge);
+ userEvent.hover(badge);
- await waitFor(() => {
- expect(getByText('The publisher owns the software deployed by this package')).toBeInTheDocument();
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+
+ expect(screen.getByText('The publisher owns the software deployed by this package')).toBeInTheDocument();
});
it('does not render label', () => {
diff --git a/web/src/layout/common/OrganizationInfo.test.tsx b/web/src/layout/common/OrganizationInfo.test.tsx
index fb9c384f..821b1455 100644
--- a/web/src/layout/common/OrganizationInfo.test.tsx
+++ b/web/src/layout/common/OrganizationInfo.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { act, render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import { mocked } from 'ts-jest/utils';
@@ -27,13 +28,7 @@ const getMockOrganization = (fixtureId: string): Organization => {
};
describe('OrganizationInfo', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -43,16 +38,16 @@ describe('OrganizationInfo', () => {
});
it('renders proper content', () => {
- const { getByText, getByTestId } = render(
);
- expect(getByText(defaultProps.organizationName)).toBeInTheDocument();
- expect(getByTestId('orgLink')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText(defaultProps.organizationName)).toBeInTheDocument();
+ expect(screen.getByTestId('orgLink')).toBeInTheDocument();
});
- it('calls history push to click org link', () => {
- const { getByTestId } = render(
);
- fireEvent.click(getByTestId('orgLink'));
+ it('calls history push to click org link', async () => {
+ render(
);
+ userEvent.click(screen.getByTestId('orgLink'));
- expect(mockHistoryPush).toHaveBeenCalledTimes(1);
+ await waitFor(() => expect(mockHistoryPush).toHaveBeenCalledTimes(1));
expect(mockHistoryPush).toHaveBeenCalledWith({
pathname: '/packages/search',
search: prepareQuerystring({
@@ -65,71 +60,86 @@ describe('OrganizationInfo', () => {
});
it('displays org info to enter on link and hides on leave', async () => {
+ jest.useFakeTimers();
+
const mockOrganization = getMockOrganization('1');
mocked(API).getOrganization.mockResolvedValue(mockOrganization);
- const { getByTestId, getByAltText, getByText } = render(
);
- fireEvent.mouseEnter(getByTestId('orgLink'));
+ render(
);
+ userEvent.hover(screen.getByTestId('orgLink'));
await waitFor(() => {
expect(API.getOrganization).toHaveBeenCalledTimes(1);
});
- expect(getByTestId('externalBtn')).toBeInTheDocument();
- expect(getByAltText(mockOrganization.displayName!)).toBeInTheDocument();
- expect(getByAltText(mockOrganization.displayName!)).toHaveProperty(
+ expect(screen.getByTestId('externalBtn')).toBeInTheDocument();
+ expect(screen.getByAltText(mockOrganization.displayName!)).toBeInTheDocument();
+ expect(screen.getByAltText(mockOrganization.displayName!)).toHaveProperty(
'src',
`http://localhost/image/${mockOrganization.logoImageId!}`
);
- expect(getByText(mockOrganization.description!)).toBeInTheDocument();
+ expect(screen.getByText(mockOrganization.description!)).toBeInTheDocument();
- await waitFor(() => {
- expect(getByTestId('orgInfoDropdown')).toHaveClass('show');
+ act(() => {
+ jest.advanceTimersByTime(100);
});
- fireEvent.mouseLeave(getByTestId('orgLink'));
+ expect(await screen.findByTestId('orgInfoDropdown')).toHaveClass('show');
- await waitFor(() => {
- expect(getByTestId('orgInfoDropdown')).not.toHaveClass('show');
+ userEvent.unhover(screen.getByTestId('orgLink'));
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
+
+ expect(await screen.findByTestId('orgInfoDropdown')).not.toHaveClass('show');
+
+ jest.useRealTimers();
});
it('hides org info to leave org dropdown', async () => {
+ jest.useFakeTimers();
+
const mockOrganization = getMockOrganization('1');
mocked(API).getOrganization.mockResolvedValue(mockOrganization);
- const { getByTestId } = render(
);
- fireEvent.mouseEnter(getByTestId('orgLink'));
+ render(
);
+ userEvent.hover(screen.getByTestId('orgLink'));
await waitFor(() => {
expect(API.getOrganization).toHaveBeenCalledTimes(1);
});
- fireEvent.mouseEnter(getByTestId('orgInfoDropdown'));
- fireEvent.mouseLeave(getByTestId('orgLink'));
+ userEvent.hover(screen.getByTestId('orgInfoDropdown'));
+ userEvent.unhover(screen.getByTestId('orgLink'));
- await waitFor(() => {
- expect(getByTestId('orgInfoDropdown')).toHaveClass('show');
+ act(() => {
+ jest.advanceTimersByTime(100);
});
- fireEvent.mouseLeave(getByTestId('orgInfoDropdown'));
- await waitFor(() => {
- expect(getByTestId('orgInfoDropdown')).not.toHaveClass('show');
+ expect(await screen.findByTestId('orgInfoDropdown')).toHaveClass('show');
+
+ userEvent.unhover(screen.getByTestId('orgInfoDropdown'));
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
+
+ expect(await screen.findByTestId('orgInfoDropdown')).not.toHaveClass('show');
+
+ jest.useRealTimers();
});
it('does not render dropdown content when api call fails', async () => {
mocked(API).getOrganization.mockRejectedValue('');
- const { getByTestId } = render(
);
- fireEvent.mouseEnter(getByTestId('orgLink'));
+ render(
);
+ userEvent.hover(screen.getByTestId('orgLink'));
await waitFor(() => {
expect(API.getOrganization).toHaveBeenCalledTimes(1);
});
- await waitFor(() => {
- expect(getByTestId('orgInfoDropdown')).toBeEmptyDOMElement();
- });
+ expect(await screen.findByTestId('orgInfoDropdown')).toBeEmptyDOMElement();
});
});
diff --git a/web/src/layout/common/RepositoryInfo.test.tsx b/web/src/layout/common/RepositoryInfo.test.tsx
index d3afd613..5cd3117d 100644
--- a/web/src/layout/common/RepositoryInfo.test.tsx
+++ b/web/src/layout/common/RepositoryInfo.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { act, render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import prepareQuerystring from '../../utils/prepareQueryString';
@@ -29,13 +30,7 @@ const defaultProps = {
};
describe('RepositoryInfo', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -45,16 +40,16 @@ describe('RepositoryInfo', () => {
});
it('renders proper content', () => {
- const { getAllByText, getByTestId } = render(
);
- expect(getAllByText(defaultProps.repository.displayName)).toHaveLength(2);
- expect(getByTestId('repoLink')).toBeInTheDocument();
+ render(
);
+ expect(screen.getAllByText(defaultProps.repository.displayName)).toHaveLength(2);
+ expect(screen.getByTestId('repoLink')).toBeInTheDocument();
});
- it('calls history push to click repo link', () => {
- const { getByTestId } = render(
);
- fireEvent.click(getByTestId('repoLink'));
+ it('calls history push to click repo link', async () => {
+ render(
);
+ userEvent.click(screen.getByTestId('repoLink'));
- expect(mockHistoryPush).toHaveBeenCalledTimes(1);
+ await waitFor(() => expect(mockHistoryPush).toHaveBeenCalledTimes(1));
expect(mockHistoryPush).toHaveBeenCalledWith({
pathname: '/packages/search',
search: prepareQuerystring({
@@ -68,38 +63,56 @@ describe('RepositoryInfo', () => {
});
it('displays repo info to enter on link and hides on leave', async () => {
- const { getByTestId, getAllByText } = render(
);
- expect(getAllByText(defaultProps.repository.displayName!)).toHaveLength(2);
- expect(getByTestId('repoUrl')).toBeInTheDocument();
- expect(getByTestId('repoUrl')).toHaveTextContent(defaultProps.repository.url);
+ jest.useFakeTimers();
- fireEvent.mouseEnter(getByTestId('repoLink'));
+ render(
);
+ expect(screen.getAllByText(defaultProps.repository.displayName!)).toHaveLength(2);
+ expect(screen.getByTestId('repoUrl')).toBeInTheDocument();
+ expect(screen.getByTestId('repoUrl')).toHaveTextContent(defaultProps.repository.url);
- await waitFor(() => {
- expect(getByTestId('repoInfoDropdown')).toHaveClass('show');
+ userEvent.hover(screen.getByTestId('repoLink'));
+
+ act(() => {
+ jest.advanceTimersByTime(100);
});
- fireEvent.mouseLeave(getByTestId('repoLink'));
+ expect(await screen.findByTestId('repoInfoDropdown')).toHaveClass('show');
- await waitFor(() => {
- expect(getByTestId('repoInfoDropdown')).not.toHaveClass('show');
+ userEvent.unhover(screen.getByTestId('repoLink'));
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
+
+ expect(await screen.findByTestId('repoInfoDropdown')).not.toHaveClass('show');
+
+ jest.useRealTimers();
});
it('hides repo info to leave dropdown', async () => {
- const { getByTestId } = render(
);
- fireEvent.mouseEnter(getByTestId('repoLink'));
+ jest.useFakeTimers();
- fireEvent.mouseEnter(getByTestId('repoInfoDropdown'));
- fireEvent.mouseLeave(getByTestId('repoLink'));
- await waitFor(() => {
- expect(getByTestId('repoInfoDropdown')).toHaveClass('show');
+ render(
);
+ userEvent.hover(screen.getByTestId('repoLink'));
+
+ userEvent.hover(screen.getByTestId('repoInfoDropdown'));
+ userEvent.unhover(screen.getByTestId('repoLink'));
+
+ act(() => {
+ jest.advanceTimersByTime(100);
});
- fireEvent.mouseLeave(getByTestId('repoInfoDropdown'));
- await waitFor(() => {
- expect(getByTestId('repoInfoDropdown')).not.toHaveClass('show');
+ expect(await screen.findByTestId('repoInfoDropdown')).toHaveClass('show');
+
+ userEvent.unhover(screen.getByTestId('repoInfoDropdown'));
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
+
+ expect(await screen.findByTestId('repoInfoDropdown')).not.toHaveClass('show');
+
+ jest.useRealTimers();
});
it('renders Verified Publisher label', () => {
@@ -110,7 +123,7 @@ describe('RepositoryInfo', () => {
verifiedPublisher: true,
},
};
- const { getByText } = render(
);
- expect(getByText('Verified Publisher')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('Verified Publisher')).toBeInTheDocument();
});
});
diff --git a/web/src/layout/common/SecurityRating.test.tsx b/web/src/layout/common/SecurityRating.test.tsx
index 356c39e9..e30c6bb4 100644
--- a/web/src/layout/common/SecurityRating.test.tsx
+++ b/web/src/layout/common/SecurityRating.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import SecurityRating from './SecutityRating';
@@ -15,13 +16,7 @@ const defaultProps = {
};
describe('SecurityRating', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -31,23 +26,21 @@ describe('SecurityRating', () => {
});
it('renders label', async () => {
- const { getByTestId, getByText, getByRole, getAllByText } = render(
);
- expect(getByText('Images Security Rating')).toBeInTheDocument();
- expect(getByText('F')).toBeInTheDocument();
+ render(
);
+ expect(screen.getByText('Images Security Rating')).toBeInTheDocument();
+ expect(screen.getByText('F')).toBeInTheDocument();
- const badge = getByTestId('elementWithTooltip');
+ const badge = screen.getByTestId('elementWithTooltip');
expect(badge).toBeInTheDocument();
- fireEvent.mouseEnter(badge);
+ userEvent.hover(badge);
- await waitFor(() => {
- expect(getByRole('tooltip')).toBeInTheDocument();
- expect(getByText('No vulnerabilities found')).toBeInTheDocument();
- expect(getAllByText(/Vulnerabilities of severity/g)).toHaveLength(5);
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+ expect(screen.getByText('No vulnerabilities found')).toBeInTheDocument();
+ expect(screen.getAllByText(/Vulnerabilities of severity/g)).toHaveLength(5);
});
it('renders A label', () => {
- const { getByText } = render(
+ render(
{
onlyBadge
/>
);
- expect(getByText('A')).toBeInTheDocument();
+ expect(screen.getByText('A')).toBeInTheDocument();
});
it('renders B label', () => {
- const { getByText } = render(
+ render(
{
onlyBadge
/>
);
- expect(getByText('B')).toBeInTheDocument();
+ expect(screen.getByText('B')).toBeInTheDocument();
});
it('renders C label', () => {
- const { getByText } = render(
+ render(
{
onlyBadge
/>
);
- expect(getByText('C')).toBeInTheDocument();
+ expect(screen.getByText('C')).toBeInTheDocument();
});
it('renders D label', () => {
- const { getByText } = render(
+ render(
{
onlyBadge
/>
);
- expect(getByText('D')).toBeInTheDocument();
+ expect(screen.getByText('D')).toBeInTheDocument();
});
it('renders F label', () => {
- const { getByText } = render(
+ render(
{
onlyBadge
/>
);
- expect(getByText('F')).toBeInTheDocument();
+ expect(screen.getByText('F')).toBeInTheDocument();
});
it('renders - label', () => {
- const { getByText } = render(
+ render(
{
onlyBadge
/>
);
- expect(getByText('-')).toBeInTheDocument();
+ expect(screen.getByText('-')).toBeInTheDocument();
});
it('does not full label when onlyBadge is true', () => {
- const { queryByText } = render();
- expect(queryByText('Images Security Rating')).toBeNull();
+ render();
+ expect(screen.queryByText('Images Security Rating')).toBeNull();
});
it('does not render label', () => {
diff --git a/web/src/layout/common/SignedBadge.test.tsx b/web/src/layout/common/SignedBadge.test.tsx
index cfd555d3..7106f79c 100644
--- a/web/src/layout/common/SignedBadge.test.tsx
+++ b/web/src/layout/common/SignedBadge.test.tsx
@@ -1,16 +1,11 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import SignedBadge from './SignedBadge';
describe('SignedBadge', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -20,31 +15,28 @@ describe('SignedBadge', () => {
});
it('renders label for Helm package', async () => {
- const { getByTestId, getByText, getByRole } = render();
- expect(getByText('Signed')).toBeInTheDocument();
+ render();
+ expect(screen.getByText('Signed')).toBeInTheDocument();
- const badge = getByTestId('elementWithTooltip');
+ const badge = screen.getByTestId('elementWithTooltip');
expect(badge).toBeInTheDocument();
- fireEvent.mouseEnter(badge);
+ userEvent.hover(badge);
- await waitFor(() => {
- expect(getByText('This chart has a provenance file')).toBeInTheDocument();
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+
+ expect(screen.getByText('This chart has a provenance file')).toBeInTheDocument();
});
it('does not render label for not helm package', () => {
- const { getByTestId, getByText, queryByText, queryByRole } = render();
- expect(getByText('Signed')).toBeInTheDocument();
+ render();
+ expect(screen.getByText('Signed')).toBeInTheDocument();
- const badge = getByTestId('elementWithTooltip');
+ const badge = screen.getByTestId('elementWithTooltip');
expect(badge).toBeInTheDocument();
- fireEvent.mouseEnter(badge);
+ userEvent.hover(badge);
- waitFor(() => {
- expect(queryByText('This chart has a provenance file')).toBeNull();
- expect(queryByRole('tooltip')).toBeNull();
- });
+ expect(screen.queryByText('This chart has a provenance file')).toBeNull();
+ expect(screen.queryByRole('tooltip')).toBeNull();
});
it('does not render label', () => {
diff --git a/web/src/layout/common/VerifiedPublisherBadge.test.tsx b/web/src/layout/common/VerifiedPublisherBadge.test.tsx
index c638930f..21a5be24 100644
--- a/web/src/layout/common/VerifiedPublisherBadge.test.tsx
+++ b/web/src/layout/common/VerifiedPublisherBadge.test.tsx
@@ -1,16 +1,11 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import VerifiedPublisherBadge from './VerifiedPublisherBadge';
describe('VerifiedPublisherBadge', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -20,17 +15,16 @@ describe('VerifiedPublisherBadge', () => {
});
it('renders label', async () => {
- const { getByTestId, getByText, getByRole } = render();
- expect(getByText('Verified Publisher')).toBeInTheDocument();
+ render();
+ expect(screen.getByText('Verified Publisher')).toBeInTheDocument();
- const badge = getByTestId('elementWithTooltip');
+ const badge = screen.getByTestId('elementWithTooltip');
expect(badge).toBeInTheDocument();
- fireEvent.mouseEnter(badge);
+ userEvent.hover(badge);
- await waitFor(() => {
- expect(getByText('The publisher owns the repository')).toBeInTheDocument();
- expect(getByRole('tooltip')).toBeInTheDocument();
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+
+ expect(screen.getByText('The publisher owns the repository')).toBeInTheDocument();
});
it('does not render label', () => {
diff --git a/web/src/layout/common/userNotifications/index.test.tsx b/web/src/layout/common/userNotifications/index.test.tsx
index 159b3f98..ffac57ed 100644
--- a/web/src/layout/common/userNotifications/index.test.tsx
+++ b/web/src/layout/common/userNotifications/index.test.tsx
@@ -1,4 +1,4 @@
-import { render, waitFor } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
import React from 'react';
import { AppCtx } from '../../../context/AppCtx';
@@ -33,8 +33,6 @@ const mockCtx = {
describe('UserNotificationsController', () => {
beforeEach(() => {
- jest.useFakeTimers();
-
const mockMath = Object.create(global.Math);
mockMath.random = () => 0;
global.Math = mockMath;
@@ -55,8 +53,6 @@ describe('UserNotificationsController', () => {
});
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -75,19 +71,18 @@ describe('UserNotificationsController', () => {
});
it('renders component', async () => {
- const { getByRole } = render(
+ render(
);
- const component = getByRole('alert');
+ const component = screen.getByRole('alert');
expect(component).toBeInTheDocument();
expect(component).not.toHaveClass('show');
expect(component).toHaveClass('toast');
await waitFor(() => {
- expect(userNotificationsDispatcher.start).toHaveBeenCalledTimes(1);
expect(userNotificationsDispatcher.start).toHaveBeenCalledWith(
{
displayed: [],
@@ -97,6 +92,7 @@ describe('UserNotificationsController', () => {
'lg'
);
});
+ expect(userNotificationsDispatcher.start).toHaveBeenCalledTimes(1);
});
it('does not call userNotificationsDispatcher.start when user is undefined', () => {
diff --git a/web/src/layout/controlPanel/ActionBtn.test.tsx b/web/src/layout/controlPanel/ActionBtn.test.tsx
index 56eb55af..7f86ffe8 100644
--- a/web/src/layout/controlPanel/ActionBtn.test.tsx
+++ b/web/src/layout/controlPanel/ActionBtn.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import { AppCtx } from '../../context/AppCtx';
@@ -40,13 +41,7 @@ const mockCtx = {
};
describe('ActionBtn', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -62,7 +57,7 @@ describe('ActionBtn', () => {
});
it('renders enabled button', () => {
- const { getByTestId, getByText } = render(
+ render(
button content
@@ -70,18 +65,18 @@ describe('ActionBtn', () => {
);
- const btn = getByTestId(defaultProps.testId);
+ const btn = screen.getByTestId(defaultProps.testId);
expect(btn).toBeInTheDocument();
expect(btn).not.toHaveClass('disabled');
- fireEvent.click(btn);
+ userEvent.click(btn);
expect(onClickMock).toHaveBeenCalledTimes(1);
- expect(getByText('button content')).toBeInTheDocument();
+ expect(screen.getByText('button content')).toBeInTheDocument();
});
it('renders disabled button', () => {
- const { getByTestId, getByText } = render(
+ render(
{
);
- const btn = getByTestId(defaultProps.testId);
+ const btn = screen.getByTestId(defaultProps.testId);
expect(btn).toBeInTheDocument();
expect(btn).toHaveClass('disabled');
- fireEvent.click(btn);
+ userEvent.click(btn);
expect(onClickMock).toHaveBeenCalledTimes(0);
- expect(getByText('button content')).toBeInTheDocument();
+ expect(screen.getByText('button content')).toBeInTheDocument();
});
it('displays tooltip', async () => {
- const { getByTestId, getByRole, getByText } = render(
+ jest.useFakeTimers();
+
+ render(
{
);
- const btn = getByTestId(defaultProps.testId);
- fireEvent.mouseEnter(btn);
+ const btn = screen.getByTestId(defaultProps.testId);
+ userEvent.hover(btn);
- await waitFor(() => {
- expect(getByRole('tooltip')).toBeInTheDocument();
- expect(getByText('You are not allowed to perform this action')).toBeInTheDocument();
- });
+ expect(await screen.findByRole('tooltip')).toBeInTheDocument();
+ expect(screen.getByText('You are not allowed to perform this action')).toBeInTheDocument();
+
+ jest.useRealTimers();
});
});
diff --git a/web/src/layout/controlPanel/repositories/Card.test.tsx b/web/src/layout/controlPanel/repositories/Card.test.tsx
index 5ffe16e9..6b10d017 100644
--- a/web/src/layout/controlPanel/repositories/Card.test.tsx
+++ b/web/src/layout/controlPanel/repositories/Card.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import moment from 'moment';
import React from 'react';
@@ -58,13 +59,7 @@ const mockCtx = {
};
describe('Repository Card - packages section', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -79,19 +74,21 @@ describe('Repository Card - packages section', () => {
describe('Render', () => {
it('renders component', () => {
- const { getByText, getByTestId } = render(
+ render(
);
- expect(getByText(repoMock.displayName!)).toBeInTheDocument();
- expect(getByTestId('getBadgeBtn')).toBeInTheDocument();
- expect(getByTestId('updateRepoBtn')).toBeInTheDocument();
- expect(getByTestId('transferRepoBtn')).toBeInTheDocument();
- expect(getByTestId('deleteRepoDropdownBtn')).toBeInTheDocument();
- expect(getByText(repoMock.url!)).toBeInTheDocument();
- expect(getByText('Not processed yet, it will be processed automatically in ~ 3 minutes')).toBeInTheDocument();
+ expect(screen.getByText(repoMock.displayName!)).toBeInTheDocument();
+ expect(screen.getByTestId('getBadgeBtn')).toBeInTheDocument();
+ expect(screen.getByTestId('updateRepoBtn')).toBeInTheDocument();
+ expect(screen.getByTestId('transferRepoBtn')).toBeInTheDocument();
+ expect(screen.getByTestId('deleteRepoDropdownBtn')).toBeInTheDocument();
+ expect(screen.getByText(repoMock.url!)).toBeInTheDocument();
+ expect(
+ screen.getByText('Not processed yet, it will be processed automatically in ~ 3 minutes')
+ ).toBeInTheDocument();
});
it('renders component with last tracking and scanning info', () => {
@@ -105,15 +102,15 @@ describe('Repository Card - packages section', () => {
lastScanningErrors: 'errors scanning',
},
};
- const { getByText, getAllByText } = render(
+ render(
);
- expect(getAllByText('a few seconds ago')).toHaveLength(2);
- expect(getByText('Show tracking errors log')).toBeInTheDocument();
- expect(getByText('Show scanning errors log')).toBeInTheDocument();
+ expect(screen.getAllByText('a few seconds ago')).toHaveLength(2);
+ expect(screen.getByText('Show tracking errors log')).toBeInTheDocument();
+ expect(screen.getByText('Show scanning errors log')).toBeInTheDocument();
});
it('renders verified publisher badge', () => {
@@ -124,13 +121,13 @@ describe('Repository Card - packages section', () => {
verifiedPublisher: true,
},
};
- const { getAllByText } = render(
+ render(
);
- expect(getAllByText('Verified Publisher')).toHaveLength(2);
+ expect(screen.getAllByText('Verified Publisher')).toHaveLength(2);
});
it('renders Official badge', () => {
@@ -141,80 +138,72 @@ describe('Repository Card - packages section', () => {
official: true,
},
};
- const { getAllByText } = render(
+ render(
);
- expect(getAllByText('Official')).toHaveLength(2);
+ expect(screen.getAllByText('Official')).toHaveLength(2);
});
- it('renders deletion modal when delete button in dropdown is clicked', () => {
- const { getByTestId } = render(
+ it('renders deletion modal when delete button in dropdown is clicked', async () => {
+ render(
);
- const btn = getByTestId('deleteRepoDropdownBtn');
- fireEvent.click(btn);
+ const btn = screen.getByTestId('deleteRepoDropdownBtn');
+ userEvent.click(btn);
- waitFor(() => {
- expect(getByTestId('deleteRepoBtn')).toBeInTheDocument();
- });
+ expect(await screen.findByTestId('deleteRepoBtn')).toBeInTheDocument();
});
it('opens Get Badge Modal when Get badge button is clicked', async () => {
- const { getByTestId } = render(
+ render(
);
- const btn = getByTestId('getBadgeBtn');
+ const btn = screen.getByTestId('getBadgeBtn');
expect(btn).toBeInTheDocument();
- fireEvent.click(btn);
+ userEvent.click(btn);
- await waitFor(() => {
- expect(getByTestId('badgeModalContent')).toBeInTheDocument();
- });
+ expect(await screen.findByTestId('badgeModalContent')).toBeInTheDocument();
});
it('calls setModalStatus when Edit button is clicked', async () => {
- const { getByTestId } = render(
+ render(
);
- const btn = getByTestId('updateRepoBtn');
+ const btn = screen.getByTestId('updateRepoBtn');
expect(btn).toBeInTheDocument();
- fireEvent.click(btn);
+ userEvent.click(btn);
- await waitFor(() => {
- expect(setModalStatusMock).toHaveBeenCalledTimes(1);
- expect(setModalStatusMock).toHaveBeenCalledWith({
- open: true,
- repository: repoMock,
- });
+ await waitFor(() => expect(setModalStatusMock).toHaveBeenCalledTimes(1));
+ expect(setModalStatusMock).toHaveBeenCalledWith({
+ open: true,
+ repository: repoMock,
});
});
it('opens Transfer Repo when Transfer button is clicked', async () => {
- const { getByTestId, getByText } = render(
+ render(
);
- const btn = getByTestId('transferRepoBtn');
+ const btn = screen.getByTestId('transferRepoBtn');
expect(btn).toBeInTheDocument();
- fireEvent.click(btn);
+ userEvent.click(btn);
- await waitFor(() => {
- expect(getByText('Transfer repository')).toBeInTheDocument();
- });
+ expect(await screen.findByText('Transfer repository')).toBeInTheDocument();
});
it('opens logs modal when visibleModal is tracking and repo has errors', () => {
@@ -233,12 +222,12 @@ describe('Repository Card - packages section', () => {
);
- const { getByText, getByRole, rerender } = render(component);
- expect(getByText('Show tracking errors log')).toBeInTheDocument();
+ const { rerender } = render(component);
+ expect(screen.getByText('Show tracking errors log')).toBeInTheDocument();
rerender(component);
- expect(getByRole('dialog')).toBeInTheDocument();
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(mockHistoryReplace).toHaveBeenCalledTimes(1);
expect(mockHistoryReplace).toHaveBeenCalledWith({ search: '' });
});
@@ -260,12 +249,12 @@ describe('Repository Card - packages section', () => {
);
- const { getByText, getByRole, rerender } = render(component);
- expect(getByText('Show scanning errors log')).toBeInTheDocument();
+ const { rerender } = render(component);
+ expect(screen.getByText('Show scanning errors log')).toBeInTheDocument();
rerender(component);
- expect(getByRole('dialog')).toBeInTheDocument();
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(mockHistoryReplace).toHaveBeenCalledTimes(1);
expect(mockHistoryReplace).toHaveBeenCalledWith({ search: '' });
});
@@ -284,17 +273,17 @@ describe('Repository Card - packages section', () => {
);
- const { queryByText, getByText, getByRole, rerender } = render(component);
- expect(queryByText('Show tracking errors log')).toBeNull();
+ const { rerender } = render(component);
+ expect(screen.queryByText('Show tracking errors log')).toBeNull();
rerender(component);
- expect(getByRole('dialog')).toBeInTheDocument();
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(
- getByText(/It looks like the last tracking of this repository worked fine and no errors were produced./g)
+ screen.getByText(/It looks like the last tracking of this repository worked fine and no errors were produced./g)
).toBeInTheDocument();
expect(
- getByText(
+ screen.getByText(
/If you have arrived to this screen from an email listing some errors, please keep in mind those may have been already solved./g
)
).toBeInTheDocument();
@@ -318,19 +307,19 @@ describe('Repository Card - packages section', () => {
);
- const { queryByText, getByText, getByRole, rerender } = render(component);
- expect(queryByText('Show scanning errors log')).toBeNull();
+ const { rerender } = render(component);
+ expect(screen.queryByText('Show scanning errors log')).toBeNull();
rerender(component);
- expect(getByRole('dialog')).toBeInTheDocument();
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(
- getByText(
+ screen.getByText(
/It looks like the last security vulnerabilities scan of this repository worked fine and no errors were produced./g
)
).toBeInTheDocument();
expect(
- getByText(
+ screen.getByText(
/If you have arrived to this screen from an email listing some errors, please keep in mind those may have been already solved./g
)
).toBeInTheDocument();
diff --git a/web/src/layout/package/chartTemplates/ParamInfo.test.tsx b/web/src/layout/package/chartTemplates/ParamInfo.test.tsx
index b6871666..99e4aeb0 100644
--- a/web/src/layout/package/chartTemplates/ParamInfo.test.tsx
+++ b/web/src/layout/package/chartTemplates/ParamInfo.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { act, render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import ParamInfo from './ParamInfo';
@@ -10,13 +11,7 @@ const defaultProps = {
};
describe('ParamInfo', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -27,43 +22,67 @@ describe('ParamInfo', () => {
describe('Render', () => {
it('renders component', () => {
- const { getByText, getByTestId } = render();
+ render();
- expect(getByText('element')).toBeInTheDocument();
- expect(getByTestId('infoText')).toBeInTheDocument();
- expect(getByText('this is a sample')).toBeInTheDocument();
+ expect(screen.getByText('element')).toBeInTheDocument();
+ expect(screen.getByTestId('infoText')).toBeInTheDocument();
+ expect(screen.getByText('this is a sample')).toBeInTheDocument();
});
it('displays info dropdown to enter on info text and hides on leave', async () => {
- const { getByTestId } = render();
+ jest.useFakeTimers();
- expect(getByTestId('infoDropdown')).not.toHaveClass('visible');
+ render();
- fireEvent.mouseEnter(getByTestId('infoText'));
- await waitFor(() => {
- expect(getByTestId('infoDropdown')).toHaveClass('visible');
+ const infoDropdown = screen.getByTestId('infoDropdown');
+
+ expect(infoDropdown).not.toHaveClass('visible');
+
+ userEvent.hover(screen.getByTestId('infoText'));
+
+ act(() => {
+ jest.advanceTimersByTime(100);
});
- fireEvent.mouseLeave(getByTestId('infoText'));
- await waitFor(() => {
- expect(getByTestId('infoDropdown')).not.toHaveClass('visible');
+ expect(infoDropdown).toHaveClass('visible');
+
+ userEvent.unhover(screen.getByTestId('infoText'));
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
+
+ expect(infoDropdown).not.toHaveClass('visible');
+
+ jest.useRealTimers();
});
it('hides info dropdown to leave it', async () => {
- const { getByTestId } = render();
- fireEvent.mouseEnter(getByTestId('infoText'));
+ jest.useFakeTimers();
- fireEvent.mouseEnter(getByTestId('infoDropdown'));
- fireEvent.mouseLeave(getByTestId('infoText'));
- await waitFor(() => {
- expect(getByTestId('infoDropdown')).toHaveClass('visible');
+ render();
+
+ const infoDropdown = screen.getByTestId('infoDropdown');
+
+ userEvent.hover(screen.getByTestId('infoText'));
+ userEvent.hover(screen.getByTestId('infoDropdown'));
+ userEvent.unhover(screen.getByTestId('infoText'));
+
+ act(() => {
+ jest.advanceTimersByTime(100);
});
- fireEvent.mouseLeave(getByTestId('infoDropdown'));
- await waitFor(() => {
- expect(getByTestId('infoDropdown')).not.toHaveClass('visible');
+ expect(infoDropdown).toHaveClass('visible');
+
+ userEvent.unhover(screen.getByTestId('infoDropdown'));
+
+ act(() => {
+ jest.advanceTimersByTime(50);
});
+
+ expect(infoDropdown).not.toHaveClass('visible');
+
+ jest.useRealTimers();
});
});
});
diff --git a/web/src/layout/package/valuesSchema/SchemaValuesSearch.test.tsx b/web/src/layout/package/valuesSchema/SchemaValuesSearch.test.tsx
index c79a01a4..40ca035b 100644
--- a/web/src/layout/package/valuesSchema/SchemaValuesSearch.test.tsx
+++ b/web/src/layout/package/valuesSchema/SchemaValuesSearch.test.tsx
@@ -1,4 +1,5 @@
-import { fireEvent, render, waitFor } from '@testing-library/react';
+import { render, screen, waitFor } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
import React from 'react';
import SchemaValuesSearch from './SchemaValuesSearch';
@@ -11,13 +12,7 @@ const defaultProps = {
};
describe('SchemaValuesSearch', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
@@ -27,49 +22,40 @@ describe('SchemaValuesSearch', () => {
});
it('renders component', () => {
- const { getByTestId } = render();
- expect(getByTestId('typeaheadInput')).toBeInTheDocument();
+ render();
+ expect(screen.getByTestId('typeaheadInput')).toBeInTheDocument();
});
it('displays options', () => {
- const { getByTestId, getAllByTestId } = render();
+ render();
- const input = getByTestId('typeaheadInput');
- fireEvent.change(input, { target: { value: 'sub' } });
+ userEvent.type(screen.getByTestId('typeaheadInput'), 'sub');
- expect(getAllByTestId('typeaheadDropdownBtn')).toHaveLength(2);
+ expect(screen.getAllByTestId('typeaheadDropdownBtn')).toHaveLength(2);
});
it('calls onSearch with selected path', () => {
- const { getByTestId, getAllByTestId } = render();
+ render();
- const input = getByTestId('typeaheadInput');
- fireEvent.change(input, { target: { value: 'sub' } });
+ userEvent.type(screen.getByTestId('typeaheadInput'), 'sub');
- const opts = getAllByTestId('typeaheadDropdownBtn');
- fireEvent.click(opts[0]);
+ const opts = screen.getAllByTestId('typeaheadDropdownBtn');
+ userEvent.click(opts[0]);
expect(onSearchMock).toHaveBeenCalledTimes(1);
expect(onSearchMock).toHaveBeenCalledWith('path1.subpath1');
});
it('calls onSearch twice', async () => {
- const { getByTestId, getAllByTestId } = render(
-
- );
+ render();
- const input = getByTestId('typeaheadInput');
- fireEvent.change(input, { target: { value: 'sub' } });
+ userEvent.type(screen.getByTestId('typeaheadInput'), 'sub');
- const opts = getAllByTestId('typeaheadDropdownBtn');
- fireEvent.click(opts[0]);
+ const opts = screen.getAllByTestId('typeaheadDropdownBtn');
+ userEvent.click(opts[0]);
- await waitFor(() => {
- expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 10);
-
- expect(onSearchMock).toHaveBeenCalledTimes(2);
- expect(onSearchMock).toHaveBeenNthCalledWith(1, undefined);
- expect(onSearchMock).toHaveBeenNthCalledWith(2, 'path1.subpath1');
- });
+ await waitFor(() => expect(onSearchMock).toHaveBeenCalledTimes(2));
+ expect(onSearchMock).toHaveBeenNthCalledWith(1, undefined);
+ expect(onSearchMock).toHaveBeenNthCalledWith(2, 'path1.subpath1');
});
});
diff --git a/web/src/utils/alertDispatcher.test.tsx b/web/src/utils/alertDispatcher.test.tsx
index bc76df76..d701001f 100644
--- a/web/src/utils/alertDispatcher.test.tsx
+++ b/web/src/utils/alertDispatcher.test.tsx
@@ -11,17 +11,13 @@ const alertSample: Alert = {
};
describe('alertDispatcher', () => {
- beforeEach(() => {
- jest.useFakeTimers();
- });
-
afterEach(() => {
- jest.runOnlyPendingTimers();
- jest.useRealTimers();
jest.resetAllMocks();
});
it('receives alert after subscription', async () => {
+ jest.useFakeTimers();
+
alertDispatcher.subscribe({
updateAlertWrapper: (alert: Alert | null) => subscriptionMock(alert),
});
@@ -35,22 +31,45 @@ describe('alertDispatcher', () => {
alertDispatcher.postAlert(null);
expect(clearTimeout).toHaveBeenCalledTimes(1);
- await waitFor(() => {
- expect(subscriptionMock).toHaveBeenCalledTimes(2);
- expect(subscriptionMock).toHaveBeenCalledWith(null);
+ await waitFor(() => expect(subscriptionMock).toHaveBeenCalledWith(null));
+
+ expect(subscriptionMock).toHaveBeenCalledTimes(2);
+
+ jest.useRealTimers();
+ });
+
+ it('dismiss alert when default time has finished', async () => {
+ jest.useFakeTimers();
+
+ alertDispatcher.subscribe({
+ updateAlertWrapper: (alert: Alert | null) => subscriptionMock(alert),
});
+
+ alertDispatcher.postAlert(alertSample);
+
+ expect(subscriptionMock).toHaveBeenCalledTimes(1);
+ expect(subscriptionMock).toHaveBeenCalledWith(alertSample);
+ expect(setTimeout).toHaveBeenCalledTimes(1);
+ expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 5000);
+
+ await waitFor(() => expect(subscriptionMock).toHaveBeenCalledWith(null));
+ expect(subscriptionMock).toHaveBeenCalledTimes(2);
+
+ jest.useRealTimers();
});
it('dismiss alert with custom time', async () => {
+ jest.useFakeTimers();
+
alertDispatcher.subscribe({
updateAlertWrapper: (alert: Alert | null) => subscriptionMock(alert),
});
alertDispatcher.postAlert({ ...alertSample, dismissOn: 3000 });
- await waitFor(() => {
- expect(setTimeout).toHaveBeenCalledTimes(1);
- expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 3000);
- });
+ await waitFor(() => expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 3000));
+ expect(setTimeout).toHaveBeenCalledTimes(1);
+
+ jest.useRealTimers();
});
});
diff --git a/web/src/utils/userNotificationsDispatcher.test.tsx b/web/src/utils/userNotificationsDispatcher.test.tsx
index 16771f19..b62bd6da 100644
--- a/web/src/utils/userNotificationsDispatcher.test.tsx
+++ b/web/src/utils/userNotificationsDispatcher.test.tsx
@@ -42,6 +42,19 @@ describe('userNotificationsDispatcher', () => {
jest.resetAllMocks();
});
+ it('starts dispatcher', async () => {
+ userNotificationsDispatcher.start({
+ lastDisplayedTime: null,
+ enabled: true,
+ displayed: [],
+ });
+
+ await waitFor(() => {
+ expect(updateUserNotificationMock).toHaveBeenCalledTimes(2);
+ expect(updateUserNotificationMock).toHaveBeenLastCalledWith(null);
+ });
+ });
+
it('dismiss notification', async () => {
userNotificationsDispatcher.updateSettings({
lastDisplayedTime: null,
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 00000000..eb4c73c9
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,249 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/code-frame@^7.10.4":
+ version "7.12.13"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
+ integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
+ dependencies:
+ "@babel/highlight" "^7.12.13"
+
+"@babel/helper-validator-identifier@^7.12.11":
+ version "7.12.11"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
+ integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
+
+"@babel/highlight@^7.12.13":
+ version "7.13.10"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1"
+ integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.12.11"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
+"@babel/runtime-corejs3@^7.10.2":
+ version "7.13.17"
+ resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.13.17.tgz#9baf45f03d4d013f021760b992d6349a9d27deaf"
+ integrity sha512-RGXINY1YvduBlGrP+vHjJqd/nK7JVpfM4rmZLGMx77WoL3sMrhheA0qxii9VNn1VHnxJLEyxmvCB+Wqc+x/FMw==
+ dependencies:
+ core-js-pure "^3.0.0"
+ regenerator-runtime "^0.13.4"
+
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5":
+ version "7.13.17"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.17.tgz#8966d1fc9593bf848602f0662d6b4d0069e3a7ec"
+ integrity sha512-NCdgJEelPTSh+FEFylhnP1ylq848l1z9t9N0j1Lfbcw0+KXGjsTvUmkxy+voLLXB5SOKMbLLx4jxYliGrYQseA==
+ dependencies:
+ regenerator-runtime "^0.13.4"
+
+"@jest/types@^26.6.2":
+ version "26.6.2"
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e"
+ integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==
+ dependencies:
+ "@types/istanbul-lib-coverage" "^2.0.0"
+ "@types/istanbul-reports" "^3.0.0"
+ "@types/node" "*"
+ "@types/yargs" "^15.0.0"
+ chalk "^4.0.0"
+
+"@testing-library/dom@^7.30.3":
+ version "7.30.3"
+ resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-7.30.3.tgz#779ea9bbb92d63302461800a388a5a890ac22519"
+ integrity sha512-7JhIg2MW6WPwyikH2iL3o7z+FTVgSOd2jqCwTAHqK7Qal2gRRYiUQyURAxtbK9VXm/UTyG9bRihv8C5Tznr2zw==
+ dependencies:
+ "@babel/code-frame" "^7.10.4"
+ "@babel/runtime" "^7.12.5"
+ "@types/aria-query" "^4.2.0"
+ aria-query "^4.2.2"
+ chalk "^4.1.0"
+ dom-accessibility-api "^0.5.4"
+ lz-string "^1.4.4"
+ pretty-format "^26.6.2"
+
+"@testing-library/user-event@^13.1.5":
+ version "13.1.5"
+ resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.1.5.tgz#1ce11c37bf4df8f264fb7999ded7139e092a29bd"
+ integrity sha512-dD1FRHuWhfdcnb6H9/oaIIZHx9LQKGxbTtYV3i5Zru8I3GWWJoG2WtlAlXZ/56djO+6TvfsWPj5cXQvoTFQATQ==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+
+"@types/aria-query@^4.2.0":
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.1.tgz#78b5433344e2f92e8b306c06a5622c50c245bf6b"
+ integrity sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==
+
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
+ integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==
+
+"@types/istanbul-lib-report@*":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
+ integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
+ dependencies:
+ "@types/istanbul-lib-coverage" "*"
+
+"@types/istanbul-reports@^3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821"
+ integrity sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==
+ dependencies:
+ "@types/istanbul-lib-report" "*"
+
+"@types/node@*":
+ version "14.14.41"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615"
+ integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==
+
+"@types/yargs-parser@*":
+ version "20.2.0"
+ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9"
+ integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==
+
+"@types/yargs@^15.0.0":
+ version "15.0.13"
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc"
+ integrity sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==
+ dependencies:
+ "@types/yargs-parser" "*"
+
+ansi-regex@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
+ integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
+
+ansi-styles@^3.2.1:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
+ integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
+ dependencies:
+ color-convert "^1.9.0"
+
+ansi-styles@^4.0.0, ansi-styles@^4.1.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+aria-query@^4.2.2:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b"
+ integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==
+ dependencies:
+ "@babel/runtime" "^7.10.2"
+ "@babel/runtime-corejs3" "^7.10.2"
+
+chalk@^2.0.0:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
+ dependencies:
+ ansi-styles "^3.2.1"
+ escape-string-regexp "^1.0.5"
+ supports-color "^5.3.0"
+
+chalk@^4.0.0, chalk@^4.1.0:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
+ integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
+ dependencies:
+ ansi-styles "^4.1.0"
+ supports-color "^7.1.0"
+
+color-convert@^1.9.0:
+ version "1.9.3"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
+ integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
+ dependencies:
+ color-name "1.1.3"
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
+ integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+core-js-pure@^3.0.0:
+ version "3.10.2"
+ resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.10.2.tgz#065304f8547bf42008d4528dfff973c38bd6a332"
+ integrity sha512-uu18pVHQ21n4mzfuSlCXpucu5VKsck3j2m5fjrBOBqqdgWAxwdCgUuGWj6cDDPN1zLj/qtiqKvBMxWgDeeu49Q==
+
+dom-accessibility-api@^0.5.4:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz#b06d059cdd4a4ad9a79275f9d414a5c126241166"
+ integrity sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==
+
+escape-string-regexp@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+ integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+
+has-flag@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
+ integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
+
+has-flag@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
+ integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+
+js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+lz-string@^1.4.4:
+ version "1.4.4"
+ resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26"
+ integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=
+
+pretty-format@^26.6.2:
+ version "26.6.2"
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93"
+ integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==
+ dependencies:
+ "@jest/types" "^26.6.2"
+ ansi-regex "^5.0.0"
+ ansi-styles "^4.0.0"
+ react-is "^17.0.1"
+
+react-is@^17.0.1:
+ version "17.0.2"
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
+ integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+
+regenerator-runtime@^0.13.4:
+ version "0.13.7"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
+ integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==
+
+supports-color@^5.3.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
+ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
+ dependencies:
+ has-flag "^3.0.0"
+
+supports-color@^7.1.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"