Chore: Convert QueryOperationRow test to RTL (#51290)

* Convert QueryOperationRow test to RTL

* Convert QueryOperationRow test to RTL

* Convert QueryOperationRow test to RTL

* Convert QueryOperationRow test to RTL

* Update QueryOperationRow.test.tsx

* update betterer

Co-authored-by: Ashley Harrison <ashley.harrison@grafana.com>
This commit is contained in:
Seyaji 2022-07-05 13:10:20 +01:00 committed by GitHub
parent d4eef3bd76
commit 500010e0b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 94 deletions

View File

@ -65,9 +65,6 @@ exports[`no enzyme tests`] = {
"packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:276996587": [ "packages/jaeger-ui-components/src/TraceTimelineViewer/index.test.js:276996587": [
[14, 19, 13, "RegExp match", "2409514259"] [14, 19, 13, "RegExp match", "2409514259"]
], ],
"public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx:3743889097": [
[0, 26, 13, "RegExp match", "2409514259"]
],
"public/app/core/components/Select/MetricSelect.test.tsx:1074737147": [ "public/app/core/components/Select/MetricSelect.test.tsx:1074737147": [
[0, 19, 13, "RegExp match", "2409514259"] [0, 19, 13, "RegExp match", "2409514259"]
], ],
@ -3125,10 +3122,6 @@ exports[`better eslint`] = {
"public/app/core/components/PermissionList/PermissionList.tsx:5381": [ "public/app/core/components/PermissionList/PermissionList.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
], ],
"public/app/core/components/QueryOperationRow/QueryOperationRow.test.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/core/components/RolePicker/RolePickerMenu.tsx:5381": [ "public/app/core/components/RolePicker/RolePickerMenu.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"] [0, 0, 0, "Unexpected any. Specify a different type.", "0"]
], ],

View File

@ -1,56 +1,44 @@
import { mount, shallow } from 'enzyme'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { act } from 'react-dom/test-utils';
import { QueryOperationRow } from './QueryOperationRow'; import { QueryOperationRow, QueryOperationRowProps } from './QueryOperationRow';
const setup = (propOverrides?: Partial<QueryOperationRowProps>) => {
const props: QueryOperationRowProps = {
title: 'test-title',
headerElement: '',
index: 0,
id: 'test-id',
children: <div>children</div>,
...propOverrides,
};
return render(<QueryOperationRow {...props}></QueryOperationRow>);
};
describe('QueryOperationRow', () => { describe('QueryOperationRow', () => {
it('renders', () => { it('renders without exploding', () => {
expect(() => expect(() => setup()).not.toThrow();
shallow( });
<QueryOperationRow id="test-id" index={0}>
<div>Test</div> it('renders the component content', () => {
</QueryOperationRow> setup();
) expect(screen.getByText(/^test-title$/)).toBeInTheDocument();
).not.toThrow();
}); });
describe('callbacks', () => { describe('callbacks', () => {
it('should not call onOpen when component is shallowed', async () => {
const onOpenSpy = jest.fn();
// @ts-ignore strict null error, you shouldn't use promise like approach with act but I don't know what the intention is here
await act(async () => {
shallow(
<QueryOperationRow onOpen={onOpenSpy} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
});
expect(onOpenSpy).not.toBeCalled();
});
it('should call onOpen when row is opened and onClose when row is collapsed', async () => { it('should call onOpen when row is opened and onClose when row is collapsed', async () => {
const onOpenSpy = jest.fn(); const onOpenSpy = jest.fn();
const onCloseSpy = jest.fn(); const onCloseSpy = jest.fn();
const wrapper = mount( setup({ isOpen: false, onOpen: onOpenSpy, onClose: onCloseSpy });
<QueryOperationRow title="title" onOpen={onOpenSpy} onClose={onCloseSpy} isOpen={false} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
const titleEl = wrapper.find({ 'aria-label': 'Query operation row title' });
expect(titleEl).toHaveLength(1);
// @ts-ignore strict null error, you shouldn't use promise like approach with act but I don't know what the intention is here const queryRow = screen.getByText(/^test-title$/);
await act(async () => { expect(queryRow).toBeInTheDocument();
// open
titleEl.first().simulate('click');
});
// @ts-ignore strict null error, you shouldn't use promise like approach with act but I don't know what the intention is here // open row on click
await act(async () => { await userEvent.click(queryRow);
// close // close row on click
titleEl.first().simulate('click'); await userEvent.click(queryRow);
});
expect(onOpenSpy).toBeCalledTimes(1); expect(onOpenSpy).toBeCalledTimes(1);
expect(onCloseSpy).toBeCalledTimes(1); expect(onCloseSpy).toBeCalledTimes(1);
@ -59,40 +47,26 @@ describe('QueryOperationRow', () => {
describe('headerElement rendering', () => { describe('headerElement rendering', () => {
it('should render headerElement provided as element', () => { it('should render headerElement provided as element', () => {
const title = <div aria-label="test title">Test</div>; const title = <div aria-label="test title">test-header-element</div>;
const wrapper = mount( setup({ headerElement: title, id: 'test-id', index: 0 });
<QueryOperationRow headerElement={title} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
const titleEl = wrapper.find({ 'aria-label': 'test title' }); expect(screen.getByText(/^test-header-element$/)).toBeInTheDocument();
expect(titleEl).toHaveLength(1);
}); });
it('should render headerElement provided as function', () => { it('should render headerElement provided as function', () => {
const title = () => <div aria-label="test title">Test</div>; const title = () => <div aria-label="test title">test-function-header</div>;
const wrapper = mount( setup({ headerElement: title, id: 'test-id', index: 0 });
<QueryOperationRow headerElement={title} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
const titleEl = wrapper.find({ 'aria-label': 'test title' }); expect(screen.getByText(/^test-function-header$/)).toBeInTheDocument();
expect(titleEl).toHaveLength(1);
}); });
it('should expose api to headerElement rendered as function', () => { it('should expose api to headerElement rendered as function', () => {
const propsSpy = jest.fn(); const propsSpy = jest.fn();
const title = (props: any) => { const title = (props: Partial<QueryOperationRowProps>) => {
propsSpy(props); propsSpy(props);
return <div aria-label="test title">Test</div>; return <div aria-label="test title">Test</div>;
}; };
shallow( setup({ headerElement: title, id: 'test-id', index: 0 });
<QueryOperationRow headerElement={title} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
expect(Object.keys(propsSpy.mock.calls[0][0])).toContain('isOpen'); expect(Object.keys(propsSpy.mock.calls[0][0])).toContain('isOpen');
}); });
@ -100,40 +74,27 @@ describe('QueryOperationRow', () => {
describe('actions rendering', () => { describe('actions rendering', () => {
it('should render actions provided as element', () => { it('should render actions provided as element', () => {
const actions = <div aria-label="test actions">Test</div>; const actions = <div aria-label="test actions">test-actions</div>;
const wrapper = mount( setup({ actions: actions, id: 'test-id', index: 0 });
<QueryOperationRow actions={actions} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
const actionsEl = wrapper.find({ 'aria-label': 'test actions' }); expect(screen.getByText(/^test-actions$/)).toBeInTheDocument();
expect(actionsEl).toHaveLength(1);
}); });
it('should render actions provided as function', () => { it('should render actions provided as function', () => {
const actions = () => <div aria-label="test actions">Test</div>; const actions = () => <div aria-label="test actions">test-actions</div>;
const wrapper = mount( setup({ actions: actions, id: 'test-id', index: 0 });
<QueryOperationRow actions={actions} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
const actionsEl = wrapper.find({ 'aria-label': 'test actions' }); expect(screen.getByText(/^test-actions$/)).toBeInTheDocument();
expect(actionsEl).toHaveLength(1);
}); });
it('should expose api to title rendered as function', () => { it('should expose api to title rendered as function', () => {
const propsSpy = jest.fn(); const propsSpy = jest.fn();
const actions = (props: any) => { const actions = (props: Partial<QueryOperationRowProps>) => {
propsSpy(props); propsSpy(props);
return <div aria-label="test actions">Test</div>; return <div aria-label="test actions">test-actions</div>;
}; };
shallow( setup({ actions: actions, id: 'test-id', index: 0 });
<QueryOperationRow actions={actions} id="test-id" index={0}>
<div>Test</div>
</QueryOperationRow>
);
expect(screen.getByText(/^test-actions$/)).toBeInTheDocument();
expect(Object.keys(propsSpy.mock.calls[0][0])).toEqual(['isOpen', 'onOpen', 'onClose']); expect(Object.keys(propsSpy.mock.calls[0][0])).toEqual(['isOpen', 'onOpen', 'onClose']);
}); });
}); });

View File

@ -9,7 +9,7 @@ import { ReactUtils, stylesFactory, useTheme } from '@grafana/ui';
import { QueryOperationRowHeader } from './QueryOperationRowHeader'; import { QueryOperationRowHeader } from './QueryOperationRowHeader';
interface QueryOperationRowProps { export interface QueryOperationRowProps {
index: number; index: number;
id: string; id: string;
title?: string; title?: string;