Skip to content

Commit

Permalink
Use useKibana in user profiles hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
e40pud committed Nov 3, 2023
1 parent 89ec60a commit dff2654
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import { render } from '@testing-library/react';
import { ASSIGNEES_APPLY_BUTTON_TEST_ID, ASSIGNEES_APPLY_PANEL_TEST_ID } from './test_ids';
import { AssigneesApplyPanel } from './assignees_apply_panel';

import { useGetUserProfiles } from '../user_profiles/use_get_user_profiles';
import { useGetCurrentUser } from '../user_profiles/use_get_current_user';
import { useBulkGetUserProfiles } from '../user_profiles/use_bulk_get_user_profiles';
import { useSuggestUsers } from '../user_profiles/use_suggest_users';
import { TestProviders } from '../../mock';
import * as i18n from './translations';
import { mockUserProfiles } from './mocks';

jest.mock('../user_profiles/use_get_user_profiles');
jest.mock('../user_profiles/use_get_current_user');
jest.mock('../user_profiles/use_bulk_get_user_profiles');
jest.mock('../user_profiles/use_suggest_users');

const renderAssigneesApplyPanel = (
Expand All @@ -34,9 +36,9 @@ const renderAssigneesApplyPanel = (
} = { assignedUserIds: [] }
) => {
const assignedProfiles = mockUserProfiles.filter((user) => assignedUserIds.includes(user.uid));
(useGetUserProfiles as jest.Mock).mockReturnValue({
loading: false,
userProfiles: assignedProfiles,
(useBulkGetUserProfiles as jest.Mock).mockReturnValue({
isLoading: false,
data: assignedProfiles,
});
return render(
<TestProviders>
Expand All @@ -53,9 +55,13 @@ const renderAssigneesApplyPanel = (
describe('<AssigneesApplyPanel />', () => {
beforeEach(() => {
jest.clearAllMocks();
(useGetCurrentUser as jest.Mock).mockReturnValue({
isLoading: false,
data: mockUserProfiles[0],
});
(useSuggestUsers as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
isLoading: false,
data: mockUserProfiles,
});
});

Expand Down Expand Up @@ -102,9 +108,9 @@ describe('<AssigneesApplyPanel />', () => {
});

it('should call `onSelectionChange` on user selection', () => {
(useGetUserProfiles as jest.Mock).mockReturnValue({
loading: false,
userProfiles: [],
(useBulkGetUserProfiles as jest.Mock).mockReturnValue({
isLoading: false,
data: [],
});

const onSelectionChangeMock = jest.fn();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import * as i18n from './translations';
import type { AssigneesIdsSelection, AssigneesProfilesSelection } from './types';
import { NO_ASSIGNEES_VALUE } from './constants';
import { useSuggestUsers } from '../user_profiles/use_suggest_users';
import { useGetUserProfiles } from '../user_profiles/use_get_user_profiles';
import { useBulkGetUserProfiles } from '../user_profiles/use_bulk_get_user_profiles';
import { bringCurrentUserToFrontAndSort, removeNoAssigneesSelection } from './utils';
import { ASSIGNEES_APPLY_BUTTON_TEST_ID, ASSIGNEES_APPLY_PANEL_TEST_ID } from './test_ids';

Expand Down Expand Up @@ -60,16 +60,19 @@ export const AssigneesApplyPanel: FC<AssigneesApplyPanelProps> = memo(
onSelectionChange,
onAssigneesApply,
}) => {
const { userProfile: currentUserProfile } = useGetCurrentUser();
const { data: currentUserProfile } = useGetCurrentUser();
const existingIds = useMemo(
() => removeNoAssigneesSelection(assignedUserIds),
() => new Set(removeNoAssigneesSelection(assignedUserIds)),
[assignedUserIds]
);
const { loading: isLoadingAssignedUsers, userProfiles: assignedUsers } =
useGetUserProfiles(existingIds);
const { isLoading: isLoadingAssignedUsers, data: assignedUsers } = useBulkGetUserProfiles({
uids: existingIds,
});

const [searchTerm, setSearchTerm] = useState('');
const { loading: isLoadingSuggestedUsers, userProfiles } = useSuggestUsers(searchTerm);
const { isLoading: isLoadingSuggestedUsers, data: userProfiles } = useSuggestUsers({
searchTerm,
});

const searchResultProfiles = useMemo(() => {
const sortedUsers = bringCurrentUserToFrontAndSort(currentUserProfile, userProfiles) ?? [];
Expand All @@ -83,7 +86,7 @@ export const AssigneesApplyPanel: FC<AssigneesApplyPanelProps> = memo(

const [selectedAssignees, setSelectedAssignees] = useState<AssigneesProfilesSelection[]>([]);
useEffect(() => {
if (isLoadingAssignedUsers) {
if (isLoadingAssignedUsers || !assignedUsers) {
return;
}
const hasNoAssigneesSelection = assignedUserIds.find((uid) => uid === NO_ASSIGNEES_VALUE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import { render } from '@testing-library/react';
import { ASSIGNEES_APPLY_PANEL_TEST_ID } from './test_ids';
import { AssigneesPopover } from './assignees_popover';

import { useGetUserProfiles } from '../user_profiles/use_get_user_profiles';
import { useGetCurrentUser } from '../user_profiles/use_get_current_user';
import { useBulkGetUserProfiles } from '../user_profiles/use_bulk_get_user_profiles';
import { useSuggestUsers } from '../user_profiles/use_suggest_users';
import { TestProviders } from '../../mock';
import { mockUserProfiles } from './mocks';
import { EuiButton } from '@elastic/eui';

jest.mock('../user_profiles/use_get_user_profiles');
jest.mock('../user_profiles/use_get_current_user');
jest.mock('../user_profiles/use_bulk_get_user_profiles');
jest.mock('../user_profiles/use_suggest_users');

const MOCK_BUTTON_TEST_ID = 'mock-assignees-button';
Expand All @@ -30,9 +32,9 @@ const renderAssigneesPopover = ({
isPopoverOpen: boolean;
}) => {
const assignedProfiles = mockUserProfiles.filter((user) => assignedUserIds.includes(user.uid));
(useGetUserProfiles as jest.Mock).mockReturnValue({
loading: false,
userProfiles: assignedProfiles,
(useBulkGetUserProfiles as jest.Mock).mockReturnValue({
isLoading: false,
data: assignedProfiles,
});
return render(
<TestProviders>
Expand All @@ -49,9 +51,13 @@ const renderAssigneesPopover = ({
describe('<AssigneesPopover />', () => {
beforeEach(() => {
jest.clearAllMocks();
(useGetCurrentUser as jest.Mock).mockReturnValue({
isLoading: false,
data: mockUserProfiles[0],
});
(useSuggestUsers as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
isLoading: false,
data: mockUserProfiles,
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import type { TimelineItem } from '@kbn/timelines-plugin/common';
import { act, fireEvent, render } from '@testing-library/react';
import React from 'react';
import { TestProviders } from '../../../mock';
import { useGetUserProfiles } from '../../user_profiles/use_get_user_profiles';
import { useGetCurrentUser } from '../../user_profiles/use_get_current_user';
import { useBulkGetUserProfiles } from '../../user_profiles/use_bulk_get_user_profiles';
import { useSuggestUsers } from '../../user_profiles/use_suggest_users';

import { BulkAlertAssigneesPanel } from './alert_bulk_assignees';
import { ALERT_WORKFLOW_ASSIGNEE_IDS } from '@kbn/rule-data-utils';
import { ASSIGNEES_APPLY_BUTTON_TEST_ID } from '../../assignees/test_ids';

jest.mock('../../user_profiles/use_get_user_profiles');
jest.mock('../../user_profiles/use_get_current_user');
jest.mock('../../user_profiles/use_bulk_get_user_profiles');
jest.mock('../../user_profiles/use_suggest_users');

const mockUserProfiles = [
Expand Down Expand Up @@ -53,13 +55,17 @@ const mockAlertsWithAssignees = [
},
];

(useGetUserProfiles as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
(useGetCurrentUser as jest.Mock).mockReturnValue({
isLoading: false,
data: mockUserProfiles[0],
});
(useBulkGetUserProfiles as jest.Mock).mockReturnValue({
isLoading: false,
data: mockUserProfiles,
});
(useSuggestUsers as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockSuggestedUserProfiles,
isLoading: false,
data: mockSuggestedUserProfiles,
});

const renderAssigneesMenu = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import type {
import { useBulkAlertAssigneesItems } from './use_bulk_alert_assignees_items';
import { useSetAlertAssignees } from './use_set_alert_assignees';
import { useGetCurrentUser } from '../../user_profiles/use_get_current_user';
import { useGetUserProfiles } from '../../user_profiles/use_get_user_profiles';
import { useBulkGetUserProfiles } from '../../user_profiles/use_bulk_get_user_profiles';
import { useSuggestUsers } from '../../user_profiles/use_suggest_users';
import { ASSIGNEES_APPLY_BUTTON_TEST_ID } from '../../assignees/test_ids';

jest.mock('./use_set_alert_assignees');
jest.mock('../../user_profiles/use_get_current_user');
jest.mock('../../user_profiles/use_get_user_profiles');
jest.mock('../../user_profiles/use_bulk_get_user_profiles');
jest.mock('../../user_profiles/use_suggest_users');

const mockUserProfiles = [
Expand Down Expand Up @@ -55,16 +55,16 @@ describe('useBulkAlertAssigneesItems', () => {
beforeEach(() => {
(useSetAlertAssignees as jest.Mock).mockReturnValue(jest.fn());
(useGetCurrentUser as jest.Mock).mockReturnValue({
loading: false,
userProfile: mockUserProfiles[0],
isLoading: false,
data: mockUserProfiles[0],
});
(useGetUserProfiles as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
(useBulkGetUserProfiles as jest.Mock).mockReturnValue({
isLoading: false,
data: mockUserProfiles,
});
(useSuggestUsers as jest.Mock).mockReturnValue({
loading: false,
userProfiles: mockUserProfiles,
isLoading: false,
data: mockUserProfiles,
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { renderHook } from '@testing-library/react-hooks';
import { securityMock } from '@kbn/security-plugin/public/mocks';

import { mockUserProfiles } from './mock';
import { useGetUserProfiles } from './use_get_user_profiles';
import { useBulkGetUserProfiles } from './use_bulk_get_user_profiles';
import { useKibana } from '../../lib/kibana';
import { useAppToasts } from '../../hooks/use_app_toasts';
import { useAppToastsMock } from '../../hooks/use_app_toasts.mock';
Expand Down Expand Up @@ -37,8 +37,10 @@ describe('useGetUserProfiles hook', () => {
it('returns an array of userProfiles', async () => {
const userProfiles = useKibana().services.security.userProfiles;
const spyOnUserProfiles = jest.spyOn(userProfiles, 'bulkGet');
const assigneesIds = ['user1'];
const { result, waitForNextUpdate } = renderHook(() => useGetUserProfiles(assigneesIds));
const assigneesIds = new Set(['user1']);
const { result, waitForNextUpdate } = renderHook(() =>
useBulkGetUserProfiles({ uids: assigneesIds })
);
await waitForNextUpdate();

expect(spyOnUserProfiles).toHaveBeenCalledTimes(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import type { SecurityPluginStart } from '@kbn/security-plugin/public';
import type { UserProfile } from '@kbn/security-plugin/common';
import type { UserProfileWithAvatar } from '@kbn/user-profile-components';
import { useQuery } from '@tanstack/react-query';
import { useKibana } from '../lib/kibana';
import { useKibana } from '../../lib/kibana';
import { useAppToasts } from '../../hooks/use_app_toasts';
import { USER_PROFILES_FAILURE } from './translations';

export interface BulkGetUserProfilesArgs {
security: SecurityPluginStart;
Expand All @@ -28,6 +30,7 @@ export const bulkGetUserProfiles = async ({

export const useBulkGetUserProfiles = ({ uids }: { uids: Set<string> }) => {
const { security } = useKibana().services;
const { addError } = useAppToasts();

return useQuery<UserProfileWithAvatar[]>(
['useBulkGetUserProfiles', ...uids],
Expand All @@ -37,6 +40,9 @@ export const useBulkGetUserProfiles = ({ uids }: { uids: Set<string> }) => {
{
retry: false,
staleTime: Infinity,
onError: (e) => {
addError(e, { title: USER_PROFILES_FAILURE });
},
}
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,38 @@
* 2.0.
*/

import { useQuery } from '@tanstack/react-query';

import type { SecurityPluginStart } from '@kbn/security-plugin/public';
import type { UserProfileWithAvatar } from '@kbn/user-profile-components';
import { useEffect, useState } from 'react';

import { CURRENT_USER_PROFILE_FAILURE } from './translations';
import { useKibana } from '../../lib/kibana';
import { useAppToasts } from '../../hooks/use_app_toasts';

interface GetCurrentUserReturn {
loading: boolean;
userProfile?: UserProfileWithAvatar;
}
export const getCurrentUser = async ({
security,
}: {
security: SecurityPluginStart;
}): Promise<UserProfileWithAvatar> => {
return security.userProfiles.getCurrent({ dataPath: 'avatar' });
};

export const useGetCurrentUser = (): GetCurrentUserReturn => {
const [loading, setLoading] = useState(false);
const [currentUser, setCurrentUser] = useState<UserProfileWithAvatar | undefined>(undefined);
export const useGetCurrentUser = () => {
const { security } = useKibana().services;
const { addError } = useAppToasts();
const userProfiles = useKibana().services.security.userProfiles;

useEffect(() => {
// isMounted tracks if a component is mounted before changing state
let isMounted = true;
setLoading(true);
const fetchData = async () => {
try {
const profile = await userProfiles.getCurrent({ dataPath: 'avatar' });
if (isMounted) {
setCurrentUser(profile);
}
} catch (error) {
addError(error.message, { title: CURRENT_USER_PROFILE_FAILURE });
}
if (isMounted) {
setLoading(false);
}
};
fetchData();
return () => {
// updates to show component is unmounted
isMounted = false;
};
}, [addError, userProfiles]);
return { loading, userProfile: currentUser };
return useQuery<UserProfileWithAvatar>(
['useGetCurrentUser'],
async () => {
return getCurrentUser({ security });
},
{
retry: false,
staleTime: Infinity,
onError: (e) => {
addError(e, { title: CURRENT_USER_PROFILE_FAILURE });
},
}
);
};
Loading

0 comments on commit dff2654

Please sign in to comment.