[Cases] Fix case view reporter tests. (#162567)

Fixes #152206

## Summary

I removed the reporter tests from
`x-pack/plugins/cases/public/components/case_view/components/case_view_activity.test.tsx`

There were a few things being tested:

| Old Test  | Where is it covered |
| ------------- | ------------- |
| does the case view render `'case-view-user-list-reporter'` | [a
functional test already covers
this](https://github.com/elastic/kibana/blob/main/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts#L47)
|
| Is a reporter name displayed correctly | covered in the UserList
component tests |
| a reporter without uid is rendered correctly | moved this logic to
`parseCaseUsers` and tested it there in this PR |
| fallbacks correctly to the caseData.createdBy user correctly | moved
this logic to `parseCaseUsers` and tested it there in this PR |
This commit is contained in:
Antonio 2023-07-27 09:19:49 +02:00 committed by GitHub
parent 0ab24e566c
commit 88aa58c166
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 305 additions and 91 deletions

View file

@ -496,54 +496,6 @@ describe('Case View Page activity tab', () => {
});
});
// FLAKY: https://github.com/elastic/kibana/issues/152206
describe.skip('Reporter', () => {
it('should render the reporter correctly', async () => {
appMockRender = createAppMockRenderer();
appMockRender.render(<CaseViewActivity {...caseProps} />);
const reporterSection = within(await screen.findByTestId('case-view-user-list-reporter'));
expect(await reporterSection.findByText('Reporter 1')).toBeInTheDocument();
expect(await reporterSection.findByText('R1')).toBeInTheDocument();
});
it('should render a reporter without uid correctly', async () => {
useGetCaseUsersMock.mockReturnValue({
isLoading: false,
data: {
...caseUsers,
reporter: {
user: {
email: 'reporter_no_uid@elastic.co',
full_name: 'Reporter No UID',
username: 'reporter_no_uid',
},
},
},
});
appMockRender = createAppMockRenderer();
appMockRender.render(<CaseViewActivity {...caseProps} />);
const reporterSection = within(await screen.findByTestId('case-view-user-list-reporter'));
expect(await reporterSection.findByText('Reporter No UID')).toBeInTheDocument();
});
it('fallbacks to the caseData reporter correctly', async () => {
useGetCaseUsersMock.mockReturnValue({
isLoading: false,
data: null,
});
appMockRender = createAppMockRenderer();
appMockRender.render(<CaseViewActivity {...caseProps} />);
const reporterSection = within(await screen.findByTestId('case-view-user-list-reporter'));
expect(await reporterSection.findByText('Leslie Knope')).toBeInTheDocument();
});
});
describe('Assignees', () => {
it('should render assignees in the participants section', async () => {
appMockRender = createAppMockRenderer({ license: platinumLicense });

View file

@ -10,14 +10,13 @@
import { EuiFlexGroup, EuiFlexItem, EuiLoadingSpinner, EuiSpacer } from '@elastic/eui';
import React, { useCallback, useMemo, useState } from 'react';
import { isEqual } from 'lodash';
import type { UserProfileWithAvatar } from '@kbn/user-profile-components';
import { useGetCaseUsers } from '../../../containers/use_get_case_users';
import { useGetCaseConnectors } from '../../../containers/use_get_case_connectors';
import { useCasesFeatures } from '../../../common/use_cases_features';
import { useGetCurrentUserProfile } from '../../../containers/user_profiles/use_get_current_user_profile';
import { useGetSupportedActionConnectors } from '../../../containers/configure/use_get_supported_action_connectors';
import type { CaseSeverity, CaseStatuses } from '../../../../common/types/domain';
import type { CaseUsers, UseFetchAlertData } from '../../../../common/ui/types';
import type { UseFetchAlertData } from '../../../../common/ui/types';
import type { CaseUI } from '../../../../common';
import { EditConnector } from '../../edit_connector';
import type { CasesNavigation } from '../../links';
@ -33,46 +32,12 @@ import { useGetCaseUserActionsStats } from '../../../containers/use_get_case_use
import { AssignUsers } from './assign_users';
import { UserActionsActivityBar } from '../../user_actions_activity_bar';
import type { Assignee } from '../../user_profiles/types';
import { convertToCaseUserWithProfileInfo } from '../../user_profiles/user_converter';
import type { UserActivityParams } from '../../user_actions_activity_bar/types';
import { CASE_VIEW_PAGE_TABS } from '../../../../common/types';
import { CaseViewTabs } from '../case_view_tabs';
import { Description } from '../../description';
import { EditCategory } from './edit_category';
const buildUserProfilesMap = (users?: CaseUsers): Map<string, UserProfileWithAvatar> => {
const userProfiles = new Map();
if (!users) {
return userProfiles;
}
for (const user of [
...users.assignees,
...users.participants,
users.reporter,
...users.unassignedUsers,
]) {
/**
* If the user has a valid profile UID and a valid username
* then the backend successfully fetched the user profile
* information from the security plugin. Checking only for the
* profile UID is not enough as a user can use our API to add
* an assignee with a non existing UID.
*/
if (user.uid != null && user.user.username != null) {
userProfiles.set(user.uid, {
uid: user.uid,
user: user.user,
data: {
avatar: user.avatar,
},
});
}
}
return userProfiles;
};
import { parseCaseUsers } from '../../utils';
export const CaseViewActivity = ({
ruleDetailsNavigation,
@ -107,7 +72,10 @@ export const CaseViewActivity = ({
const { data: caseUsers, isLoading: isLoadingCaseUsers } = useGetCaseUsers(caseData.id);
const userProfiles = buildUserProfilesMap(caseUsers);
const { userProfiles, reporterAsArray } = parseCaseUsers({
caseUsers,
createdBy: caseData.createdBy,
});
const assignees = useMemo(
() => caseData.assignees.map((assignee) => assignee.uid),
@ -203,11 +171,6 @@ export const CaseViewActivity = ({
const showConnectorSidebar =
pushToServiceAuthorized && caseConnectors && supportedActionConnectors;
const reporterAsArray =
caseUsers?.reporter != null
? [caseUsers.reporter]
: [convertToCaseUserWithProfileInfo(caseData.createdBy)];
const isLoadingDescription = isLoading && loadingKey === 'description';
return (

View file

@ -7,6 +7,7 @@
import { actionTypeRegistryMock } from '@kbn/triggers-actions-ui-plugin/public/application/action_type_registry.mock';
import { triggersActionsUiMock } from '@kbn/triggers-actions-ui-plugin/public/mocks';
import { elasticUser, getCaseUsersMockResponse } from '../containers/mock';
import {
connectorDeprecationValidator,
convertEmptyValuesToNull,
@ -18,6 +19,7 @@ import {
removeItemFromSessionStorage,
parseURL,
stringifyToURL,
parseCaseUsers,
} from './utils';
describe('Utils', () => {
@ -255,4 +257,252 @@ describe('Utils', () => {
expect(stringifyToURL({})).toBe('');
});
});
describe('parseCaseUsers', () => {
it('should define userProfiles and reporters correctly', () => {
const caseUsers = getCaseUsersMockResponse();
const { userProfiles, reporterAsArray } = parseCaseUsers({
caseUsers,
createdBy: elasticUser,
});
expect(userProfiles).toMatchInlineSnapshot(`
Map {
"u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
"user": Object {
"email": null,
"full_name": null,
"username": "elastic",
},
},
"u_3OgKOf-ogtr8kJ5B0fnRcqzXs2aQQkZLtzKEEFnKaYg_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_3OgKOf-ogtr8kJ5B0fnRcqzXs2aQQkZLtzKEEFnKaYg_0",
"user": Object {
"email": "fuzzy_marten@profiles.elastic.co",
"full_name": "Fuzzy Marten",
"username": "fuzzy_marten",
},
},
"u_BXf_iGxcnicv4l-3-ER7I-XPpfanAFAap7uls86xV7A_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_BXf_iGxcnicv4l-3-ER7I-XPpfanAFAap7uls86xV7A_0",
"user": Object {
"email": "misty_mackerel@profiles.elastic.co",
"full_name": "Misty Mackerel",
"username": "misty_mackerel",
},
},
"participant_4_uid" => Object {
"data": Object {
"avatar": Object {
"initials": "P4",
},
},
"uid": "participant_4_uid",
"user": Object {
"email": null,
"full_name": null,
"username": "participant_4",
},
},
"participant_5_uid" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "participant_5_uid",
"user": Object {
"email": "participant_5@elastic.co",
"full_name": "Participant 5",
"username": "participant_5",
},
},
"reporter_1_uid" => Object {
"data": Object {
"avatar": Object {
"initials": "R1",
},
},
"uid": "reporter_1_uid",
"user": Object {
"email": "reporter_1@elastic.co",
"full_name": "Reporter 1",
"username": "reporter_1",
},
},
"u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0",
"user": Object {
"email": "",
"full_name": "",
"username": "cases_no_connectors",
},
},
"u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0",
"user": Object {
"email": "valid_chimpanzee@profiles.elastic.co",
"full_name": "Valid Chimpanzee",
"username": "valid_chimpanzee",
},
},
}
`);
expect(reporterAsArray).toEqual([
{
uid: 'reporter_1_uid',
avatar: {
initials: 'R1',
},
user: {
email: 'reporter_1@elastic.co',
full_name: 'Reporter 1',
username: 'reporter_1',
},
},
]);
});
it('should define a reporter without uid correctly', () => {
const caseUsers = getCaseUsersMockResponse();
const { userProfiles, reporterAsArray } = parseCaseUsers({
caseUsers: {
...caseUsers,
reporter: {
user: {
email: 'reporter_no_uid@elastic.co',
full_name: 'Reporter No UID',
username: 'reporter_no_uid',
},
},
},
createdBy: elasticUser,
});
expect(userProfiles).toMatchInlineSnapshot(`
Map {
"u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0",
"user": Object {
"email": null,
"full_name": null,
"username": "elastic",
},
},
"u_3OgKOf-ogtr8kJ5B0fnRcqzXs2aQQkZLtzKEEFnKaYg_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_3OgKOf-ogtr8kJ5B0fnRcqzXs2aQQkZLtzKEEFnKaYg_0",
"user": Object {
"email": "fuzzy_marten@profiles.elastic.co",
"full_name": "Fuzzy Marten",
"username": "fuzzy_marten",
},
},
"u_BXf_iGxcnicv4l-3-ER7I-XPpfanAFAap7uls86xV7A_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_BXf_iGxcnicv4l-3-ER7I-XPpfanAFAap7uls86xV7A_0",
"user": Object {
"email": "misty_mackerel@profiles.elastic.co",
"full_name": "Misty Mackerel",
"username": "misty_mackerel",
},
},
"participant_4_uid" => Object {
"data": Object {
"avatar": Object {
"initials": "P4",
},
},
"uid": "participant_4_uid",
"user": Object {
"email": null,
"full_name": null,
"username": "participant_4",
},
},
"participant_5_uid" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "participant_5_uid",
"user": Object {
"email": "participant_5@elastic.co",
"full_name": "Participant 5",
"username": "participant_5",
},
},
"u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_J41Oh6L9ki-Vo2tOogS8WRTENzhHurGtRc87NgEAlkc_0",
"user": Object {
"email": "",
"full_name": "",
"username": "cases_no_connectors",
},
},
"u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0" => Object {
"data": Object {
"avatar": undefined,
},
"uid": "u_A_tM4n0wPkdiQ9smmd8o0Hr_h61XQfu8aRPh9GMoRoc_0",
"user": Object {
"email": "valid_chimpanzee@profiles.elastic.co",
"full_name": "Valid Chimpanzee",
"username": "valid_chimpanzee",
},
},
}
`);
expect(reporterAsArray).toEqual([
{
user: {
email: 'reporter_no_uid@elastic.co',
full_name: 'Reporter No UID',
username: 'reporter_no_uid',
},
},
]);
});
it('uses the fallback reporter correctly', () => {
const { userProfiles, reporterAsArray } = parseCaseUsers({
createdBy: elasticUser,
});
expect(userProfiles).toMatchInlineSnapshot(`Map {}`);
expect(reporterAsArray).toEqual([
{
uid: undefined,
user: {
email: 'leslie.knope@elastic.co',
full_name: 'Leslie Knope',
username: 'lknope',
},
},
]);
});
});
});

View file

@ -10,11 +10,15 @@ import type {
FieldConfig,
ValidationConfig,
} from '@kbn/es-ui-shared-plugin/static/forms/hook_form_lib';
import type { UserProfileWithAvatar } from '@kbn/user-profile-components';
import type { ConnectorTypeFields } from '../../common/types/domain';
import { ConnectorTypes } from '../../common/types/domain';
import type { CasesPluginStart } from '../types';
import { connectorValidator as swimlaneConnectorValidator } from './connectors/swimlane/validator';
import type { CaseActionConnector } from './types';
import type { CaseUser, CaseUsers } from '../../common/ui/types';
import { convertToCaseUserWithProfileInfo } from './user_profiles/user_converter';
import type { CaseUserWithProfileInfo } from './user_profiles/types';
export const getConnectorById = (
id: string,
@ -176,3 +180,48 @@ export const stringifyToURL = (parsedParams: Record<string, string>) =>
new URLSearchParams(parsedParams).toString();
export const parseURL = (queryString: string) =>
Object.fromEntries(new URLSearchParams(queryString));
export const parseCaseUsers = ({
caseUsers,
createdBy,
}: {
caseUsers?: CaseUsers;
createdBy: CaseUser;
}): {
userProfiles: Map<string, UserProfileWithAvatar>;
reporterAsArray: CaseUserWithProfileInfo[];
} => {
const userProfiles = new Map();
const reporterAsArray =
caseUsers?.reporter != null
? [caseUsers.reporter]
: [convertToCaseUserWithProfileInfo(createdBy)];
if (caseUsers) {
for (const user of [
...caseUsers.assignees,
...caseUsers.participants,
caseUsers.reporter,
...caseUsers.unassignedUsers,
]) {
/**
* If the user has a valid profile UID and a valid username
* then the backend successfully fetched the user profile
* information from the security plugin. Checking only for the
* profile UID is not enough as a user can use our API to add
* an assignee with a non existing UID.
*/
if (user.uid != null && user.user.username != null) {
userProfiles.set(user.uid, {
uid: user.uid,
user: user.user,
data: {
avatar: user.avatar,
},
});
}
}
}
return { userProfiles, reporterAsArray };
};