/* * Copyright OpenSearch Contributors * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://www.apache.org/licenses/LICENSE-2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ import { EuiBadge, EuiText, EuiInMemoryTable } from '@elastic/eui'; import { shallow } from 'enzyme'; import React from 'react'; import { EMPTY_FIELD_VALUE } from '../../ui-constants'; import { useDeleteConfirmState } from '../../utils/delete-confirm-modal-utils'; import { getUserList, InternalUsersListing, requestDeleteUsers, } from '../../utils/internal-user-list-utils'; import { dictView, getColumns, UserList } from '../user-list'; jest.mock('../../utils/internal-user-list-utils'); jest.mock('../../../../utils/auth-info-utils', () => ({ getAuthInfo: jest.fn().mockReturnValue({ user_name: 'user' }), })); jest.mock('../../utils/delete-confirm-modal-utils', () => ({ useDeleteConfirmState: jest.fn().mockReturnValue([jest.fn(), '']), })); jest.mock('../../utils/context-menu', () => ({ useContextMenuState: jest .fn() .mockImplementation((buttonText, buttonProps, children) => [children, jest.fn()]), })); import { getAuthInfo } from '../../../../utils/auth-info-utils'; import { buildHashUrl } from '../../utils/url-builder'; import { ResourceType, Action } from '../../types'; describe('User list', () => { describe('dictView', () => { it('- empty', () => { const result = dictView({}); expect(result).toEqual(EMPTY_FIELD_VALUE); }); it('dictView - non-empty', () => { const attr1 = 'attr1'; const attr2 = 'attr2'; const value1 = 'value1'; const value2 = 'value2'; const result = shallow(dictView({ [attr1]: value1, [attr2]: value2 })); expect(result.find(EuiText).at(0).prop('children')).toEqual([attr1, ': ', `"${value1}"`]); expect(result.find(EuiText).at(1).prop('children')).toEqual([attr2, ': ', `"${value2}"`]); }); }); describe('getColumns', () => { it('current user', () => { const columns = getColumns('user1'); const usernameRenderer = columns[0].render as (usename: string) => JSX.Element; const Container = (props: { username: string }) => usernameRenderer(props.username); const result = shallow(); expect(result.find(EuiBadge).length).toBe(1); }); it('not current user', () => { const columns = getColumns('user1'); const usernameRenderer = columns[0].render as (usename: string) => JSX.Element; const Container = (props: { username: string }) => usernameRenderer(props.username); const result = shallow(); expect(result.find(EuiBadge).length).toBe(0); }); }); describe('UserList', () => { const mockCoreStart = { http: 1, }; const setState = jest.fn(); jest.spyOn(React, 'useState').mockImplementation((initValue) => [initValue, setState]); it('render empty', () => { const component = shallow( ); expect(component.find(EuiInMemoryTable).prop('items')).toEqual([]); }); it('fetch data', () => { jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); shallow( ); expect(getUserList).toBeCalled(); expect(getAuthInfo).toBeCalled(); }); it('fetch data error', () => { jest.spyOn(React, 'useEffect').mockImplementationOnce((f) => f()); getUserList.mockImplementationOnce(() => { throw new Error(); }); // Hide the error message jest.spyOn(console, 'log').mockImplementationOnce(() => {}); shallow( ); // Expect error flag set to true expect(setState).toBeCalledWith(true); }); it('delete user', (done) => { shallow( ); const deleteFunc = useDeleteConfirmState.mock.calls[0][0]; deleteFunc(); process.nextTick(() => { expect(requestDeleteUsers).toBeCalled(); done(); }); }); it('delete user error', (done) => { requestDeleteUsers.mockImplementationOnce(() => { throw new Error(); }); // Hide the error message const loggingFunc = jest.fn(); jest.spyOn(console, 'log').mockImplementationOnce(loggingFunc); shallow( ); const deleteFunc = useDeleteConfirmState.mock.calls[0][0]; deleteFunc(); process.nextTick(() => { expect(loggingFunc).toBeCalled(); done(); }); }); }); describe('Action menu click', () => { const mockCoreStart = { http: { basePath: { serverBasePath: '', }, }, }; let component; const mockUserListingData: InternalUsersListing = { username: 'user_1', attributes: { key: 'value' }, backend_roles: ['backend_role1'], }; beforeEach(() => { jest.spyOn(React, 'useState').mockImplementation(() => [[mockUserListingData], jest.fn()]); component = shallow( ); }); it('Edit click', () => { component.find('[data-test-subj="edit"]').simulate('click'); expect(window.location.hash).toBe( buildHashUrl(ResourceType.users, Action.edit, mockUserListingData.username) ); }); it('Duplicate click', () => { component.find('[data-test-subj="duplicate"]').simulate('click'); expect(window.location.hash).toBe( buildHashUrl(ResourceType.users, Action.duplicate, mockUserListingData.username) ); }); }); });