Skip to content

Commit

Permalink
fix jest tests for plugins/security_solution
Browse files Browse the repository at this point in the history
  • Loading branch information
walterra committed Sep 3, 2024
1 parent 01a6998 commit 0e27a30
Show file tree
Hide file tree
Showing 17 changed files with 715 additions and 479 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,110 +5,107 @@
* 2.0.
*/

import type { AppContextTestRender } from '../../../../../common/mock/endpoint';
import type { trustedAppsAllHttpMocks } from '../../../../mocks';
import type { ArtifactListPageRenderingSetup } from '../../mocks';
import { getArtifactListPageRenderingSetup } from '../../mocks';
import { act, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getDeferred } from '../../../../mocks/utils';
import { waitFor } from '@testing-library/react';

describe('When displaying the Delete artifact modal in the Artifact List Page', () => {
let renderResult: ReturnType<AppContextTestRender['render']>;
let history: AppContextTestRender['history'];
let coreStart: AppContextTestRender['coreStart'];
let mockedApi: ReturnType<typeof trustedAppsAllHttpMocks>;
let getFirstCard: ArtifactListPageRenderingSetup['getFirstCard'];
let cancelButton: HTMLButtonElement;
let submitButton: HTMLButtonElement;
const setupTest = async () => {
const renderSetup = getArtifactListPageRenderingSetup();

const { history, coreStart, mockedApi, getFirstCard, user } = renderSetup;

history.push('somepage?show=create');

const renderResult = renderSetup.renderArtifactListPage();

await waitFor(() => {
expect(renderResult.getByTestId('testPage-list')).toBeInTheDocument();
});

const clickCardAction = async (action: 'edit' | 'delete') => {
await getFirstCard({ showActions: true });
switch (action) {
case 'delete':
await userEvent.click(renderResult.getByTestId('testPage-card-cardDeleteAction'));
await user.click(renderResult.getByTestId('testPage-card-cardDeleteAction'));
break;

case 'edit':
await userEvent.click(renderResult.getByTestId('testPage-card-cardEditAction'));
await user.click(renderResult.getByTestId('testPage-card-cardEditAction'));
break;
}
};

beforeEach(
async () => {
const renderSetup = getArtifactListPageRenderingSetup();
await clickCardAction('delete');

({ history, coreStart, mockedApi, getFirstCard } = renderSetup);

history.push('somepage?show=create');
// Wait for the dialog to be present
await waitFor(() => {
expect(renderResult.getByTestId('testPage-deleteModal')).toBeInTheDocument();
});

renderResult = renderSetup.renderArtifactListPage();
const cancelButton = renderResult.getByTestId(
'testPage-deleteModal-cancelButton'
) as HTMLButtonElement;

await act(async () => {
await waitFor(() => {
expect(renderResult.getByTestId('testPage-list')).toBeTruthy();
});
});
const submitButton = renderResult.getByTestId(
'testPage-deleteModal-submitButton'
) as HTMLButtonElement;

await clickCardAction('delete');
return { cancelButton, submitButton, user, coreStart, mockedApi, renderResult };
};

// Wait for the dialog to be present
await act(async () => {
await waitFor(() => {
expect(renderResult.getByTestId('testPage-deleteModal')).not.toBeNull();
});
});
describe('When displaying the Delete artifact modal in the Artifact List Page', () => {
beforeAll(() => {
jest.useFakeTimers();
});

cancelButton = renderResult.getByTestId(
'testPage-deleteModal-cancelButton'
) as HTMLButtonElement;
afterAll(() => {
jest.useRealTimers();
});

submitButton = renderResult.getByTestId(
'testPage-deleteModal-submitButton'
) as HTMLButtonElement;
},
// Timeout set to 10s
// In some cases, whose causes are unknown, a test will timeout and will point
// to this setup as the culprid. It rarely happens, but in order to avoid it,
// the timeout below is being set to 10s
10000
);
afterEach(() => {
jest.clearAllMocks();
});

it('should show Cancel and Delete buttons enabled', async () => {
const { cancelButton, submitButton } = await setupTest();

expect(cancelButton).toBeEnabled();
expect(submitButton).toBeEnabled();
});

it('should close modal if Cancel/Close buttons are clicked', async () => {
await userEvent.click(cancelButton);
const { cancelButton, user, renderResult } = await setupTest();

await user.click(cancelButton);

expect(renderResult.queryByTestId('testPage-deleteModal')).toBeNull();
expect(renderResult.queryByTestId('testPage-deleteModal')).not.toBeInTheDocument();
});

it('should prevent modal from being closed while deletion is in flight', async () => {
const deferred = getDeferred();
mockedApi.responseProvider.trustedAppDelete.mockDelay.mockReturnValue(deferred.promise);
const { submitButton, mockedApi, user, renderResult } = await setupTest();

mockedApi.responseProvider.trustedAppDelete.mockImplementation(
// @ts-expect-error This satisfies the test, but the type is incorrect
() => new Promise((resolve) => setTimeout(() => resolve({ name: 'the-name' }), 500))
);

await userEvent.click(submitButton);
await user.click(submitButton);

await waitFor(() => {
expect(cancelButton).toBeEnabled();
expect(submitButton).toBeEnabled();
});
expect(renderResult.queryByTestId('testPage-deleteModal')).toBeInTheDocument();

await act(async () => {
deferred.resolve(); // cleanup
jest.advanceTimersByTime(510);

await waitFor(() => {
expect(renderResult.queryByTestId('testPage-deleteModal')).not.toBeInTheDocument();
});
});

it('should show success toast if deleted successfully', async () => {
await userEvent.click(submitButton);
const { submitButton, coreStart, mockedApi, user } = await setupTest();

await user.click(submitButton);

await act(async () => {
await waitFor(() => {
expect(mockedApi.responseProvider.trustedAppDelete).toHaveBeenCalled();
});
await waitFor(() => {
expect(mockedApi.responseProvider.trustedAppDelete).toHaveBeenCalled();
});

expect(coreStart.notifications.toasts.addSuccess).toHaveBeenCalledWith(
Expand All @@ -119,16 +116,17 @@ describe('When displaying the Delete artifact modal in the Artifact List Page',
// FIXME:PT investigate test failure
// (I don't understand why its failing... All assertions are successful -- HELP!)
it.skip('should show error toast if deletion failed', async () => {
const { cancelButton, submitButton, mockedApi, user, coreStart, renderResult } =
await setupTest();

mockedApi.responseProvider.trustedAppDelete.mockImplementation(() => {
throw new Error('oh oh');
});

await userEvent.click(submitButton);
await user.click(submitButton);

await act(async () => {
await waitFor(() => {
expect(mockedApi.responseProvider.trustedAppDelete).toHaveBeenCalled();
});
await waitFor(() => {
expect(mockedApi.responseProvider.trustedAppDelete).toHaveBeenCalled();
});

expect(coreStart.notifications.toasts.addDanger).toHaveBeenCalledWith(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

import React from 'react';
// eslint-disable-next-line import/no-extraneous-dependencies
import { act, waitFor, within } from '@testing-library/react';
import { waitFor, within } from '@testing-library/react';
// eslint-disable-next-line import/no-extraneous-dependencies
import userEvent from '@testing-library/user-event';
import userEvent, { type UserEvent } from '@testing-library/user-event';
import type { ArtifactFormComponentProps } from './types';
import type { ArtifactListPageProps } from './artifact_list_page';
import { ArtifactListPage } from './artifact_list_page';
Expand Down Expand Up @@ -52,6 +52,7 @@ export const getFormComponentMock = (): {
};

export const getFirstCard = async (
user: UserEvent,
renderResult: ReturnType<AppContextTestRender['render']>,
{
showActions = false,
Expand All @@ -67,19 +68,20 @@ export const getFirstCard = async (
const card = cards[0];

if (showActions) {
await act(async () => {
await userEvent.click(within(card).getByTestId(`${testId}-card-header-actions-button`));
await user.click(within(card).getByTestId(`${testId}-card-header-actions-button`));

await waitFor(() => {
expect(renderResult.getByTestId(`${testId}-card-header-actions-contextMenuPanel`));
});
await waitFor(() => {
expect(
renderResult.getByTestId(`${testId}-card-header-actions-contextMenuPanel`)
).toBeInTheDocument();
});
}

return card;
};

export interface ArtifactListPageRenderingSetup {
user: UserEvent;
renderArtifactListPage: (
props?: Partial<ArtifactListPageProps>
) => ReturnType<AppContextTestRender['render']>;
Expand All @@ -95,6 +97,9 @@ export interface ArtifactListPageRenderingSetup {
* Returns the setup needed to render the ArtifactListPage for unit tests
*/
export const getArtifactListPageRenderingSetup = (): ArtifactListPageRenderingSetup => {
// Workaround for timeout via https://github.com/testing-library/user-event/issues/833#issuecomment-1171452841
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTime, pointerEventsCheck: 0 });

const mockedContext = createAppRootMockRenderer();

const { history, coreStart } = mockedContext;
Expand Down Expand Up @@ -124,10 +129,11 @@ export const getArtifactListPageRenderingSetup = (): ArtifactListPageRenderingSe
};

const getCard: ArtifactListPageRenderingSetup['getFirstCard'] = (props) => {
return getFirstCard(renderResult, props);
return getFirstCard(user, renderResult, props);
};

return {
user,
renderArtifactListPage,
history,
coreStart,
Expand Down
Loading

0 comments on commit 0e27a30

Please sign in to comment.