/*
* 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)
);
});
});
});