Merge pull request #195 from acelaya-forks/feature/server-version-wrapper

Feature/server version wrapper
This commit is contained in:
Alejandro Celaya 2020-01-28 19:55:24 +01:00 committed by GitHub
commit cf4e8190a4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 136 additions and 132 deletions

View file

@ -12,7 +12,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
#### Changed #### Changed
* *Nothing* * [#191](https://github.com/shlinkio/shlink-web-client/issues/191) Created `ForServerVersion` helper component which dynamically renders children if current server conditions are met.
#### Deprecated #### Deprecated

View file

@ -20,7 +20,7 @@ const mapActionService = (map, actionName) => ({
// Wrap actual action service in a function so that it is lazily created the first time it is called // Wrap actual action service in a function so that it is lazily created the first time it is called
[actionName]: lazyService(container, actionName), [actionName]: lazyService(container, actionName),
}); });
const connect = (propsFromState, actionServiceNames) => const connect = (propsFromState, actionServiceNames = []) =>
reduxConnect( reduxConnect(
propsFromState ? pick(propsFromState) : null, propsFromState ? pick(propsFromState) : null,
actionServiceNames.reduce(mapActionService, {}) actionServiceNames.reduce(mapActionService, {})

View file

@ -0,0 +1,31 @@
import React from 'react';
import PropTypes from 'prop-types';
import { compareVersions } from '../../utils/utils';
import { serverType } from '../prop-types';
const propTypes = {
minVersion: PropTypes.string,
maxVersion: PropTypes.string,
selectedServer: serverType,
children: PropTypes.node.isRequired,
};
const ForServerVersion = ({ minVersion, maxVersion, selectedServer, children }) => {
if (!selectedServer) {
return null;
}
const { version } = selectedServer;
const matchesMinVersion = !minVersion || compareVersions(version, '>=', minVersion);
const matchesMaxVersion = !maxVersion || compareVersions(version, '<=', maxVersion);
if (!matchesMinVersion || !matchesMaxVersion) {
return null;
}
return <React.Fragment>{children}</React.Fragment>;
};
ForServerVersion.propTypes = propTypes;
export default ForServerVersion;

View file

@ -5,4 +5,5 @@ export const serverType = PropTypes.shape({
name: PropTypes.string, name: PropTypes.string,
url: PropTypes.string, url: PropTypes.string,
apiKey: PropTypes.string, apiKey: PropTypes.string,
version: PropTypes.string,
}); });

View file

@ -6,6 +6,7 @@ import DeleteServerButton from '../DeleteServerButton';
import ImportServersBtn from '../helpers/ImportServersBtn'; import ImportServersBtn from '../helpers/ImportServersBtn';
import { resetSelectedServer, selectServer } from '../reducers/selectedServer'; import { resetSelectedServer, selectServer } from '../reducers/selectedServer';
import { createServer, createServers, deleteServer, listServers } from '../reducers/server'; import { createServer, createServers, deleteServer, listServers } from '../reducers/server';
import ForServerVersion from '../helpers/ForServerVersion';
import ServersImporter from './ServersImporter'; import ServersImporter from './ServersImporter';
import ServersService from './ServersService'; import ServersService from './ServersService';
import ServersExporter from './ServersExporter'; import ServersExporter from './ServersExporter';
@ -28,6 +29,9 @@ const provideServices = (bottle, connect, withRouter) => {
bottle.serviceFactory('ImportServersBtn', ImportServersBtn, 'ServersImporter'); bottle.serviceFactory('ImportServersBtn', ImportServersBtn, 'ServersImporter');
bottle.decorator('ImportServersBtn', connect(null, [ 'createServers' ])); bottle.decorator('ImportServersBtn', connect(null, [ 'createServers' ]));
bottle.serviceFactory('ForServerVersion', () => ForServerVersion);
bottle.decorator('ForServerVersion', connect([ 'selectedServer' ]));
// Services // Services
bottle.constant('csvjson', csvjson); bottle.constant('csvjson', csvjson);
bottle.service('ServersImporter', ServersImporter, 'csvjson'); bottle.service('ServersImporter', ServersImporter, 'csvjson');

View file

@ -6,7 +6,6 @@ import { Collapse, FormGroup, Input } from 'reactstrap';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import DateInput from '../utils/DateInput'; import DateInput from '../utils/DateInput';
import Checkbox from '../utils/Checkbox'; import Checkbox from '../utils/Checkbox';
import ForVersion from '../utils/ForVersion';
import { serverType } from '../servers/prop-types'; import { serverType } from '../servers/prop-types';
import { compareVersions } from '../utils/utils'; import { compareVersions } from '../utils/utils';
import { createShortUrlResultType } from './reducers/shortUrlCreation'; import { createShortUrlResultType } from './reducers/shortUrlCreation';
@ -15,7 +14,11 @@ import UseExistingIfFoundInfoIcon from './UseExistingIfFoundInfoIcon';
const normalizeTag = pipe(trim, replace(/ /g, '-')); const normalizeTag = pipe(trim, replace(/ /g, '-'));
const formatDate = (date) => isNil(date) ? date : date.format(); const formatDate = (date) => isNil(date) ? date : date.format();
const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShortUrl extends React.Component { const CreateShortUrl = (
TagsSelector,
CreateShortUrlResult,
ForServerVersion
) => class CreateShortUrl extends React.Component {
static propTypes = { static propTypes = {
createShortUrl: PropTypes.func, createShortUrl: PropTypes.func,
shortUrlCreationResult: createShortUrlResultType, shortUrlCreationResult: createShortUrlResultType,
@ -116,7 +119,7 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShort
</div> </div>
</div> </div>
<ForVersion minVersion="1.16.0" currentServerVersion={currentServerVersion}> <ForServerVersion minVersion="1.16.0">
<div className="mb-4 text-right"> <div className="mb-4 text-right">
<Checkbox <Checkbox
className="mr-2" className="mr-2"
@ -127,7 +130,7 @@ const CreateShortUrl = (TagsSelector, CreateShortUrlResult) => class CreateShort
</Checkbox> </Checkbox>
<UseExistingIfFoundInfoIcon /> <UseExistingIfFoundInfoIcon />
</div> </div>
</ForVersion> </ForServerVersion>
</Collapse> </Collapse>
<div> <div>

View file

@ -7,23 +7,19 @@ import moment from 'moment';
import SearchField from '../utils/SearchField'; import SearchField from '../utils/SearchField';
import Tag from '../tags/helpers/Tag'; import Tag from '../tags/helpers/Tag';
import DateRangeRow from '../utils/DateRangeRow'; import DateRangeRow from '../utils/DateRangeRow';
import { compareVersions, formatDate } from '../utils/utils'; import { formatDate } from '../utils/utils';
import { serverType } from '../servers/prop-types';
import { shortUrlsListParamsType } from './reducers/shortUrlsListParams'; import { shortUrlsListParamsType } from './reducers/shortUrlsListParams';
import './SearchBar.scss'; import './SearchBar.scss';
const propTypes = { const propTypes = {
listShortUrls: PropTypes.func, listShortUrls: PropTypes.func,
shortUrlsListParams: shortUrlsListParamsType, shortUrlsListParams: shortUrlsListParamsType,
selectedServer: serverType,
}; };
const dateOrUndefined = (date) => date ? moment(date) : undefined; const dateOrUndefined = (date) => date ? moment(date) : undefined;
const SearchBar = (colorGenerator) => { const SearchBar = (colorGenerator, ForServerVersion) => {
const SearchBar = ({ listShortUrls, shortUrlsListParams, selectedServer }) => { const SearchBar = ({ listShortUrls, shortUrlsListParams }) => {
const currentServerVersion = selectedServer ? selectedServer.version : '';
const enableDateFiltering = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '>=', '1.21.0');
const selectedTags = shortUrlsListParams.tags || []; const selectedTags = shortUrlsListParams.tags || [];
const setDate = (dateName) => pipe( const setDate = (dateName) => pipe(
formatDate(), formatDate(),
@ -38,7 +34,7 @@ const SearchBar = (colorGenerator) => {
} }
/> />
{enableDateFiltering && ( <ForServerVersion minVersion="1.21.0">
<div className="mt-3"> <div className="mt-3">
<DateRangeRow <DateRangeRow
startDate={dateOrUndefined(shortUrlsListParams.startDate)} startDate={dateOrUndefined(shortUrlsListParams.startDate)}
@ -47,7 +43,7 @@ const SearchBar = (colorGenerator) => {
onEndDateChange={setDate('endDate')} onEndDateChange={setDate('endDate')}
/> />
</div> </div>
)} </ForServerVersion>
{!isEmpty(selectedTags) && ( {!isEmpty(selectedTags) && (
<h4 className="search-bar__selected-tag mt-3"> <h4 className="search-bar__selected-tag mt-3">

View file

@ -13,9 +13,7 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap'; import { ButtonDropdown, DropdownItem, DropdownMenu, DropdownToggle } from 'reactstrap';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { isEmpty } from 'ramda';
import { serverType } from '../../servers/prop-types'; import { serverType } from '../../servers/prop-types';
import { compareVersions } from '../../utils/utils';
import { shortUrlType } from '../reducers/shortUrlsList'; import { shortUrlType } from '../reducers/shortUrlsList';
import PreviewModal from './PreviewModal'; import PreviewModal from './PreviewModal';
import QrCodeModal from './QrCodeModal'; import QrCodeModal from './QrCodeModal';
@ -24,7 +22,8 @@ import './ShortUrlsRowMenu.scss';
const ShortUrlsRowMenu = ( const ShortUrlsRowMenu = (
DeleteShortUrlModal, DeleteShortUrlModal,
EditTagsModal, EditTagsModal,
EditMetaModal EditMetaModal,
ForServerVersion
) => class ShortUrlsRowMenu extends React.Component { ) => class ShortUrlsRowMenu extends React.Component {
static propTypes = { static propTypes = {
onCopyToClipboard: PropTypes.func, onCopyToClipboard: PropTypes.func,
@ -45,9 +44,6 @@ const ShortUrlsRowMenu = (
render() { render() {
const { onCopyToClipboard, shortUrl, selectedServer } = this.props; const { onCopyToClipboard, shortUrl, selectedServer } = this.props;
const completeShortUrl = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : ''; const completeShortUrl = shortUrl && shortUrl.shortUrl ? shortUrl.shortUrl : '';
const currentServerVersion = selectedServer ? selectedServer.version : '';
const showEditMetaBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '>=', '1.18.0');
const showPreviewBtn = !isEmpty(currentServerVersion) && compareVersions(currentServerVersion, '<', '2.0.0');
const toggleModal = (prop) => () => this.setState((prevState) => ({ [prop]: !prevState[prop] })); const toggleModal = (prop) => () => this.setState((prevState) => ({ [prop]: !prevState[prop] }));
const toggleQrCode = toggleModal('isQrModalOpen'); const toggleQrCode = toggleModal('isQrModalOpen');
const togglePreview = toggleModal('isPreviewModalOpen'); const togglePreview = toggleModal('isPreviewModalOpen');
@ -70,14 +66,12 @@ const ShortUrlsRowMenu = (
</DropdownItem> </DropdownItem>
<EditTagsModal shortUrl={shortUrl} isOpen={this.state.isTagsModalOpen} toggle={toggleTags} /> <EditTagsModal shortUrl={shortUrl} isOpen={this.state.isTagsModalOpen} toggle={toggleTags} />
{showEditMetaBtn && ( <ForServerVersion minVersion="1.18.0">
<React.Fragment> <DropdownItem onClick={toggleMeta}>
<DropdownItem onClick={toggleMeta}> <FontAwesomeIcon icon={editIcon} fixedWidth /> Edit metadata
<FontAwesomeIcon icon={editIcon} fixedWidth /> Edit metadata </DropdownItem>
</DropdownItem> <EditMetaModal shortUrl={shortUrl} isOpen={this.state.isMetaModalOpen} toggle={toggleMeta} />
<EditMetaModal shortUrl={shortUrl} isOpen={this.state.isMetaModalOpen} toggle={toggleMeta} /> </ForServerVersion>
</React.Fragment>
)}
<DropdownItem className="short-urls-row-menu__dropdown-item--danger" onClick={toggleDelete}> <DropdownItem className="short-urls-row-menu__dropdown-item--danger" onClick={toggleDelete}>
<FontAwesomeIcon icon={deleteIcon} fixedWidth /> Delete short URL <FontAwesomeIcon icon={deleteIcon} fixedWidth /> Delete short URL
@ -86,21 +80,21 @@ const ShortUrlsRowMenu = (
<DropdownItem divider /> <DropdownItem divider />
{showPreviewBtn && ( <ForServerVersion maxVersion="1.x">
<React.Fragment> <DropdownItem onClick={togglePreview}>
<DropdownItem onClick={togglePreview}> <FontAwesomeIcon icon={pictureIcon} fixedWidth /> Preview
<FontAwesomeIcon icon={pictureIcon} fixedWidth /> Preview </DropdownItem>
</DropdownItem> <PreviewModal url={completeShortUrl} isOpen={this.state.isPreviewModalOpen} toggle={togglePreview} />
<PreviewModal url={completeShortUrl} isOpen={this.state.isPreviewModalOpen} toggle={togglePreview} /> </ForServerVersion>
</React.Fragment>
)}
<DropdownItem onClick={toggleQrCode}> <DropdownItem onClick={toggleQrCode}>
<FontAwesomeIcon icon={qrIcon} fixedWidth /> QR code <FontAwesomeIcon icon={qrIcon} fixedWidth /> QR code
</DropdownItem> </DropdownItem>
<QrCodeModal url={completeShortUrl} isOpen={this.state.isQrModalOpen} toggle={toggleQrCode} /> <QrCodeModal url={completeShortUrl} isOpen={this.state.isQrModalOpen} toggle={toggleQrCode} />
{showPreviewBtn && <DropdownItem divider />} <ForServerVersion maxVersion="1.x">
<DropdownItem divider />
</ForServerVersion>
<CopyToClipboard text={completeShortUrl} onCopy={onCopyToClipboard}> <CopyToClipboard text={completeShortUrl} onCopy={onCopyToClipboard}>
<DropdownItem> <DropdownItem>

View file

@ -24,8 +24,8 @@ const provideServices = (bottle, connect) => {
(state) => assoc('shortUrlsList', state.shortUrlsList.shortUrls, state.shortUrlsList) (state) => assoc('shortUrlsList', state.shortUrlsList.shortUrls, state.shortUrlsList)
)); ));
bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator'); bottle.serviceFactory('SearchBar', SearchBar, 'ColorGenerator', 'ForServerVersion');
bottle.decorator('SearchBar', connect([ 'shortUrlsListParams', 'selectedServer' ], [ 'listShortUrls' ])); bottle.decorator('SearchBar', connect([ 'shortUrlsListParams' ], [ 'listShortUrls' ]));
bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow'); bottle.serviceFactory('ShortUrlsList', ShortUrlsList, 'ShortUrlsRow');
bottle.decorator('ShortUrlsList', connect( bottle.decorator('ShortUrlsList', connect(
@ -35,10 +35,17 @@ const provideServices = (bottle, connect) => {
bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'ShortUrlsRowMenu', 'ColorGenerator', 'stateFlagTimeout'); bottle.serviceFactory('ShortUrlsRow', ShortUrlsRow, 'ShortUrlsRowMenu', 'ColorGenerator', 'stateFlagTimeout');
bottle.serviceFactory('ShortUrlsRowMenu', ShortUrlsRowMenu, 'DeleteShortUrlModal', 'EditTagsModal', 'EditMetaModal'); bottle.serviceFactory(
'ShortUrlsRowMenu',
ShortUrlsRowMenu,
'DeleteShortUrlModal',
'EditTagsModal',
'EditMetaModal',
'ForServerVersion'
);
bottle.serviceFactory('CreateShortUrlResult', CreateShortUrlResult, 'stateFlagTimeout'); bottle.serviceFactory('CreateShortUrlResult', CreateShortUrlResult, 'stateFlagTimeout');
bottle.serviceFactory('CreateShortUrl', CreateShortUrl, 'TagsSelector', 'CreateShortUrlResult'); bottle.serviceFactory('CreateShortUrl', CreateShortUrl, 'TagsSelector', 'CreateShortUrlResult', 'ForServerVersion');
bottle.decorator( bottle.decorator(
'CreateShortUrl', 'CreateShortUrl',
connect([ 'shortUrlCreationResult', 'selectedServer' ], [ 'createShortUrl', 'resetCreateShortUrl' ]) connect([ 'shortUrlCreationResult', 'selectedServer' ], [ 'createShortUrl', 'resetCreateShortUrl' ])

View file

@ -1,19 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { isEmpty } from 'ramda';
import { compareVersions } from './utils';
const propTypes = {
minVersion: PropTypes.string.isRequired,
currentServerVersion: PropTypes.string.isRequired,
children: PropTypes.node.isRequired,
};
const ForVersion = ({ minVersion, currentServerVersion, children }) =>
isEmpty(currentServerVersion) || compareVersions(currentServerVersion, '<', minVersion)
? null
: <React.Fragment>{children}</React.Fragment>;
ForVersion.propTypes = propTypes;
export default ForVersion;

View file

@ -0,0 +1,48 @@
import React from 'react';
import { mount } from 'enzyme';
import each from 'jest-each';
import ForServerVersion from '../../../src/servers/helpers/ForServerVersion';
describe('<ForServerVersion />', () => {
let wrapped;
const renderComponent = (minVersion, maxVersion, selectedServer) => {
wrapped = mount(
<ForServerVersion minVersion={minVersion} maxVersion={maxVersion} selectedServer={selectedServer}>
<span>Hello</span>
</ForServerVersion>
);
return wrapped;
};
afterEach(() => wrapped && wrapped.unmount());
it('does not render children when current server is empty', () => {
const wrapped = renderComponent('1');
expect(wrapped.html()).toBeNull();
});
each([
[ '2.0.0', undefined, '1.8.3' ],
[ undefined, '1.8.0', '1.8.3' ],
[ '1.7.0', '1.8.0', '1.8.3' ],
]).it('does not render children when current version does not match requirements', (min, max, version) => {
const wrapped = renderComponent(min, max, { version });
expect(wrapped.html()).toBeNull();
});
each([
[ '2.0.0', undefined, '2.8.3' ],
[ '2.0.0', undefined, '2.0.0' ],
[ undefined, '1.8.0', '1.8.0' ],
[ undefined, '1.8.0', '1.7.1' ],
[ '1.7.0', '1.8.0', '1.7.3' ],
]).it('renders children when current version matches requirements', (min, max, version) => {
const wrapped = renderComponent(min, max, { version });
expect(wrapped.html()).toContain('<span>Hello</span>');
});
});

View file

@ -22,15 +22,10 @@ describe('<SearchBar />', () => {
expect(wrapper.find(SearchField)).toHaveLength(1); expect(wrapper.find(SearchField)).toHaveLength(1);
}); });
each([ it('renders a DateRangeRow', () => {
[ '2.0.0', 1 ], wrapper = shallow(<SearchBar shortUrlsListParams={{}} />);
[ '1.21.2', 1 ],
[ '1.21.0', 1 ],
[ '1.20.0', 0 ],
]).it('renders a DateRangeRow when proper version is run', (version, expectedLength) => {
wrapper = shallow(<SearchBar shortUrlsListParams={{}} selectedServer={{ version }} />);
expect(wrapper.find(DateRangeRow)).toHaveLength(expectedLength); expect(wrapper.find(DateRangeRow)).toHaveLength(1);
}); });
it('renders no tags when the list of tags is empty', () => { it('renders no tags when the list of tags is empty', () => {
@ -69,7 +64,7 @@ describe('<SearchBar />', () => {
each([ 'startDateChange', 'endDateChange' ]).it('updates short URLs list when date range changes', (event) => { each([ 'startDateChange', 'endDateChange' ]).it('updates short URLs list when date range changes', (event) => {
wrapper = shallow( wrapper = shallow(
<SearchBar shortUrlsListParams={{}} listShortUrls={listShortUrlsMock} selectedServer={{ version: '2.0.0' }} /> <SearchBar shortUrlsListParams={{}} listShortUrls={listShortUrlsMock} />
); );
const dateRange = wrapper.find(DateRangeRow); const dateRange = wrapper.find(DateRangeRow);

View file

@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { ButtonDropdown, DropdownItem } from 'reactstrap'; import { ButtonDropdown, DropdownItem } from 'reactstrap';
import each from 'jest-each';
import createShortUrlsRowMenu from '../../../src/short-urls/helpers/ShortUrlsRowMenu'; import createShortUrlsRowMenu from '../../../src/short-urls/helpers/ShortUrlsRowMenu';
import PreviewModal from '../../../src/short-urls/helpers/PreviewModal'; import PreviewModal from '../../../src/short-urls/helpers/PreviewModal';
import QrCodeModal from '../../../src/short-urls/helpers/QrCodeModal'; import QrCodeModal from '../../../src/short-urls/helpers/QrCodeModal';
@ -17,12 +16,12 @@ describe('<ShortUrlsRowMenu />', () => {
shortCode: 'abc123', shortCode: 'abc123',
shortUrl: 'https://doma.in/abc123', shortUrl: 'https://doma.in/abc123',
}; };
const createWrapper = (serverVersion = '1.21.1') => { const createWrapper = () => {
const ShortUrlsRowMenu = createShortUrlsRowMenu(DeleteShortUrlModal, EditTagsModal, EditMetaModal); const ShortUrlsRowMenu = createShortUrlsRowMenu(DeleteShortUrlModal, EditTagsModal, EditMetaModal);
wrapper = shallow( wrapper = shallow(
<ShortUrlsRowMenu <ShortUrlsRowMenu
selectedServer={{ ...selectedServer, version: serverVersion }} selectedServer={selectedServer}
shortUrl={shortUrl} shortUrl={shortUrl}
onCopyToClipboard={onCopyToClipboard} onCopyToClipboard={onCopyToClipboard}
/> />
@ -46,24 +45,12 @@ describe('<ShortUrlsRowMenu />', () => {
expect(qrCodeModal).toHaveLength(1); expect(qrCodeModal).toHaveLength(1);
}); });
each([ it('renders correct amount of menu items', () => {
[ '1.17.0', 6, 2 ], const wrapper = createWrapper();
[ '1.17.2', 6, 2 ],
[ '1.18.0', 7, 2 ],
[ '1.18.1', 7, 2 ],
[ '1.19.0', 7, 2 ],
[ '1.20.3', 7, 2 ],
[ '1.21.0', 7, 2 ],
[ '1.21.1', 7, 2 ],
[ '2.0.0', 6, 1 ],
[ '2.0.1', 6, 1 ],
[ '2.1.0', 6, 1 ],
]).it('renders correct amount of menu items depending on the version', (version, expectedNonDividerItems, expectedDividerItems) => {
const wrapper = createWrapper(version);
const items = wrapper.find(DropdownItem); const items = wrapper.find(DropdownItem);
expect(items).toHaveLength(expectedNonDividerItems + expectedDividerItems); expect(items).toHaveLength(9);
expect(items.find('[divider]')).toHaveLength(expectedDividerItems); expect(items.find('[divider]')).toHaveLength(2);
}); });
describe('toggles state when toggling modal windows', () => { describe('toggles state when toggling modal windows', () => {

View file

@ -1,43 +0,0 @@
import React from 'react';
import { mount } from 'enzyme';
import ForVersion from '../../src/utils/ForVersion';
describe('<ForVersion />', () => {
let wrapped;
const renderComponent = (minVersion, currentServerVersion) => {
wrapped = mount(
<ForVersion minVersion={minVersion} currentServerVersion={currentServerVersion}>
<span>Hello</span>
</ForVersion>
);
return wrapped;
};
afterEach(() => wrapped && wrapped.unmount());
it('does not render children when current version is empty', () => {
const wrapped = renderComponent('1', '');
expect(wrapped.html()).toBeNull();
});
it('does not render children when current version is lower than min version', () => {
const wrapped = renderComponent('2.0.0', '1.8.3');
expect(wrapped.html()).toBeNull();
});
it('renders children when current version is equal min version', () => {
const wrapped = renderComponent('2.0.0', '2.0.0');
expect(wrapped.html()).toContain('<span>Hello</span>');
});
it('renders children when current version is higher than min version', () => {
const wrapped = renderComponent('2.0.0', '2.1.0');
expect(wrapped.html()).toContain('<span>Hello</span>');
});
});