Remove enzyme from links

This commit is contained in:
Clément DUNGLER 2020-11-03 23:29:12 +01:00
parent ffcd6fe938
commit 390b8332ab
7 changed files with 76 additions and 91 deletions

View File

@ -45,8 +45,7 @@
"ts-dedent": "^2.0.0"
},
"devDependencies": {
"@types/webpack-env": "^1.15.2",
"enzyme": "^3.11.0"
"@types/webpack-env": "^1.15.2"
},
"publishConfig": {
"access": "public"

View File

@ -32,11 +32,13 @@ jest.mock('global', () => ({
},
}));
const mockAddons = (addons as unknown) as jest.Mocked<typeof addons>;
describe('preview', () => {
describe('linkTo()', () => {
it('should select the kind and story provided', () => {
const channel = { emit: jest.fn() };
addons.getChannel.mockReturnValue(channel);
const channel = { emit: jest.fn() } as any;
mockAddons.getChannel.mockReturnValue(channel);
const handler = linkTo('kind', 'name');
handler();
@ -48,9 +50,9 @@ describe('preview', () => {
});
it('should select the kind (only) provided', () => {
const channel = { emit: jest.fn() };
addons.getChannel.mockReturnValue(channel);
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) => null);
const channel = { emit: jest.fn() } as any;
mockAddons.getChannel.mockReturnValue(channel);
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((): any => null);
const handler = linkTo('kind');
handler();
@ -62,10 +64,10 @@ describe('preview', () => {
});
it('should select the story (only) provided', () => {
const channel = { emit: jest.fn() };
addons.getChannel.mockReturnValue(channel);
const channel = { emit: jest.fn() } as any;
mockAddons.getChannel.mockReturnValue(channel);
// simulate a currently selected, but not found as ID
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) =>
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input: any) =>
!input
? {
kind: 'kind',
@ -84,9 +86,9 @@ describe('preview', () => {
});
it('should select the id provided', () => {
const channel = { emit: jest.fn() };
addons.getChannel.mockReturnValue(channel);
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) =>
const channel = { emit: jest.fn() } as any;
mockAddons.getChannel.mockReturnValue(channel);
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input: any) =>
input === 'kind--story'
? {
story: 'name',
@ -105,11 +107,12 @@ describe('preview', () => {
});
it('should handle functions returning strings', () => {
const channel = { emit: jest.fn() };
addons.getChannel.mockReturnValue(channel);
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input) => null);
const channel = { emit: jest.fn() } as any;
mockAddons.getChannel.mockReturnValue(channel);
__STORYBOOK_STORY_STORE__.fromId.mockImplementation((input: any): any => null);
const handler = linkTo(
// @ts-expect-error
(a, b) => a + b,
(a, b) => b + a
);

View File

@ -1,50 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
// NOTE: this is a copy of `lib/components/src/navigation/RoutedLink.js`.
// It's duplicated here because that copy has an explicit dependency on
// React 16.3+, which breaks older versions of React running in the preview.
// The proper DRY solution is to create a new package that doesn't depend
// on a specific react version. However, that's a heavy-handed solution for
// one trivial file.
const LEFT_BUTTON = 0;
// Cmd/Ctrl/Shift/Alt + Click should trigger default browser behaviour. Same applies to non-left clicks
const isPlainLeftClick = (e) =>
e.button === LEFT_BUTTON && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey;
export default class RoutedLink extends React.Component {
onClick = (e) => {
const { onClick } = this.props;
if (isPlainLeftClick(e)) {
e.preventDefault();
onClick(e);
}
};
render() {
const { href, children, onClick, className, style } = this.props;
const props = onClick
? { href, className, style, onClick: this.onClick }
: { href, className, style };
return <a {...props}>{children}</a>;
}
}
RoutedLink.defaultProps = {
onClick: null,
href: '#',
children: null,
className: undefined,
style: undefined,
};
RoutedLink.propTypes = {
onClick: PropTypes.func,
href: PropTypes.string,
children: PropTypes.node,
className: PropTypes.string,
// eslint-disable-next-line react/forbid-prop-types
style: PropTypes.object,
};

View File

@ -0,0 +1,32 @@
import React from 'react';
// NOTE: this is a copy of `lib/components/src/navigation/RoutedLink.js`.
// It's duplicated here because that copy has an explicit dependency on
// React 16.3+, which breaks older versions of React running in the preview.
// The proper DRY solution is to create a new package that doesn't depend
// on a specific react version. However, that's a heavy-handed solution for
// one trivial file.
const LEFT_BUTTON = 0;
// Cmd/Ctrl/Shift/Alt + Click should trigger default browser behaviour. Same applies to non-left clicks
const isPlainLeftClick = (e: React.MouseEvent) =>
e.button === LEFT_BUTTON && !e.altKey && !e.ctrlKey && !e.metaKey && !e.shiftKey;
const RoutedLink: React.FC<React.DetailedHTMLProps<
React.AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
>> = ({ href = '#', children, onClick, className, style }) => {
const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
if (isPlainLeftClick(e)) {
e.preventDefault();
onClick(e);
}
};
const props = onClick
? { href, className, style, onClick: handleClick }
: { href, className, style };
return <a {...props}>{children}</a>;
};
export default RoutedLink;

View File

@ -1,8 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`LinkTo render should render a link 1`] = `
<a
href="originpathname?search=&id=foo--bar"
onClick={[Function]}
/>
`;

View File

@ -1,7 +1,7 @@
import { shallow } from 'enzyme';
import React from 'react';
import addons from '@storybook/addons';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { SELECT_STORY } from '@storybook/core-events';
import LinkTo from './link';
@ -28,17 +28,21 @@ const mockChannel = () => {
once: jest.fn(),
};
};
const mockAddons = (addons as unknown) as jest.Mocked<typeof addons>;
describe('LinkTo', () => {
describe('render', () => {
it('should render a link', async () => {
const channel = mockChannel();
addons.getChannel.mockReturnValue(channel);
const channel = mockChannel() as any;
mockAddons.getChannel.mockReturnValue(channel);
const wrapper = shallow(<LinkTo kind="foo" story="bar" />);
await wrapper.instance().updateHref(wrapper.props());
wrapper.update();
expect(wrapper).toMatchSnapshot();
const { container } = render(<LinkTo kind="foo" story="bar" />);
expect(container.firstChild).toMatchInlineSnapshot(`
<a
href="/"
/>
`);
});
});
@ -47,18 +51,23 @@ describe('LinkTo', () => {
const channel = {
emit: jest.fn(),
on: jest.fn(),
};
addons.getChannel.mockReturnValue(channel);
} as any;
mockAddons.getChannel.mockReturnValue(channel);
const wrapper = shallow(<LinkTo kind="foo" story="bar" />);
wrapper.simulate('click', { button: 0, preventDefault: () => {} });
expect(channel.emit.mock.calls).toContainEqual([
render(
<LinkTo kind="foo" story="bar">
link
</LinkTo>
);
userEvent.click(screen.getByText('link'));
expect(channel.emit).toHaveBeenLastCalledWith(
SELECT_STORY,
{
expect.objectContaining({
kind: 'foo',
story: 'bar',
},
]);
})
);
});
});
});

View File

@ -2,7 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"types": ["webpack-env"]
"types": ["webpack-env", "@testing-library/jest-dom"]
},
"include": [
"src/**/*"