diff --git a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx
index 63be7009f8c15..07cf815555f61 100644
--- a/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx
+++ b/x-pack/plugins/cases/public/components/case_view/components/case_view_activity.tsx
@@ -58,7 +58,8 @@ export const CaseViewActivity = ({
[caseData.assignees]
);
- const uidsToRetrieve = uniq([...(userActionsData?.profileUids ?? []), ...assignees]);
+ const userActionProfileUids = Array.from(userActionsData?.profileUids.values() ?? []);
+ const uidsToRetrieve = uniq([...userActionProfileUids, ...assignees]);
const { data: userProfiles, isLoading: isLoadingUserProfiles } = useBulkGetUserProfiles({
uids: uidsToRetrieve,
diff --git a/x-pack/plugins/cases/public/components/user_actions/assignees.test.tsx b/x-pack/plugins/cases/public/components/user_actions/assignees.test.tsx
index f27721fa5c04a..57cde43c9fee6 100644
--- a/x-pack/plugins/cases/public/components/user_actions/assignees.test.tsx
+++ b/x-pack/plugins/cases/public/components/user_actions/assignees.test.tsx
@@ -12,158 +12,219 @@ import { render, screen } from '@testing-library/react';
import { Actions } from '../../../common/api';
import { elasticUser, getUserAction } from '../../containers/mock';
import { TestProviders } from '../../common/mock';
-import { createAssigneesUserActionBuilder } from './assignees';
+import { createAssigneesUserActionBuilder, shouldAddAnd, shouldAddComma } from './assignees';
import { getMockBuilderArgs } from './mock';
jest.mock('../../common/lib/kibana');
jest.mock('../../common/navigation/hooks');
describe('createAssigneesUserActionBuilder', () => {
- const builderArgs = getMockBuilderArgs();
-
- beforeEach(() => {
- jest.clearAllMocks();
- });
-
- it('renders assigned users', () => {
- const userAction = getUserAction('assignees', Actions.add, {
- createdBy: {
- // damaged_raccoon uid
- profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
- },
+ describe('shouldAddComma', () => {
+ it('returns false if there are only 2 items', () => {
+ expect(shouldAddComma(0, 2)).toBeFalsy();
});
- const builder = createAssigneesUserActionBuilder({
- ...builderArgs,
- userAction,
- });
-
- const createdUserAction = builder.build();
- render(
-
-
-
- );
-
- expect(screen.getByText('assigned')).toBeInTheDocument();
- expect(screen.getByText('themselves,')).toBeInTheDocument();
- expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
- expect(screen.getByTestId('ua-assignee-physical_dinosaur')).toContainElement(
- screen.getByText('and')
- );
- });
-
- it('renders unassigned users', () => {
- const userAction = getUserAction('assignees', Actions.delete, {
- createdBy: {
- // damaged_raccoon uid
- profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
- },
- });
- const builder = createAssigneesUserActionBuilder({
- ...builderArgs,
- userAction,
+ it('returns false it is the last items', () => {
+ expect(shouldAddComma(2, 3)).toBeFalsy();
});
-
- const createdUserAction = builder.build();
- render(
-
-
-
- );
-
- expect(screen.getByText('unassigned')).toBeInTheDocument();
- expect(screen.getByText('themselves,')).toBeInTheDocument();
- expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
-
- expect(screen.getByTestId('ua-assignee-physical_dinosaur')).toContainElement(
- screen.getByText('and')
- );
});
- it('renders a single assigned user', () => {
- const userAction = getUserAction('assignees', Actions.add, {
- payload: {
- assignees: [
- // only render the physical dinosaur
- { uid: 'u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0' },
- ],
- },
+ describe('shouldAddAnd', () => {
+ it('returns false if there is only 1 item', () => {
+ expect(shouldAddAnd(0, 1)).toBeFalsy();
});
- const builder = createAssigneesUserActionBuilder({
- ...builderArgs,
- userAction,
- });
-
- const createdUserAction = builder.build();
- render(
-
-
-
- );
- expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
- expect(screen.queryByText('themselves,')).not.toBeInTheDocument();
- expect(screen.queryByText('and')).not.toBeInTheDocument();
+ it('returns false it is not the last items', () => {
+ expect(shouldAddAnd(1, 3)).toBeFalsy();
+ });
});
- it('renders a single assigned user that is themselves using matching profile uids', () => {
- const userAction = getUserAction('assignees', Actions.add, {
- createdBy: {
- ...elasticUser,
- profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
- },
- payload: {
- assignees: [
- // only render the damaged raccoon which is the current user
- { uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0' },
- ],
- },
- });
- const builder = createAssigneesUserActionBuilder({
- ...builderArgs,
- userAction,
+ describe('component', () => {
+ const builderArgs = getMockBuilderArgs();
+
+ beforeEach(() => {
+ jest.clearAllMocks();
});
- const createdUserAction = builder.build();
- render(
-
-
-
- );
+ it('renders assigned users', () => {
+ const userAction = getUserAction('assignees', Actions.add, {
+ createdBy: {
+ // damaged_raccoon uid
+ profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
+ },
+ });
+ const builder = createAssigneesUserActionBuilder({
+ ...builderArgs,
+ userAction,
+ });
+
+ const createdUserAction = builder.build();
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('assigned')).toBeInTheDocument();
+ expect(screen.getByText('themselves')).toBeInTheDocument();
+ expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
+
+ expect(screen.getByTestId('ua-assignee-physical_dinosaur')).toContainElement(
+ screen.getByText('and')
+ );
+ });
- expect(screen.getByText('themselves')).toBeInTheDocument();
- expect(screen.queryByText('Physical Dinosaur')).not.toBeInTheDocument();
- expect(screen.queryByText('and')).not.toBeInTheDocument();
- });
+ it('renders assigned users with a comma', () => {
+ const userAction = getUserAction('assignees', Actions.add, {
+ createdBy: {
+ // damaged_raccoon uid
+ profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
+ },
+ payload: {
+ assignees: [
+ // These values map to uids in x-pack/plugins/cases/public/containers/user_profiles/api.mock.ts
+ { uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0' },
+ { uid: 'u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0' },
+ { uid: 'u_9xDEQqUqoYCnFnPPLq5mIRHKL8gBTo_NiKgOnd5gGk0_0' },
+ ],
+ },
+ });
+ const builder = createAssigneesUserActionBuilder({
+ ...builderArgs,
+ userAction,
+ });
+
+ const createdUserAction = builder.build();
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('assigned')).toBeInTheDocument();
+ expect(screen.getByText('themselves,')).toBeInTheDocument();
+ expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
+
+ expect(screen.getByTestId('ua-assignee-physical_dinosaur')).toContainElement(
+ screen.getByText(',')
+ );
+
+ expect(screen.getByText('Wet Dingo')).toBeInTheDocument();
+ expect(screen.getByTestId('ua-assignee-wet_dingo')).toContainElement(screen.getByText('and'));
+ });
- it('renders a single assigned user that is themselves using matching usernames', () => {
- const userAction = getUserAction('assignees', Actions.add, {
- createdBy: {
- ...elasticUser,
- username: 'damaged_raccoon',
- },
- payload: {
- assignees: [
- // only render the damaged raccoon which is the current user
- { uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0' },
- ],
- },
+ it('renders unassigned users', () => {
+ const userAction = getUserAction('assignees', Actions.delete, {
+ createdBy: {
+ // damaged_raccoon uid
+ profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
+ },
+ });
+ const builder = createAssigneesUserActionBuilder({
+ ...builderArgs,
+ userAction,
+ });
+
+ const createdUserAction = builder.build();
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('unassigned')).toBeInTheDocument();
+ expect(screen.getByText('themselves')).toBeInTheDocument();
+ expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
+
+ expect(screen.getByTestId('ua-assignee-physical_dinosaur')).toContainElement(
+ screen.getByText('and')
+ );
});
- const builder = createAssigneesUserActionBuilder({
- ...builderArgs,
- userAction,
+
+ it('renders a single assigned user', () => {
+ const userAction = getUserAction('assignees', Actions.add, {
+ payload: {
+ assignees: [
+ // only render the physical dinosaur
+ { uid: 'u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0' },
+ ],
+ },
+ });
+ const builder = createAssigneesUserActionBuilder({
+ ...builderArgs,
+ userAction,
+ });
+
+ const createdUserAction = builder.build();
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('Physical Dinosaur')).toBeInTheDocument();
+ expect(screen.queryByText('themselves,')).not.toBeInTheDocument();
+ expect(screen.queryByText('and')).not.toBeInTheDocument();
});
- const createdUserAction = builder.build();
- render(
-
-
-
- );
+ it('renders a single assigned user that is themselves using matching profile uids', () => {
+ const userAction = getUserAction('assignees', Actions.add, {
+ createdBy: {
+ ...elasticUser,
+ profileUid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0',
+ },
+ payload: {
+ assignees: [
+ // only render the damaged raccoon which is the current user
+ { uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0' },
+ ],
+ },
+ });
+ const builder = createAssigneesUserActionBuilder({
+ ...builderArgs,
+ userAction,
+ });
+
+ const createdUserAction = builder.build();
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('themselves')).toBeInTheDocument();
+ expect(screen.queryByText('Physical Dinosaur')).not.toBeInTheDocument();
+ expect(screen.queryByText('and')).not.toBeInTheDocument();
+ });
- expect(screen.getByText('themselves')).toBeInTheDocument();
- expect(screen.queryByText('Physical Dinosaur')).not.toBeInTheDocument();
- expect(screen.queryByText('and')).not.toBeInTheDocument();
+ it('renders a single assigned user that is themselves using matching usernames', () => {
+ const userAction = getUserAction('assignees', Actions.add, {
+ createdBy: {
+ ...elasticUser,
+ username: 'damaged_raccoon',
+ },
+ payload: {
+ assignees: [
+ // only render the damaged raccoon which is the current user
+ { uid: 'u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0' },
+ ],
+ },
+ });
+ const builder = createAssigneesUserActionBuilder({
+ ...builderArgs,
+ userAction,
+ });
+
+ const createdUserAction = builder.build();
+ render(
+
+
+
+ );
+
+ expect(screen.getByText('themselves')).toBeInTheDocument();
+ expect(screen.queryByText('Physical Dinosaur')).not.toBeInTheDocument();
+ expect(screen.queryByText('and')).not.toBeInTheDocument();
+ });
});
});
diff --git a/x-pack/plugins/cases/public/components/user_actions/assignees.tsx b/x-pack/plugins/cases/public/components/user_actions/assignees.tsx
index 0e16184634a4a..e0a499df05633 100644
--- a/x-pack/plugins/cases/public/components/user_actions/assignees.tsx
+++ b/x-pack/plugins/cases/public/components/user_actions/assignees.tsx
@@ -42,11 +42,11 @@ const FormatListItem: React.FC<{
};
FormatListItem.displayName = 'FormatListItem';
-const shouldAddComma = (index: number, arrayLength: number) => {
- return arrayLength > 0 && index !== arrayLength - 1;
+export const shouldAddComma = (index: number, arrayLength: number) => {
+ return arrayLength > 2 && index !== arrayLength - 1;
};
-const shouldAddAnd = (index: number, arrayLength: number) => {
+export const shouldAddAnd = (index: number, arrayLength: number) => {
return arrayLength > 1 && index === arrayLength - 1;
};
diff --git a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx
index cb39b4e7247d5..c97e1a8668b1d 100644
--- a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx
+++ b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.test.tsx
@@ -104,10 +104,38 @@ describe('useGetCaseUserActions', () => {
await waitFor(() => {
expect(result.current.data?.profileUids).toMatchInlineSnapshot(`
- Array [
+ Set {
"u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0",
"u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0",
- ]
+ }
+ `);
+ });
+ });
+ });
+
+ it('ignores duplicate uids', async () => {
+ jest
+ .spyOn(api, 'getCaseUserActions')
+ .mockReturnValue(
+ Promise.resolve([
+ ...caseUserActions,
+ getUserAction('assignees', Actions.add),
+ getUserAction('assignees', Actions.add),
+ ])
+ );
+
+ await act(async () => {
+ const { result } = renderHook(
+ () => useGetCaseUserActions(basicCase.id, basicCase.connector.id),
+ { wrapper }
+ );
+
+ await waitFor(() => {
+ expect(result.current.data?.profileUids).toMatchInlineSnapshot(`
+ Set {
+ "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0",
+ "u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0",
+ }
`);
});
});
@@ -128,10 +156,10 @@ describe('useGetCaseUserActions', () => {
await waitFor(() => {
expect(result.current.data?.profileUids).toMatchInlineSnapshot(`
- Array [
+ Set {
"u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0",
"u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0",
- ]
+ }
`);
});
});
diff --git a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx
index 04448612ce481..1d36521d0b6f4 100644
--- a/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx
+++ b/x-pack/plugins/cases/public/containers/use_get_case_user_actions.tsx
@@ -209,14 +209,16 @@ export const getPushedInfo = (
};
export const getProfileUids = (userActions: CaseUserActions[]) => {
- const uids = userActions.reduce((acc, userAction) => {
+ const uids = userActions.reduce>((acc, userAction) => {
if (userAction.type === ActionTypes.assignees) {
const uidsFromPayload = userAction.payload.assignees.map((assignee) => assignee.uid);
- acc.push(...uidsFromPayload);
+ for (const uid of uidsFromPayload) {
+ acc.add(uid);
+ }
}
return acc;
- }, []);
+ }, new Set());
return uids;
};