Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
e40pud committed Oct 17, 2023
1 parent 7bbdcad commit 0c5f351
Show file tree
Hide file tree
Showing 5 changed files with 275 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { render } from '@testing-library/react';
import type { UserProfileWithAvatar } from '@kbn/user-profile-components';

import {
ASSIGNEES_ADD_BUTTON_TEST_ID,
ASSIGNEES_COUNT_BADGE_TEST_ID,
ASSIGNEES_TITLE_TEST_ID,
ASSIGNEES_VALUE_TEST_ID,
ASSIGNEE_AVATAR_TEST_ID,
} from './test_ids';
import { Assignees } from './assignees';

import { useGetUserProfiles } from '../../../../detections/containers/detection_engine/alerts/use_get_user_profiles';
import { useSuggestUsers } from '../../../../detections/containers/detection_engine/alerts/use_suggest_users';
import type { SetAlertAssigneesFunc } from '../../../../common/components/toolbar/bulk_actions/use_set_alert_assignees';
import { useSetAlertAssignees } from '../../../../common/components/toolbar/bulk_actions/use_set_alert_assignees';
import { TestProviders } from '../../../../common/mock';

jest.mock('../../../../detections/containers/detection_engine/alerts/use_get_user_profiles');
jest.mock('../../../../detections/containers/detection_engine/alerts/use_suggest_users');
jest.mock('../../../../common/components/toolbar/bulk_actions/use_set_alert_assignees');

const mockUserProfiles: UserProfileWithAvatar[] = [
{ uid: 'user-id-1', enabled: true, user: { username: 'user1', full_name: 'User 1' }, data: {} },
{ uid: 'user-id-2', enabled: true, user: { username: 'user2', full_name: 'User 2' }, data: {} },
{ uid: 'user-id-3', enabled: true, user: { username: 'user3', full_name: 'User 3' }, data: {} },
];

const renderAssignees = (
eventId = 'event-1',
alertAssignees = ['user-id-1'],
onAssigneesUpdated = jest.fn()
) =>
render(
<TestProviders>
<Assignees
eventId={eventId}
alertAssignees={alertAssignees}
onAssigneesUpdated={onAssigneesUpdated}
/>
</TestProviders>
);

describe('<Assignees />', () => {
let setAlertAssigneesMock: jest.Mocked<SetAlertAssigneesFunc>;

beforeEach(() => {
jest.clearAllMocks();
(useGetUserProfiles as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
});
(useSuggestUsers as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
});

setAlertAssigneesMock = jest.fn().mockReturnValue(Promise.resolve());
(useSetAlertAssignees as jest.Mock).mockReturnValue(setAlertAssigneesMock);
});

it('should render component', () => {
const { getByTestId } = renderAssignees();

expect(getByTestId(ASSIGNEES_TITLE_TEST_ID)).toBeInTheDocument();
expect(getByTestId(ASSIGNEES_VALUE_TEST_ID)).toBeInTheDocument();
expect(getByTestId(ASSIGNEES_ADD_BUTTON_TEST_ID)).toBeInTheDocument();
});

it('should render assignees avatars', () => {
const assignees = ['user-id-1', 'user-id-2'];
const { getByTestId, queryByTestId } = renderAssignees('test-event', assignees);

expect(getByTestId(ASSIGNEE_AVATAR_TEST_ID('user1'))).toBeInTheDocument();
expect(getByTestId(ASSIGNEE_AVATAR_TEST_ID('user2'))).toBeInTheDocument();

expect(queryByTestId(ASSIGNEES_COUNT_BADGE_TEST_ID)).not.toBeInTheDocument();
});

it('should render badge with assignees count in case there are more than two users assigned to an alert', () => {
const assignees = ['user-id-1', 'user-id-2', 'user-id-3'];
const { getByTestId, queryByTestId } = renderAssignees('test-event', assignees);

const assigneesCountBadge = getByTestId(ASSIGNEES_COUNT_BADGE_TEST_ID);
expect(assigneesCountBadge).toBeInTheDocument();
expect(assigneesCountBadge).toHaveTextContent(`${assignees.length}`);

expect(queryByTestId(ASSIGNEE_AVATAR_TEST_ID('user1'))).not.toBeInTheDocument();
expect(queryByTestId(ASSIGNEE_AVATAR_TEST_ID('user2'))).not.toBeInTheDocument();
expect(queryByTestId(ASSIGNEE_AVATAR_TEST_ID('user3'))).not.toBeInTheDocument();
});

it('should call assignees update functionality with the right arguments', () => {
const assignees = ['user-id-1', 'user-id-2'];
const { getByTestId, getByText } = renderAssignees('test-event', assignees);

// Update assignees
getByTestId(ASSIGNEES_ADD_BUTTON_TEST_ID).click();
getByText('User 1').click();
getByText('User 3').click();

// Close assignees popover
getByTestId(ASSIGNEES_ADD_BUTTON_TEST_ID).click();

expect(setAlertAssigneesMock).toHaveBeenCalledWith(
{
assignees_to_add: ['user-id-3'],
assignees_to_remove: ['user-id-1'],
},
['test-event'],
expect.anything(),
expect.anything()
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ import {
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { UserAvatar } from '@kbn/user-profile-components';
import { noop } from 'lodash';
import { useGetUserProfiles } from '../../../../detections/containers/detection_engine/alerts/use_get_user_profiles';
import { useSetAlertAssignees } from '../../../../common/components/toolbar/bulk_actions/use_set_alert_assignees';
import { ASSIGNEES_TITLE_TEST_ID, ASSIGNEES_VALUE_TEST_ID } from './test_ids';
import {
ASSIGNEE_AVATAR_TEST_ID,
ASSIGNEES_TITLE_TEST_ID,
ASSIGNEES_VALUE_TEST_ID,
ASSIGNEES_COUNT_BADGE_TEST_ID,
} from './test_ids';
import { AssigneesPopover } from './assignees_popover';

export interface AssigneesProps {
Expand All @@ -44,7 +50,6 @@ export const Assignees: FC<AssigneesProps> = memo(
const onSuccess = useCallback(() => {
if (onAssigneesUpdated) onAssigneesUpdated();
}, [onAssigneesUpdated]);
const setIsLoading = useCallback(() => {}, []);

const handleOnAlertAssigneesSubmit = useCallback(async () => {
if (setAlertAssignees && selectedAssignees) {
Expand All @@ -59,9 +64,9 @@ export const Assignees: FC<AssigneesProps> = memo(
assignees_to_remove: assigneesToRemoveArray,
};

await setAlertAssignees(assigneesToUpdate, [eventId], onSuccess, setIsLoading);
await setAlertAssignees(assigneesToUpdate, [eventId], onSuccess, noop);
}
}, [alertAssignees, eventId, onSuccess, selectedAssignees, setAlertAssignees, setIsLoading]);
}, [alertAssignees, eventId, onSuccess, selectedAssignees, setAlertAssignees]);

const togglePopover = useCallback(() => {
setIsPopoverOpen((value) => !value);
Expand Down Expand Up @@ -111,11 +116,19 @@ export const Assignees: FC<AssigneesProps> = memo(
))}
repositionOnScroll={true}
>
<EuiNotificationBadge>{assignees.length}</EuiNotificationBadge>
<EuiNotificationBadge data-test-subj={ASSIGNEES_COUNT_BADGE_TEST_ID}>
{assignees.length}
</EuiNotificationBadge>
</EuiToolTip>
) : (
assignees.map((user) => (
<UserAvatar user={user.user} avatar={user.data.avatar} size={'s'} />
<UserAvatar
key={user.uid}
data-test-subj={ASSIGNEE_AVATAR_TEST_ID(user.user.username)}
user={user.user}
avatar={user.data.avatar}
size={'s'}
/>
))
)}
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { render } from '@testing-library/react';
import type { UserProfileWithAvatar } from '@kbn/user-profile-components';

import { ASSIGNEES_ADD_BUTTON_TEST_ID } from './test_ids';
import { AssigneesPopover } from './assignees_popover';

import { useSuggestUsers } from '../../../../detections/containers/detection_engine/alerts/use_suggest_users';
import { TestProviders } from '../../../../common/mock';

jest.mock('../../../../detections/containers/detection_engine/alerts/use_suggest_users');

const mockUserProfiles: UserProfileWithAvatar[] = [
{
uid: 'user-id-1',
enabled: true,
user: { username: 'user1', full_name: 'User 1', email: '[email protected]' },
data: {},
},
{
uid: 'user-id-2',
enabled: true,
user: { username: 'user2', full_name: 'User 2', email: '[email protected]' },
data: {},
},
{
uid: 'user-id-3',
enabled: true,
user: { username: 'user3', full_name: 'User 3', email: '[email protected]' },
data: {},
},
];

const renderAssigneesPopover = (
alertAssignees: string[],
isPopoverOpen: boolean,
onUsersChange = jest.fn(),
togglePopover = jest.fn(),
onClosePopover = jest.fn()
) =>
render(
<TestProviders>
<AssigneesPopover
existingAssigneesIds={alertAssignees}
isPopoverOpen={isPopoverOpen}
onUsersChange={onUsersChange}
onClosePopover={onClosePopover}
togglePopover={togglePopover}
/>
</TestProviders>
);

describe('<AssigneesPopover />', () => {
beforeEach(() => {
jest.clearAllMocks();
(useSuggestUsers as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
});
});

it('should render closed popover component', () => {
const { getByTestId, queryByTestId } = renderAssigneesPopover([], false);

expect(getByTestId(ASSIGNEES_ADD_BUTTON_TEST_ID)).toBeInTheDocument();
expect(queryByTestId('euiSelectableList')).not.toBeInTheDocument();
});

it('should render opened popover component', () => {
const { getByTestId } = renderAssigneesPopover([], true);

expect(getByTestId(ASSIGNEES_ADD_BUTTON_TEST_ID)).toBeInTheDocument();
expect(getByTestId('euiSelectableList')).toBeInTheDocument();
});

it('should render assignees', () => {
const { getByTestId } = renderAssigneesPopover([], true);

const assigneesList = getByTestId('euiSelectableList');
expect(assigneesList).toHaveTextContent('User 1');
expect(assigneesList).toHaveTextContent('[email protected]');
expect(assigneesList).toHaveTextContent('User 2');
expect(assigneesList).toHaveTextContent('[email protected]');
expect(assigneesList).toHaveTextContent('User 3');
expect(assigneesList).toHaveTextContent('[email protected]');
});

it('should call onUsersChange on clsing the popover', () => {
const onUsersChangeMock = jest.fn();
const { getByText } = renderAssigneesPopover([], true, onUsersChangeMock);

getByText('User 1').click();
getByText('User 2').click();
getByText('User 3').click();
getByText('User 3').click();
getByText('User 2').click();
getByText('User 1').click();

expect(onUsersChangeMock).toHaveBeenCalledTimes(6);
expect(onUsersChangeMock.mock.calls).toEqual([
[['user-id-1']],
[['user-id-2', 'user-id-1']],
[['user-id-3', 'user-id-2', 'user-id-1']],
[['user-id-2', 'user-id-1']],
[['user-id-1']],
[[]],
]);
});

it('should call togglePopover on add button click', () => {
const togglePopoverMock = jest.fn();
const { getByTestId } = renderAssigneesPopover([], false, jest.fn(), togglePopoverMock);

getByTestId(ASSIGNEES_ADD_BUTTON_TEST_ID).click();

expect(togglePopoverMock).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { UserProfilesPopover } from '@kbn/user-profile-components';

import { EuiButtonIcon, EuiToolTip } from '@elastic/eui';
import { useSuggestUsers } from '../../../../detections/containers/detection_engine/alerts/use_suggest_users';
import { ASSIGNEES_ADD_BUTTON_TEST_ID } from './test_ids';

const PopoverButton: React.FC<{ togglePopover: () => void; isDisabled: boolean }> = ({
togglePopover,
Expand All @@ -28,7 +29,8 @@ const PopoverButton: React.FC<{ togglePopover: () => void; isDisabled: boolean }
)}
>
<EuiButtonIcon
data-test-subj="assignees-edit-button"
aria-label="Update assignees"
data-test-subj={ASSIGNEES_ADD_BUTTON_TEST_ID}
iconType={'plusInCircle'}
onClick={togglePopover}
disabled={isDisabled}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const SHARE_BUTTON_TEST_ID = `${FLYOUT_HEADER_TEST_ID}ShareButton` as con
export const CHAT_BUTTON_TEST_ID = 'newChatById' as const;
export const ASSIGNEES_TITLE_TEST_ID = `${FLYOUT_HEADER_TEST_ID}AssigneesTitle`;
export const ASSIGNEES_VALUE_TEST_ID = `${FLYOUT_HEADER_TEST_ID}AssigneesValue`;
export const ASSIGNEES_ADD_BUTTON_TEST_ID = `${FLYOUT_HEADER_TEST_ID}AssigneesAddButton`;

/* About section */

Expand Down Expand Up @@ -149,3 +150,7 @@ export const RESPONSE_SECTION_HEADER_TEST_ID = RESPONSE_SECTION_TEST_ID + HEADER
export const RESPONSE_SECTION_CONTENT_TEST_ID = RESPONSE_SECTION_TEST_ID + CONTENT_TEST_ID;
export const RESPONSE_BUTTON_TEST_ID = `${RESPONSE_TEST_ID}Button` as const;
export const RESPONSE_EMPTY_TEST_ID = `${RESPONSE_TEST_ID}Empty` as const;

/* Alert Assignees */
export const ASSIGNEE_AVATAR_TEST_ID = (userName: string) => `${PREFIX}AssigneeAvatar-${userName}`;
export const ASSIGNEES_COUNT_BADGE_TEST_ID = `${PREFIX}AssigneesCountBadge`;

0 comments on commit 0c5f351

Please sign in to comment.