Adds tests and storybook to CopyToClipboard component (#13359)
This commit is contained in:
parent
7d270bced6
commit
e9d5d3b137
|
|
@ -21,18 +21,34 @@ import { addDecorator } from '@storybook/react';
|
|||
import { jsxDecorator } from 'storybook-addon-jsx';
|
||||
import { addParameters } from '@storybook/react';
|
||||
import { withPaddings } from 'storybook-addon-paddings';
|
||||
|
||||
import { supersetTheme, ThemeProvider } from '@superset-ui/core';
|
||||
import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
|
||||
import thunk from 'redux-thunk';
|
||||
import { Provider } from 'react-redux';
|
||||
import reducerIndex from 'spec/helpers/reducerIndex';
|
||||
|
||||
import '../src/theme.ts';
|
||||
import 'src/theme.ts';
|
||||
import './storybook.css';
|
||||
|
||||
const store = createStore(
|
||||
combineReducers(reducerIndex),
|
||||
{},
|
||||
compose(applyMiddleware(thunk)),
|
||||
);
|
||||
|
||||
const themeDecorator = Story => (
|
||||
<ThemeProvider theme={supersetTheme}>{<Story />}</ThemeProvider>
|
||||
);
|
||||
|
||||
const providerDecorator = Story => (
|
||||
<Provider store={store}>
|
||||
<Story />
|
||||
</Provider>
|
||||
);
|
||||
|
||||
addDecorator(jsxDecorator);
|
||||
addDecorator(themeDecorator);
|
||||
addDecorator(providerDecorator);
|
||||
addDecorator(withPaddings);
|
||||
|
||||
addParameters({
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License 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 React from 'react';
|
||||
|
||||
import CopyToClipboard from 'src/components/CopyToClipboard';
|
||||
|
||||
describe('CopyToClipboard', () => {
|
||||
const defaultProps = {
|
||||
text: 'some text to copy',
|
||||
};
|
||||
|
||||
it('renders', () => {
|
||||
expect(React.isValidElement(<CopyToClipboard {...defaultProps} />)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -62,10 +62,10 @@ InteractiveCollapse.argTypes = {
|
|||
InteractiveCollapse.story = {
|
||||
parameters: {
|
||||
actions: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export const InteractiveTooltip = (args: TooltipProps) => (
|
|||
InteractiveTooltip.story = {
|
||||
parameters: {
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,13 +63,13 @@ export const AlertGallery = () => (
|
|||
AlertGallery.story = {
|
||||
parameters: {
|
||||
actions: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
controls: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -94,7 +94,7 @@ InteractiveAlert.argTypes = {
|
|||
InteractiveAlert.story = {
|
||||
parameters: {
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ export const AsyncAceEditor = (
|
|||
AsyncAceEditor.args = {
|
||||
defaultTabSize: 2,
|
||||
width: '100%',
|
||||
height: 500,
|
||||
height: '500px',
|
||||
value: `{"text": "Simple text"}`,
|
||||
};
|
||||
|
||||
|
|
@ -99,10 +99,10 @@ AsyncAceEditor.argTypes = {
|
|||
AsyncAceEditor.story = {
|
||||
parameters: {
|
||||
actions: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -98,13 +98,13 @@ export const ButtonGallery = () => (
|
|||
ButtonGallery.story = {
|
||||
parameters: {
|
||||
actions: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
controls: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -117,7 +117,7 @@ export const InteractiveButton = (args: ButtonProps & { label: string }) => {
|
|||
InteractiveButton.story = {
|
||||
parameters: {
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ InteractiveButtonGroup.argTypes = {
|
|||
InteractiveButtonGroup.story = {
|
||||
parameters: {
|
||||
actions: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License 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 React from 'react';
|
||||
import Button from 'src/components/Button';
|
||||
import Icon from 'src/components/Icon';
|
||||
import ToastPresenter from 'src/messageToasts/containers/ToastPresenter';
|
||||
import CopyToClipboard from '.';
|
||||
|
||||
export default {
|
||||
title: 'CopyToClipboard',
|
||||
component: CopyToClipboard,
|
||||
};
|
||||
|
||||
export const InteractiveCopyToClipboard = ({ copyNode, ...rest }: any) => {
|
||||
let node = <Button>Copy</Button>;
|
||||
if (copyNode === 'Icon') {
|
||||
node = <Icon name="copy" />;
|
||||
} else if (copyNode === 'Text') {
|
||||
node = <span role="button">Copy</span>;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<CopyToClipboard copyNode={node} {...rest} />
|
||||
<ToastPresenter />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
InteractiveCopyToClipboard.args = {
|
||||
shouldShowText: true,
|
||||
text: 'http://superset.apache.org/',
|
||||
wrapped: true,
|
||||
tooltipText: 'Copy to clipboard',
|
||||
};
|
||||
|
||||
InteractiveCopyToClipboard.argTypes = {
|
||||
onCopyEnd: { action: 'onCopyEnd' },
|
||||
copyNode: {
|
||||
defaultValue: 'Button',
|
||||
control: { type: 'radio', options: ['Button', 'Icon', 'Text'] },
|
||||
},
|
||||
};
|
||||
|
||||
InteractiveCopyToClipboard.story = {
|
||||
parameters: {
|
||||
knobs: {
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License 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 React from 'react';
|
||||
import { render, screen, waitFor } from 'spec/helpers/testing-library';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import CopyToClipboard from '.';
|
||||
|
||||
test('renders with default props', () => {
|
||||
const text = 'Text';
|
||||
render(<CopyToClipboard text={text} />, { useRedux: true });
|
||||
expect(screen.getByText(text)).toBeInTheDocument();
|
||||
expect(screen.getByText('Copy')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders with custom copy node', () => {
|
||||
const copyNode = <a href="/">Custom node</a>;
|
||||
render(<CopyToClipboard copyNode={copyNode} />, { useRedux: true });
|
||||
expect(screen.getByRole('link')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('renders without text showing', () => {
|
||||
const text = 'Text';
|
||||
render(<CopyToClipboard text={text} shouldShowText={false} />, {
|
||||
useRedux: true,
|
||||
});
|
||||
expect(screen.queryByText(text)).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('getText on copy', async () => {
|
||||
const getText = jest.fn(() => 'Text');
|
||||
render(<CopyToClipboard getText={getText} />, { useRedux: true });
|
||||
userEvent.click(screen.getByText('Copy'));
|
||||
await waitFor(() => expect(getText).toHaveBeenCalled());
|
||||
});
|
||||
|
||||
test('renders tooltip on hover', async () => {
|
||||
const tooltipText = 'Tooltip';
|
||||
render(<CopyToClipboard tooltipText={tooltipText} />, { useRedux: true });
|
||||
userEvent.hover(screen.getByText('Copy'));
|
||||
const tooltip = await screen.findByRole('tooltip');
|
||||
expect(tooltip).toBeInTheDocument();
|
||||
expect(tooltip).toHaveTextContent(tooltipText);
|
||||
});
|
||||
|
||||
test('triggers onCopyEnd', async () => {
|
||||
const onCopyEnd = jest.fn();
|
||||
render(<CopyToClipboard onCopyEnd={onCopyEnd} />, {
|
||||
useRedux: true,
|
||||
});
|
||||
userEvent.click(screen.getByText('Copy'));
|
||||
await waitFor(() => expect(onCopyEnd).toHaveBeenCalled());
|
||||
});
|
||||
|
||||
test('renders unwrapped', () => {
|
||||
const text = 'Text';
|
||||
render(<CopyToClipboard text={text} wrapped={false} />, {
|
||||
useRedux: true,
|
||||
});
|
||||
expect(screen.queryByText(text)).not.toBeInTheDocument();
|
||||
});
|
||||
|
|
@ -102,7 +102,7 @@ class CopyToClipboard extends React.Component {
|
|||
|
||||
renderLink() {
|
||||
return (
|
||||
<span>
|
||||
<span css={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||
{this.props.shouldShowText && this.props.text && (
|
||||
<span className="m-r-5" data-test="short-url">
|
||||
{this.props.text}
|
||||
|
|
@ -49,13 +49,13 @@ export const LoadingGallery = () => (
|
|||
LoadingGallery.story = {
|
||||
parameters: {
|
||||
actions: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
controls: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -65,7 +65,7 @@ export const InteractiveLoading = (args: Props) => <Loading {...args} />;
|
|||
InteractiveLoading.story = {
|
||||
parameters: {
|
||||
knobs: {
|
||||
disabled: true,
|
||||
disable: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue