forked from sombochea/verdaccio-ui
fix: convert Engine component to hooks (#233)
* refactor: convert Engine component to hooks * inline engine test data only used by one test * remove from engines tests * remove confusing test abstraction * change tests to not use mutations
This commit is contained in:
parent
b56e43846b
commit
5cb47ed49e
@ -1,71 +1,61 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
|
import { DetailContext } from '../../pages/Version';
|
||||||
|
import { PackageMetaInterface } from '../../../types/packageMeta';
|
||||||
|
|
||||||
import Engine from './Engines';
|
import Engine from './Engines';
|
||||||
|
|
||||||
jest.mock('./img/node.png', () => '');
|
jest.mock('./img/node.png', () => '');
|
||||||
jest.mock('../Install/img/npm.svg', () => '');
|
jest.mock('../Install/img/npm.svg', () => '');
|
||||||
|
|
||||||
const mockPackageMeta: jest.Mock = jest.fn(() => ({
|
const mockPackageMeta = (engines?: PackageMetaInterface['latest']['engines']): PackageMetaInterface => ({
|
||||||
latest: {
|
latest: {
|
||||||
homepage: 'https://verdaccio.tld',
|
name: 'verdaccio',
|
||||||
bugs: {
|
version: '0.0.0',
|
||||||
url: 'https://verdaccio.tld/bugs',
|
|
||||||
},
|
|
||||||
dist: {
|
dist: {
|
||||||
tarball: 'https://verdaccio.tld/download',
|
fileCount: 1,
|
||||||
|
unpackedSize: 1,
|
||||||
},
|
},
|
||||||
|
...(engines && { engines }),
|
||||||
},
|
},
|
||||||
}));
|
_uplinks: {},
|
||||||
|
});
|
||||||
jest.mock('../../pages/Version', () => ({
|
|
||||||
DetailContextConsumer: component => {
|
|
||||||
return component.children({ packageMeta: mockPackageMeta() });
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('<Engines /> component', () => {
|
describe('<Engines /> component', () => {
|
||||||
beforeEach(() => {
|
|
||||||
jest.resetAllMocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should render the component in default state', () => {
|
test('should render the component in default state', () => {
|
||||||
const packageMeta = {
|
const packageMeta = mockPackageMeta({
|
||||||
latest: {
|
node: '>= 0.1.98',
|
||||||
engines: {
|
npm: '>3',
|
||||||
node: '>= 0.1.98',
|
});
|
||||||
npm: '>3',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
const wrapper = mount(
|
||||||
|
<DetailContext.Provider value={{ packageMeta }}>
|
||||||
const wrapper = mount(<Engine />);
|
<Engine />
|
||||||
|
</DetailContext.Provider>
|
||||||
|
);
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render the component when there is no engine key in package meta', () => {
|
test('should render the component when there is no engine key in package meta', () => {
|
||||||
const packageMeta = {
|
const packageMeta = mockPackageMeta();
|
||||||
latest: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
const wrapper = mount(
|
||||||
|
<DetailContext.Provider value={{ packageMeta }}>
|
||||||
const wrapper = mount(<Engine />);
|
<Engine />
|
||||||
expect(wrapper.html()).toEqual('');
|
</DetailContext.Provider>
|
||||||
|
);
|
||||||
|
expect(wrapper.html()).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render the component when there is no keys in engine in package meta', () => {
|
test('should render the component when there is no keys in engine in package meta', () => {
|
||||||
const packageMeta = {
|
const packageMeta = mockPackageMeta({});
|
||||||
latest: {
|
|
||||||
engines: {},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
const wrapper = mount(
|
||||||
|
<DetailContext.Provider value={{ packageMeta }}>
|
||||||
const wrapper = mount(<Engine />);
|
<Engine />
|
||||||
expect(wrapper.html()).toEqual('');
|
</DetailContext.Provider>
|
||||||
|
);
|
||||||
|
expect(wrapper.html()).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { Component, ReactElement } from 'react';
|
import React, { useContext } from 'react';
|
||||||
|
|
||||||
import { VersionPageConsumerProps, DetailContextConsumer } from '../../pages/Version';
|
import { DetailContext } from '../../pages/Version';
|
||||||
import Avatar from '../../muiComponents/Avatar';
|
import Avatar from '../../muiComponents/Avatar';
|
||||||
import List from '../../muiComponents/List';
|
import List from '../../muiComponents/List';
|
||||||
import npm from '../Install/img/npm.svg';
|
import npm from '../Install/img/npm.svg';
|
||||||
@ -8,66 +8,44 @@ import ListItemText from '../../muiComponents/ListItemText';
|
|||||||
import Grid from '../../muiComponents/Grid';
|
import Grid from '../../muiComponents/Grid';
|
||||||
|
|
||||||
import { StyledText, EngineListItem } from './styles';
|
import { StyledText, EngineListItem } from './styles';
|
||||||
// @ts-ignore
|
|
||||||
import node from './img/node.png';
|
import node from './img/node.png';
|
||||||
|
|
||||||
const ICONS = {
|
const Engine: React.FC = () => {
|
||||||
'node-JS': <Avatar src={node} />,
|
const { packageMeta } = useContext(DetailContext);
|
||||||
'NPM-version': <Avatar src={npm} />,
|
|
||||||
};
|
|
||||||
|
|
||||||
class Engine extends Component {
|
const engines = packageMeta && packageMeta.latest && packageMeta.latest.engines;
|
||||||
public render(): ReactElement<HTMLElement> {
|
|
||||||
return (
|
if (!engines || (!engines.node && !engines.npm)) {
|
||||||
<DetailContextConsumer>
|
return null;
|
||||||
{context => {
|
|
||||||
return this.renderEngine(context as VersionPageConsumerProps);
|
|
||||||
}}
|
|
||||||
</DetailContextConsumer>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderEngine = ({ packageMeta }): ReactElement<HTMLElement> | null => {
|
/* eslint-disable react/jsx-max-depth */
|
||||||
const { engines } = packageMeta.latest;
|
return (
|
||||||
if (!engines) {
|
<Grid container={true}>
|
||||||
return null;
|
{engines.node && (
|
||||||
}
|
<Grid item={true} xs={6}>
|
||||||
|
<List subheader={<StyledText variant={'subtitle1'}>{'node JS'}</StyledText>}>
|
||||||
|
<EngineListItem button={true}>
|
||||||
|
<Avatar src={node} />
|
||||||
|
<ListItemText primary={engines.node} />
|
||||||
|
</EngineListItem>
|
||||||
|
</List>
|
||||||
|
</Grid>
|
||||||
|
)}
|
||||||
|
|
||||||
const engineDict = {
|
{engines.npm && (
|
||||||
'node-JS': engines.node,
|
<Grid item={true} xs={6}>
|
||||||
'NPM-version': engines.npm,
|
<List subheader={<StyledText variant={'subtitle1'}>{'NPM version'}</StyledText>}>
|
||||||
};
|
<EngineListItem button={true}>
|
||||||
|
<Avatar src={npm} />
|
||||||
const accumulator: React.ReactNode[] = [];
|
<ListItemText primary={engines.npm} />
|
||||||
const items = Object.keys(engineDict).reduce((markup, text, key) => {
|
</EngineListItem>
|
||||||
const heading = engineDict[text];
|
</List>
|
||||||
if (heading) {
|
</Grid>
|
||||||
markup.push(
|
)}
|
||||||
<Grid item={true} key={key} xs={6}>
|
</Grid>
|
||||||
{this.renderListItems(heading, text)}
|
);
|
||||||
</Grid>
|
/* eslint-enable react/jsx-max-depth */
|
||||||
);
|
};
|
||||||
}
|
|
||||||
return markup;
|
|
||||||
}, accumulator);
|
|
||||||
|
|
||||||
if (items.length < 1) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Grid container={true}>{items}</Grid>;
|
|
||||||
};
|
|
||||||
|
|
||||||
private renderListItems = (heading: string, text: string) => {
|
|
||||||
return (
|
|
||||||
<List subheader={<StyledText variant={'subtitle1'}>{text.split('-').join(' ')}</StyledText>}>
|
|
||||||
<EngineListItem button={true}>
|
|
||||||
{ICONS[text]}
|
|
||||||
<ListItemText primary={heading} />
|
|
||||||
</EngineListItem>
|
|
||||||
</List>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Engine;
|
export default Engine;
|
||||||
|
@ -9,6 +9,10 @@ export interface PackageMetaInterface {
|
|||||||
fileCount: number;
|
fileCount: number;
|
||||||
unpackedSize: number;
|
unpackedSize: number;
|
||||||
};
|
};
|
||||||
|
engines?: {
|
||||||
|
node?: string;
|
||||||
|
npm?: string;
|
||||||
|
};
|
||||||
license?: Partial<LicenseInterface> | string;
|
license?: Partial<LicenseInterface> | string;
|
||||||
version: string;
|
version: string;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user