fix test errors (Sort, CredentialEdit, InventoryHost, JobTemplateEdit, etc)

This commit is contained in:
Keith J. Grant
2021-07-07 13:29:30 -07:00
parent 1b5fa9c799
commit 226ffafbd6
14 changed files with 161 additions and 187 deletions

View File

@@ -8,7 +8,7 @@ jest.mock('../../api');
describe('<VariablesDetail>', () => {
test('should render readonly CodeEditor', () => {
const wrapper = mountWithContexts(
<VariablesDetail value="---foo: bar" label="Variables" />
<VariablesDetail value="---foo: bar" label="Variables" name="test" />
);
const input = wrapper.find('VariablesDetail___StyledCodeEditor');
expect(input).toHaveLength(1);
@@ -19,7 +19,7 @@ describe('<VariablesDetail>', () => {
test('should detect JSON', () => {
const wrapper = mountWithContexts(
<VariablesDetail value='{"foo": "bar"}' label="Variables" />
<VariablesDetail value='{"foo": "bar"}' label="Variables" name="test" />
);
const input = wrapper.find('VariablesDetail___StyledCodeEditor');
expect(input).toHaveLength(1);
@@ -28,7 +28,7 @@ describe('<VariablesDetail>', () => {
test('should format JSON', () => {
const wrapper = mountWithContexts(
<VariablesDetail value='{"foo": "bar"}' label="Variables" />
<VariablesDetail value='{"foo": "bar"}' label="Variables" name="test" />
);
const input = wrapper.find('VariablesDetail___StyledCodeEditor');
expect(input).toHaveLength(1);
@@ -37,7 +37,7 @@ describe('<VariablesDetail>', () => {
test('should convert between modes', () => {
const wrapper = mountWithContexts(
<VariablesDetail value="---foo: bar" label="Variables" />
<VariablesDetail value="---foo: bar" label="Variables" name="test" />
);
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
const input = wrapper.find('VariablesDetail___StyledCodeEditor');
@@ -52,7 +52,7 @@ describe('<VariablesDetail>', () => {
test('should render label and value --- when there are no values', () => {
const wrapper = mountWithContexts(
<VariablesDetail value="" label="Variables" />
<VariablesDetail value="" label="Variables" name="test" />
);
expect(wrapper.find('VariablesDetail___StyledCodeEditor').length).toBe(1);
expect(wrapper.find('.pf-c-form__label').text()).toBe('Variables');
@@ -60,7 +60,7 @@ describe('<VariablesDetail>', () => {
test('should update value if prop changes', () => {
const wrapper = mountWithContexts(
<VariablesDetail value="---foo: bar" label="Variables" />
<VariablesDetail value="---foo: bar" label="Variables" name="test" />
);
act(() => {
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');
@@ -76,7 +76,7 @@ describe('<VariablesDetail>', () => {
test('should default yaml value to "---"', () => {
const wrapper = mountWithContexts(
<VariablesDetail value="" label="Variables" />
<VariablesDetail value="" label="Variables" name="test" />
);
const input = wrapper.find('VariablesDetail___StyledCodeEditor');
expect(input.prop('value')).toEqual('---');
@@ -84,7 +84,7 @@ describe('<VariablesDetail>', () => {
test('should default empty json to "{}"', () => {
const wrapper = mountWithContexts(
<VariablesDetail value="" label="Variables" />
<VariablesDetail value="" label="Variables" name="test" />
);
act(() => {
wrapper.find('MultiButtonToggle').invoke('onChange')('javascript');

View File

@@ -1,5 +1,6 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { shallow } from 'enzyme';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import DataListToolbar from './DataListToolbar';
import AddDropDownButton from '../AddDropDownButton/AddDropDownButton';
@@ -100,6 +101,7 @@ describe('<DataListToolbar />', () => {
searchColumns={searchColumns}
sortColumns={sortColumns}
onSort={onSort}
onSearch={() => {}}
/>
);
const sortDropdownToggle = toolbar.find(sortDropdownToggleSelector);
@@ -122,6 +124,7 @@ describe('<DataListToolbar />', () => {
searchColumns={searchColumns}
sortColumns={sortColumns}
onSort={onSort}
onSearch={() => {}}
/>
);
toolbar.update();
@@ -155,92 +158,28 @@ describe('<DataListToolbar />', () => {
searchDropdownItems.at(0).simulate('click', mockedSearchEvent);
});
test('it displays correct sort icon', () => {
const NUM_QS_CONFIG = {
test('should render sort icon', () => {
const qsConfig = {
namespace: 'organization',
dateFields: ['modified', 'created'],
defaultParams: { page: 1, page_size: 5, order_by: 'id' },
integerFields: ['page', 'page_size', 'id'],
};
const sortColumns = [{ name: 'Name', key: 'name' }];
const NUM_DESC_QS_CONFIG = {
namespace: 'organization',
dateFields: ['modified', 'created'],
defaultParams: { page: 1, page_size: 5, order_by: '-id' },
integerFields: ['page', 'page_size', 'id'],
};
const ALPH_QS_CONFIG = {
namespace: 'organization',
dateFields: ['modified', 'created'],
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
integerFields: ['page', 'page_size', 'id'],
};
const ALPH_DESC_QS_CONFIG = {
namespace: 'organization',
dateFields: ['modified', 'created'],
defaultParams: { page: 1, page_size: 5, order_by: '-name' },
integerFields: ['page', 'page_size', 'id'],
};
const forwardNumericIconSelector = 'SortNumericDownIcon';
const reverseNumericIconSelector = 'SortNumericDownAltIcon';
const forwardAlphaIconSelector = 'SortAlphaDownIcon';
const reverseAlphaIconSelector = 'SortAlphaDownAltIcon';
const numericColumns = [{ name: 'ID', key: 'id' }];
const alphaColumns = [{ name: 'Name', key: 'name' }];
const searchColumns = [
{ name: 'Name', key: 'name', isDefault: true },
{ name: 'ID', key: 'id' },
];
toolbar = mountWithContexts(
const wrapper = shallow(
<DataListToolbar
qsConfig={NUM_DESC_QS_CONFIG}
searchColumns={searchColumns}
sortColumns={numericColumns}
qsConfig={qsConfig}
searchColumns={[{ name: 'ID', key: 'id' }]}
sortColumns={sortColumns}
onSort={onSort}
/>
);
const reverseNumericIcon = toolbar.find(reverseNumericIconSelector);
expect(reverseNumericIcon.length).toBe(1);
toolbar = mountWithContexts(
<DataListToolbar
qsConfig={NUM_QS_CONFIG}
searchColumns={searchColumns}
sortColumns={numericColumns}
/>
);
const forwardNumericIcon = toolbar.find(forwardNumericIconSelector);
expect(forwardNumericIcon.length).toBe(1);
toolbar = mountWithContexts(
<DataListToolbar
qsConfig={ALPH_DESC_QS_CONFIG}
searchColumns={searchColumns}
sortColumns={alphaColumns}
/>
);
const reverseAlphaIcon = toolbar.find(reverseAlphaIconSelector);
expect(reverseAlphaIcon.length).toBe(1);
toolbar = mountWithContexts(
<DataListToolbar
qsConfig={ALPH_QS_CONFIG}
searchColumns={searchColumns}
sortColumns={alphaColumns}
/>
);
const forwardAlphaIcon = toolbar.find(forwardAlphaIconSelector);
expect(forwardAlphaIcon.length).toBe(1);
const sort = wrapper.find('Sort');
expect(sort.prop('qsConfig')).toEqual(qsConfig);
expect(sort.prop('columns')).toEqual(sortColumns);
expect(sort.prop('onSort')).toEqual(onSort);
});
test('should render additionalControls', () => {

View File

@@ -10,6 +10,7 @@ const SmallButton = styled(Button)`
font-size: var(--pf-global--FontSize--xs);
}
`;
SmallButton.displayName = 'SmallButton';
function MultiButtonToggle({ buttons, value, onChange, name }) {
const setValue = newValue => {

View File

@@ -1,12 +1,13 @@
import React from 'react';
import { mount } from 'enzyme';
import { shallow } from 'enzyme';
import MultiButtonToggle from './MultiButtonToggle';
describe('<MultiButtonToggle />', () => {
let wrapper;
const onChange = jest.fn();
beforeAll(() => {
wrapper = mount(
wrapper = shallow(
<MultiButtonToggle
buttons={[
['yaml', 'YAML'],
@@ -14,20 +15,20 @@ describe('<MultiButtonToggle />', () => {
]}
value="yaml"
onChange={onChange}
name="the-button"
/>
);
});
afterAll(() => {
wrapper.unmount();
});
it('should render buttons successfully', () => {
const buttons = wrapper.find('Button');
const buttons = wrapper.find('SmallButton');
expect(buttons.length).toBe(2);
expect(buttons.at(0).props().variant).toBe('primary');
expect(buttons.at(1).props().variant).toBe('secondary');
});
it('should call onChange function when button clicked', () => {
const buttons = wrapper.find('Button');
const buttons = wrapper.find('SmallButton');
buttons.at(1).simulate('click');
expect(onChange).toHaveBeenCalledWith('json');
});

View File

@@ -147,4 +147,7 @@ Sort.defaultProps = {
onSort: null,
};
export default withRouter(Sort);
export { Sort as _Sort };
const Wrapped = withRouter(Sort);
Wrapped.displayName = 'Sort';
export default Wrapped;

View File

@@ -1,11 +1,19 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { shallow } from 'enzyme';
import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import Sort from './Sort';
import Sort, { _Sort as SortUnwrapped } from './Sort';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useLocation: () => ({
pathname: '/organizations',
}),
}));
describe('<Sort />', () => {
let sort;
@@ -16,7 +24,7 @@ describe('<Sort />', () => {
}
});
test('it triggers the expected callbacks', () => {
test('should trigger onSort callback', () => {
const qsConfig = {
namespace: 'item',
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
@@ -150,71 +158,79 @@ describe('<Sort />', () => {
expect(onSort).toBeCalledWith('bar', 'ascending');
});
test('It displays correct sort icon', () => {
const forwardNumericIconSelector = 'SortNumericDownIcon';
const reverseNumericIconSelector = 'SortNumericDownAltIcon';
const forwardAlphaIconSelector = 'SortAlphaDownIcon';
const reverseAlphaIconSelector = 'SortAlphaDownAltIcon';
test('should display numeric descending icon', () => {
const qsConfigNumDown = {
namespace: 'item',
defaultParams: { page: 1, page_size: 5, order_by: '-id' },
integerFields: ['page', 'page_size', 'id'],
};
const numericColumns = [{ name: 'ID', key: 'id' }];
const wrapper = shallow(
<SortUnwrapped
qsConfig={qsConfigNumDown}
columns={numericColumns}
onSort={jest.fn()}
/>
);
expect(wrapper.find('SortNumericDownAltIcon')).toHaveLength(1);
});
test('should display numeric ascending icon', () => {
const qsConfigNumUp = {
namespace: 'item',
defaultParams: { page: 1, page_size: 5, order_by: 'id' },
integerFields: ['page', 'page_size', 'id'],
};
const numericColumns = [{ name: 'ID', key: 'id' }];
const wrapper = shallow(
<SortUnwrapped
qsConfig={qsConfigNumUp}
columns={numericColumns}
onSort={jest.fn()}
/>
);
expect(wrapper.find('SortNumericDownIcon')).toHaveLength(1);
});
test('should display alphanumeric descending icon', () => {
const qsConfigAlphaDown = {
namespace: 'item',
defaultParams: { page: 1, page_size: 5, order_by: '-name' },
integerFields: ['page', 'page_size'],
};
const qsConfigAlphaUp = {
const alphaColumns = [{ name: 'Name', key: 'name' }];
const wrapper = shallow(
<SortUnwrapped
qsConfig={qsConfigAlphaDown}
columns={alphaColumns}
onSort={jest.fn()}
/>
);
expect(wrapper.find('SortAlphaDownAltIcon')).toHaveLength(1);
});
test('should display alphanumeric ascending icon', () => {
const qsConfigAlphaDown = {
namespace: 'item',
defaultParams: { page: 1, page_size: 5, order_by: 'name' },
integerFields: ['page', 'page_size'],
};
const numericColumns = [{ name: 'ID', key: 'id' }];
const alphaColumns = [{ name: 'Name', key: 'name' }];
const onSort = jest.fn();
sort = mountWithContexts(
<Sort
qsConfig={qsConfigNumDown}
columns={numericColumns}
onSort={onSort}
/>
);
const reverseNumericIcon = sort.find(reverseNumericIconSelector);
expect(reverseNumericIcon.length).toBe(1);
sort = mountWithContexts(
<Sort qsConfig={qsConfigNumUp} columns={numericColumns} onSort={onSort} />
);
const forwardNumericIcon = sort.find(forwardNumericIconSelector);
expect(forwardNumericIcon.length).toBe(1);
sort = mountWithContexts(
<Sort
const wrapper = shallow(
<SortUnwrapped
qsConfig={qsConfigAlphaDown}
columns={alphaColumns}
onSort={onSort}
onSort={jest.fn()}
/>
);
const reverseAlphaIcon = sort.find(reverseAlphaIconSelector);
expect(reverseAlphaIcon.length).toBe(1);
sort = mountWithContexts(
<Sort qsConfig={qsConfigAlphaUp} columns={alphaColumns} onSort={onSort} />
);
const forwardAlphaIcon = sort.find(forwardAlphaIconSelector);
expect(forwardAlphaIcon.length).toBe(1);
expect(wrapper.find('SortAlphaDownIcon')).toHaveLength(1);
});
});

View File

@@ -350,10 +350,6 @@ describe('<CredentialEdit />', () => {
});
});
afterEach(() => {
wrapper.unmount();
});
test('initially renders successfully', async () => {
expect(wrapper.find('CredentialEdit').length).toBe(1);
});

View File

@@ -128,6 +128,7 @@ function CredentialPluginField(props) {
{fieldOptions.ask_at_runtime ? (
<FieldWithPrompt
isRequired={isRequired}
fieldId={`credential-${fieldOptions.id}`}
label={fieldOptions.label}
promptId={`credential-prompt-${fieldOptions.id}`}
promptName={`passwordPrompts.${fieldOptions.id}`}

View File

@@ -32,9 +32,7 @@ describe('<InventoryHost />', () => {
let history;
beforeEach(async () => {
InventoriesAPI.readHostDetail.mockResolvedValue({
data: { ...mockHost },
});
InventoriesAPI.readHostDetail.mockResolvedValue(mockHost);
await act(async () => {
wrapper = mountWithContexts(

View File

@@ -11,21 +11,21 @@ describe('<InventoryRelatedGroupListItem />', () => {
beforeEach(() => {
wrapper = mountWithContexts(
<InventoryRelatedGroupListItem
detailUrl="/group/1"
editUrl="/group/1"
group={mockGroup}
isSelected={false}
onSelect={() => {}}
rowIndex={0}
/>
<table>
<tbody>
<InventoryRelatedGroupListItem
detailUrl="/group/1"
editUrl="/group/1"
group={mockGroup}
isSelected={false}
onSelect={() => {}}
rowIndex={0}
/>
</tbody>
</table>
);
});
afterEach(() => {
wrapper.unmount();
});
test('should display expected row item content', () => {
expect(wrapper.find('b').text()).toContain('Group 2 Inventory 0');
});
@@ -36,14 +36,18 @@ describe('<InventoryRelatedGroupListItem />', () => {
test('edit button hidden from users without edit capabilities', () => {
wrapper = mountWithContexts(
<InventoryRelatedGroupListItem
detailUrl="/group/1"
editUrl="/group/1"
group={mockRelatedGroups.results[2]}
isSelected={false}
onSelect={() => {}}
rowIndex={0}
/>
<table>
<tbody>
<InventoryRelatedGroupListItem
detailUrl="/group/1"
editUrl="/group/1"
group={mockRelatedGroups.results[2]}
isSelected={false}
onSelect={() => {}}
rowIndex={0}
/>
</tbody>
</table>
);
expect(wrapper.find('PencilAltIcon').exists()).toBeFalsy();
});

View File

@@ -34,9 +34,7 @@ describe('<SmartInventoryHost />', () => {
});
test('should render expected tabs', async () => {
InventoriesAPI.readHostDetail.mockResolvedValue({
data: { ...mockHost },
});
InventoriesAPI.readHostDetail.mockResolvedValue(mockHost);
await act(async () => {
wrapper = mountWithContexts(
<SmartInventoryHost
@@ -73,9 +71,7 @@ describe('<SmartInventoryHost />', () => {
});
test('should show content error when user attempts to navigate to erroneous route', async () => {
InventoriesAPI.readHostDetail.mockResolvedValue({
data: { ...mockHost },
});
InventoriesAPI.readHostDetail.mockResolvedValue(mockHost);
history = createMemoryHistory({
initialEntries: ['/inventories/smart_inventory/1/hosts/1/foobar'],
});

View File

@@ -20,10 +20,14 @@ describe('<TeamRoleListItem/>', () => {
test('should mount properly', () => {
wrapper = mountWithContexts(
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
<table>
<tbody>
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
</tbody>
</table>
);
expect(wrapper.length).toBe(1);
@@ -31,10 +35,14 @@ describe('<TeamRoleListItem/>', () => {
test('should render proper list item data', () => {
wrapper = mountWithContexts(
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
<table>
<tbody>
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
</tbody>
</table>
);
expect(wrapper.find('Td[dataLabel="Resource Name"]').text()).toBe(
'template delete project'
@@ -47,20 +55,28 @@ describe('<TeamRoleListItem/>', () => {
test('should render deletable chip', () => {
wrapper = mountWithContexts(
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
<table>
<tbody>
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
</tbody>
</table>
);
expect(wrapper.find('Chip').prop('isReadOnly')).toBe(false);
});
test('should render read only chip', () => {
role.summary_fields.user_capabilities.unattach = false;
wrapper = mountWithContexts(
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
<table>
<tbody>
<TeamRoleListItem
role={role}
detailUrl="/templates/job_template/15/details"
/>
</tbody>
</table>
);
expect(wrapper.find('Chip').prop('isReadOnly')).toBe(true);
});

View File

@@ -299,7 +299,10 @@ describe('<JobTemplateEdit />', () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<JobTemplateEdit template={mockJobTemplate} />
<JobTemplateEdit
template={mockJobTemplate}
reloadTemplate={jest.fn()}
/>
);
});
wrapper.update();

View File

@@ -13,9 +13,9 @@ describe('<MultipleChoiceField/>', () => {
<Formik
initialValues={{
formattedChoices: [
{ choice: 'apollo', isDefault: true },
{ choice: 'alex', isDefault: true },
{ choice: 'athena', isDefault: false },
{ id: 1, choice: 'apollo', isDefault: true },
{ id: 2, choice: 'alex', isDefault: true },
{ id: 3, choice: 'athena', isDefault: false },
],
type: 'multiselect',
}}