Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions awx/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@
},
"jest": {
"roots": [
"<rootDir>/src"
"<rootDir>/src",
"<rootDir>/testUtils"
],
"collectCoverageFrom": [
"src/**/*.{js,jsx}",
Expand All @@ -164,7 +165,8 @@
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}",
"<rootDir>/testUtils/**/*.{spec,test}.{js,jsx,ts,tsx}"
],
"testEnvironment": "jsdom",
"transform": {
Expand Down
13 changes: 9 additions & 4 deletions awx/ui/src/components/AlertModal/AlertModal.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { screen } from '@testing-library/react';
import { renderWithContexts } from '../../../testUtils/rtlContexts';

import AlertModal from './AlertModal';

describe('AlertModal', () => {
test('renders the expected content', () => {
const wrapper = mountWithContexts(
<AlertModal title="Danger!">Are you sure?</AlertModal>
renderWithContexts(
<AlertModal isOpen title="Danger!">
Are you sure?
</AlertModal>
);
expect(wrapper).toHaveLength(1);
expect(screen.getByRole('dialog')).toBeInTheDocument();
expect(screen.getByText('Danger!')).toBeInTheDocument();
expect(screen.getByText('Are you sure?')).toBeInTheDocument();
});
});
18 changes: 11 additions & 7 deletions awx/ui/src/components/ChipGroup/ChipGroup.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { Chip } from '@patternfly/react-core';
import { screen } from '@testing-library/react';
import { renderWithContexts } from '../../../testUtils/rtlContexts';
import ChipGroup from './ChipGroup';

describe('ChipGroup', () => {
test('should mount properly', () => {
const wrapper = mountWithContexts(
<ChipGroup numChips={5} totalChips={10} />
);
expect(wrapper.find('ChipGroup').at(1).props().collapsedText).toEqual(
'5 more'
test('should show the collapsed-chip count', () => {
renderWithContexts(
<ChipGroup numChips={5} totalChips={10}>
{Array.from({ length: 10 }, (v, i) => (
<Chip key={i}>{`chip ${i}`}</Chip>
))}
</ChipGroup>
);
expect(screen.getByText('5 more')).toBeInTheDocument();
});
});
7 changes: 4 additions & 3 deletions awx/ui/src/components/ContentEmpty/ContentEmpty.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { screen } from '@testing-library/react';
import { renderWithContexts } from '../../../testUtils/rtlContexts';

import ContentEmpty from './ContentEmpty';

describe('ContentEmpty', () => {
test('renders the expected content', () => {
const wrapper = mountWithContexts(<ContentEmpty />);
expect(wrapper).toHaveLength(1);
renderWithContexts(<ContentEmpty />);
expect(screen.getByText('No items found.')).toBeInTheDocument();
});
});
7 changes: 4 additions & 3 deletions awx/ui/src/components/ContentLoading/ContentLoading.test.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { screen } from '@testing-library/react';
import { renderWithContexts } from '../../../testUtils/rtlContexts';

import ContentLoading from './ContentLoading';

describe('ContentLoading', () => {
test('renders the expected content', () => {
const wrapper = mountWithContexts(<ContentLoading />);
expect(wrapper).toHaveLength(1);
renderWithContexts(<ContentLoading />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
});
});
125 changes: 52 additions & 73 deletions awx/ui/src/components/DeleteButton/DeleteButton.test.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,42 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { screen, waitFor } from '@testing-library/react';
import { CredentialsAPI } from 'api';
import {
mountWithContexts,
waitForElement,
} from '../../../testUtils/enzymeHelpers';
import { renderWithContexts } from '../../../testUtils/rtlContexts';
import DeleteButton from './DeleteButton';

jest.mock('../../api');

describe('<DeleteButton />', () => {
test('should render button', () => {
const wrapper = mountWithContexts(
<DeleteButton onConfirm={() => {}} name="Foo" />
);
expect(wrapper.find('button')).toHaveLength(1);
renderWithContexts(<DeleteButton onConfirm={() => {}} name="Foo" />);
expect(screen.getByRole('button', { name: 'Delete' })).toBeInTheDocument();
});

test('should open confirmation modal', async () => {
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<DeleteButton
onConfirm={() => {}}
name="Foo"
deleteDetailsRequests={[
{
label: 'job',
request: CredentialsAPI.read.mockResolvedValue({
data: { count: 1 },
}),
},
]}
deleteMessage="Delete this?"
warningMessage="Are you sure to want to delete this"
/>
);
});

await act(async () => {
wrapper.find('button').prop('onClick')();
});

await waitForElement(wrapper, 'Modal', (el) => el.length > 0);
expect(wrapper.find('Modal')).toHaveLength(1);

expect(wrapper.find('div[aria-label="Delete this?"]')).toHaveLength(1);
const { user } = renderWithContexts(
<DeleteButton
onConfirm={() => {}}
name="Foo"
deleteDetailsRequests={[
{
label: 'job',
request: CredentialsAPI.read.mockResolvedValue({
data: { count: 1 },
}),
},
]}
deleteMessage="Delete this?"
warningMessage="Are you sure to want to delete this"
/>
);
await user.click(screen.getByRole('button', { name: 'Delete' }));
expect(await screen.findByRole('dialog')).toBeInTheDocument();
expect(screen.getByText('Delete this?')).toBeInTheDocument();
});

test('should invoke onConfirm prop', async () => {
const onConfirm = jest.fn();
const wrapper = mountWithContexts(
const { user } = renderWithContexts(
<DeleteButton
onConfirm={onConfirm}
itemsToDelete="foo"
Expand All @@ -65,48 +51,41 @@ describe('<DeleteButton />', () => {
deleteMessage="Delete this?"
/>
);
await act(async () => wrapper.find('button').simulate('click'));
wrapper.update();
await act(async () =>
wrapper
.find('ModalBoxFooter button[aria-label="Confirm Delete"]')
.simulate('click')
await user.click(screen.getByRole('button', { name: 'Delete' }));
await user.click(
await screen.findByRole('button', { name: 'Confirm Delete' })
);
wrapper.update();
expect(onConfirm).toHaveBeenCalled();
});

test('should show delete details error', async () => {
const onConfirm = jest.fn();
let wrapper;
await act(async () => {
wrapper = mountWithContexts(
<DeleteButton
onConfirm={onConfirm}
itemsToDelete="foo"
deleteDetailsRequests={[
{
label: 'job',
request: CredentialsAPI.read.mockRejectedValue(
new Error({
response: {
config: {
method: 'get',
url: '/api/v2/credentals',
},
data: 'An error occurred',
status: 403,
const { user } = renderWithContexts(
<DeleteButton
onConfirm={onConfirm}
itemsToDelete="foo"
deleteDetailsRequests={[
{
label: 'job',
request: CredentialsAPI.read.mockRejectedValue(
Object.assign(new Error('An error occurred'), {
response: {
config: {
method: 'get',
Comment thread
cigamit marked this conversation as resolved.
url: '/api/v2/credentials',
},
})
),
},
]}
/>
);
data: 'An error occurred',
status: 403,
},
})
),
},
]}
/>
);
await user.click(screen.getByRole('button', { name: 'Delete' }));
await waitFor(() => {
expect(screen.getByText('Error!')).toBeInTheDocument();
});
await act(async () => wrapper.find('button').simulate('click'));
wrapper.update();

expect(wrapper.find('AlertModal[title="Error!"]')).toHaveLength(1);
});
});
16 changes: 11 additions & 5 deletions awx/ui/src/components/FormActionGroup/FormActionGroup.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { screen } from '@testing-library/react';
import { renderWithContexts } from '../../../testUtils/rtlContexts';

import FormActionGroup from './FormActionGroup';

describe('FormActionGroup', () => {
test('should render the expected content', () => {
const wrapper = mountWithContexts(
<FormActionGroup onSubmit={() => {}} onCancel={() => {}} />
test('should render save and cancel buttons and invoke their handlers', async () => {
const onSubmit = jest.fn();
const onCancel = jest.fn();
const { user } = renderWithContexts(
<FormActionGroup onSubmit={onSubmit} onCancel={onCancel} />
);
expect(wrapper).toHaveLength(1);
await user.click(screen.getByRole('button', { name: 'Save' }));
expect(onSubmit).toHaveBeenCalled();
await user.click(screen.getByRole('button', { name: 'Cancel' }));
expect(onCancel).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import { screen } from '@testing-library/react';
import { renderWithContexts } from '../../../testUtils/rtlContexts';
import ToolbarSyncSourceButton from './ToolbarSyncSourceButton';

describe('<ToolbarSyncSourceButton />', () => {
test('should render button', () => {
test('should render button and invoke onClick', async () => {
const onClick = jest.fn();
const wrapper = mountWithContexts(
const { user } = renderWithContexts(
<ToolbarSyncSourceButton onClick={onClick} />
);
const button = wrapper.find('button');
expect(button).toHaveLength(1);
button.simulate('click');
const button = screen.getByRole('button', { name: 'Sync all' });
await user.click(button);
expect(onClick).toHaveBeenCalled();
});
});
1 change: 1 addition & 0 deletions awx/ui/src/setupTests.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import '@testing-library/jest-dom';
import React from 'react';
import { configure } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
Expand Down
53 changes: 53 additions & 0 deletions awx/ui/testUtils/__snapshots__/enzymeHelpers.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing

exports[`mountWithContexts injected ConfigProvider should mount and render with custom Config value 1`] = `
<Foo>
<div>
1.1
</div>
</Foo>
`;

exports[`mountWithContexts injected ConfigProvider should mount and render with default values 1`] = `
<Foo>
<div />
</Foo>
`;

exports[`mountWithContexts injected I18nProvider should mount and render 1`] = `
<div>
<span>
Text content
</span>
</div>
`;

exports[`mountWithContexts injected I18nProvider should mount and render deeply nested consumer 1`] = `
<Parent>
<Child>
<div>
Text content
</div>
</Child>
</Parent>
`;

exports[`mountWithContexts injected Router should mount and render 1`] = `
<div>
<Link
to="/"
>
<LinkAnchor
href="/"
navigate={[Function]}
>
<a
href="/"
onClick={[Function]}
>
home
</a>
</LinkAnchor>
</Link>
</div>
`;
6 changes: 2 additions & 4 deletions awx/ui/testUtils/enzymeHelpers.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,18 +120,17 @@ class TestAsyncComponent extends Component {
}

describe('waitForElement', () => {
it('waits for the element and returns it', async done => {
it('waits for the element and returns it', async () => {
const selector = '#test-async-component';
const wrapper = mountWithContexts(<TestAsyncComponent />);
expect(wrapper.exists(selector)).toEqual(false);

const elem = await waitForElement(wrapper, selector);
expect(elem.props().id).toEqual('test-async-component');
expect(wrapper.exists(selector)).toEqual(true);
done();
});

it("eventually throws an error for elements that don't exist", async done => {
it("eventually throws an error for elements that don't exist", async () => {
const wrapper = mountWithContexts(<div />);

let error;
Expand All @@ -144,7 +143,6 @@ describe('waitForElement', () => {
'Expected condition for <#does-not-exist> not met'
);
expect(error.message).toContain('el.length === 1');
done();
}
});
});
Loading