test: Adds tests to URLShortLinkButton component (#13319)

This commit is contained in:
Michael S. Molina 2021-02-25 15:59:36 -03:00 committed by GitHub
parent 8395b3d6c8
commit 72721845e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 167 additions and 56 deletions

View File

@ -0,0 +1,55 @@
/**
* 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 charts from 'src/chart/chartReducer';
import dashboardInfo from 'src/dashboard/reducers/dashboardInfo';
import dashboardState from 'src/dashboard/reducers/dashboardState';
import dashboardFilters from 'src/dashboard/reducers/dashboardFilters';
import nativeFilters from 'src/dashboard/reducers/nativeFilters';
import datasources from 'src/dashboard/reducers/datasources';
import sliceEntities from 'src/dashboard/reducers/sliceEntities';
import dashboardLayout from 'src/dashboard/reducers/undoableDashboardLayout';
import messageToasts from 'src/messageToasts/reducers';
import saveModal from 'src/explore/reducers/saveModalReducer';
import explore from 'src/explore/reducers/exploreReducer';
import sqlLab from 'src/SqlLab/reducers/sqlLab';
import localStorageUsageInKilobytes from 'src/SqlLab/reducers/localStorageUsage';
const impressionId = (state = '') => state;
const container = document.getElementById('app');
const bootstrap = JSON.parse(container?.getAttribute('data-bootstrap') ?? '{}');
const common = { ...bootstrap.common };
export default {
charts,
datasources,
dashboardInfo,
dashboardFilters,
nativeFilters,
dashboardState,
dashboardLayout,
impressionId,
messageToasts,
sliceEntities,
saveModal,
explore,
sqlLab,
localStorageUsageInKilobytes,
common,
};

View File

@ -20,15 +20,41 @@ import '@testing-library/jest-dom/extend-expect';
import React, { ReactNode, ReactElement } from 'react';
import { render, RenderOptions } from '@testing-library/react';
import { ThemeProvider, supersetTheme } from '@superset-ui/core';
import { Provider } from 'react-redux';
import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import reducerIndex from 'spec/helpers/reducerIndex';
function SupersetProviders({ children }: { children?: ReactNode }) {
return <ThemeProvider theme={supersetTheme}>{children}</ThemeProvider>;
type Options = Omit<RenderOptions, 'queries'> & {
useRedux?: boolean;
initialState?: {};
reducers?: {};
};
function createWrapper(options?: Options) {
const { useRedux, initialState, reducers } = options || {};
if (useRedux) {
const store = createStore(
combineReducers(reducers || reducerIndex),
initialState || {},
compose(applyMiddleware(thunk)),
);
return ({ children }: { children?: ReactNode }) => (
<Provider store={store}>
<ThemeProvider theme={supersetTheme}>{children}</ThemeProvider>
</Provider>
);
}
return ({ children }: { children?: ReactNode }) => (
<ThemeProvider theme={supersetTheme}>{children}</ThemeProvider>
);
}
const customRender = (
ui: ReactElement,
options?: Omit<RenderOptions, 'queries'>,
) => render(ui, { wrapper: SupersetProviders, ...options });
const customRender = (ui: ReactElement, options?: Options) =>
render(ui, { wrapper: createWrapper(options), ...options });
export function sleep(time: number) {
return new Promise(resolve => {

View File

@ -1,45 +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 configureStore from 'redux-mock-store';
import { shallow } from 'enzyme';
import Popover from 'src/common/components/Popover';
import URLShortLinkButton from 'src/components/URLShortLinkButton';
describe('URLShortLinkButton', () => {
const defaultProps = {
url: 'mockURL',
emailSubject: 'Mock Subject',
emailContent: 'mock content',
};
function setup() {
const mockStore = configureStore([]);
const store = mockStore({});
return shallow(
<URLShortLinkButton store={store} {...defaultProps} />,
).dive();
}
it('renders OverlayTrigger', () => {
const wrapper = setup();
expect(wrapper.find(Popover)).toExist();
});
});

View File

@ -134,7 +134,7 @@ describe('Tabs', () => {
const wrapper = setup({ editMode: true, onChangeTab });
wrapper
.find(
'[data-test="dashboard-component-tabs"] .ant-tabs-tab [data-test="short-link-button"]',
'[data-test="dashboard-component-tabs"] .ant-tabs-tab [role="button"]',
)
.at(1) // will not call if it is already selected
.simulate('click');

View File

@ -0,0 +1,74 @@
/**
* 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 } from 'spec/helpers/testing-library';
import userEvent from '@testing-library/user-event';
import fetchMock from 'fetch-mock';
import URLShortLinkButton from 'src/components/URLShortLinkButton';
import ToastPresenter from 'src/messageToasts/containers/ToastPresenter';
const fakeUrl = 'http://fakeurl.com';
fetchMock.post('glob:*/r/shortner/', fakeUrl);
test('renders with default props', () => {
render(<URLShortLinkButton />, { useRedux: true });
expect(screen.getByRole('button')).toBeInTheDocument();
});
test('renders overlay on click', async () => {
render(<URLShortLinkButton />, { useRedux: true });
userEvent.click(screen.getByRole('button'));
expect(await screen.findByRole('tooltip')).toBeInTheDocument();
});
test('obtains short url', async () => {
render(<URLShortLinkButton />, { useRedux: true });
userEvent.click(screen.getByRole('button'));
expect(await screen.findByRole('tooltip')).toHaveTextContent(fakeUrl);
});
test('creates email anchor', async () => {
const subject = 'Subject';
const content = 'Content';
render(<URLShortLinkButton emailSubject={subject} emailContent={content} />, {
useRedux: true,
});
const href = `mailto:?Subject=${subject}%20&Body=${content}${fakeUrl}`;
userEvent.click(screen.getByRole('button'));
expect(await screen.findByRole('link')).toHaveAttribute('href', href);
});
test('renders error message on short url error', async () => {
fetchMock.mock('glob:*/r/shortner/', 500, {
overwriteRoutes: true,
});
render(
<>
<URLShortLinkButton />
<ToastPresenter />
</>,
{ useRedux: true },
);
userEvent.click(screen.getByRole('button'));
expect(await screen.findByRole('alert')).toBeInTheDocument();
});

View File

@ -20,9 +20,9 @@ import React from 'react';
import PropTypes from 'prop-types';
import { t } from '@superset-ui/core';
import Popover from 'src/common/components/Popover';
import CopyToClipboard from './CopyToClipboard';
import { getShortUrl } from '../utils/urlUtils';
import withToasts from '../messageToasts/enhancers/withToasts';
import CopyToClipboard from 'src/components/CopyToClipboard';
import { getShortUrl } from 'src/utils/urlUtils';
import withToasts from 'src/messageToasts/enhancers/withToasts';
const propTypes = {
url: PropTypes.string,
@ -85,7 +85,7 @@ class URLShortLinkButton extends React.Component {
>
<span
className="short-link-trigger btn btn-default btn-sm"
data-test="short-link-button"
role="button"
>
<i className="short-link-trigger fa fa-link" />
&nbsp;

View File

@ -93,6 +93,7 @@ export default function Toast({ toast, onCloseToast }: ToastPresenterProps) {
<ToastContainer
className={cx('alert', 'toast', visible && 'toast--visible', className)}
data-test="toast-container"
role="alert"
>
<StyledIcon name={iconName} />
<Interweave content={toast.text} />