forked from sombochea/verdaccio-ui
Repository Component - Replaced class by func. comp (#323)
This commit is contained in:
parent
d37de29d36
commit
e60ab9e247
@ -1,64 +1,58 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { mount } from '../../utils/test-enzyme';
|
import { render } from '../../utils/test-react-testing-library';
|
||||||
|
import { DetailContext, DetailContextProps } from '../../pages/Version';
|
||||||
|
|
||||||
import Repository from './Repository';
|
import Repository from './Repository';
|
||||||
|
import data from './__partials__/data.json';
|
||||||
|
|
||||||
jest.mock('./img/git.png', () => '');
|
const detailContextValue: DetailContextProps = {
|
||||||
|
packageName: 'foo',
|
||||||
|
readMe: 'readMe',
|
||||||
|
enableLoading: () => {},
|
||||||
|
isLoading: false,
|
||||||
|
hasNotBeenFound: false,
|
||||||
|
packageMeta: data,
|
||||||
|
};
|
||||||
|
|
||||||
const mockPackageMeta: jest.Mock = jest.fn(() => ({
|
const ComponentToBeRendered: React.FC<{ contextValue: DetailContextProps }> = ({ contextValue }) => (
|
||||||
latest: {
|
<DetailContext.Provider value={contextValue}>
|
||||||
homepage: 'https://verdaccio.tld',
|
<Repository />
|
||||||
bugs: {
|
</DetailContext.Provider>
|
||||||
url: 'https://verdaccio.tld/bugs',
|
);
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
tarball: 'https://verdaccio.tld/download',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../../pages/Version', () => ({
|
|
||||||
DetailContextConsumer: component => {
|
|
||||||
return component.children({ packageMeta: mockPackageMeta() });
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('<Repository /> component', () => {
|
describe('<Repository /> component', () => {
|
||||||
beforeEach(() => {
|
test('should load the component in default state', () => {
|
||||||
jest.resetAllMocks();
|
const { container } = render(<ComponentToBeRendered contextValue={detailContextValue} />);
|
||||||
});
|
expect(container.firstChild).toMatchSnapshot();
|
||||||
|
|
||||||
test('should render the component in default state', () => {
|
|
||||||
const packageMeta = {
|
|
||||||
latest: {
|
|
||||||
repository: {
|
|
||||||
type: 'git',
|
|
||||||
url: 'git+https://github.com/verdaccio/ui.git',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
|
||||||
|
|
||||||
const wrapper = mount(<Repository />);
|
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render the component in with no repository data', () => {
|
test('should render the component in with no repository data', () => {
|
||||||
const packageMeta = {
|
const packageMeta = {
|
||||||
latest: {},
|
...detailContextValue.packageMeta,
|
||||||
|
latest: {
|
||||||
|
...detailContextValue.packageMeta?.latest,
|
||||||
|
repository: undefined,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
const { queryByText } = render(
|
||||||
|
<ComponentToBeRendered
|
||||||
|
contextValue={{
|
||||||
|
...detailContextValue,
|
||||||
|
packageMeta,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const wrapper = mount(<Repository />);
|
expect(queryByText('Repository')).toBeFalsy();
|
||||||
expect(wrapper.html()).toEqual('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render the component in with invalid url', () => {
|
test('should render the component in with invalid url', () => {
|
||||||
const packageMeta = {
|
const packageMeta = {
|
||||||
|
...detailContextValue.packageMeta,
|
||||||
latest: {
|
latest: {
|
||||||
|
...detailContextValue.packageMeta?.latest,
|
||||||
repository: {
|
repository: {
|
||||||
type: 'git',
|
type: 'git',
|
||||||
url: 'git://github.com/verdaccio/ui.git',
|
url: 'git://github.com/verdaccio/ui.git',
|
||||||
@ -66,9 +60,15 @@ describe('<Repository /> component', () => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
const { queryByText } = render(
|
||||||
|
<ComponentToBeRendered
|
||||||
|
contextValue={{
|
||||||
|
...detailContextValue,
|
||||||
|
packageMeta,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
const wrapper = mount(<Repository />);
|
expect(queryByText('Repository')).toBeFalsy();
|
||||||
expect(wrapper.html()).toEqual('');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,57 +1,80 @@
|
|||||||
/* eslint react/jsx-max-depth: 0 */
|
/* eslint react/jsx-max-depth: 0 */
|
||||||
|
|
||||||
import React, { Component, Fragment, ReactElement } from 'react';
|
import React from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import Avatar from '../../muiComponents/Avatar';
|
import Avatar from '../../muiComponents/Avatar';
|
||||||
import { DetailContextConsumer } from '../../pages/Version';
|
import Text from '../../muiComponents/Text';
|
||||||
|
import ListItem from '../../muiComponents/ListItem';
|
||||||
|
import ListItemText from '../../muiComponents/ListItemText';
|
||||||
import { isURL } from '../../utils/url';
|
import { isURL } from '../../utils/url';
|
||||||
import CopyToClipBoard from '../CopyToClipBoard';
|
import CopyToClipBoard from '../CopyToClipBoard';
|
||||||
import List from '../../muiComponents/List';
|
import List from '../../muiComponents/List';
|
||||||
|
import { DetailContext } from '../../pages/Version';
|
||||||
|
import { Theme } from '../../design-tokens/theme';
|
||||||
|
import { fontWeight } from '../../utils/styles/sizes';
|
||||||
|
|
||||||
import git from './img/git.png';
|
import git from './img/git.png';
|
||||||
import { GithubLink, StyledText, RepositoryListItem, RepositoryListItemText } from './styles';
|
|
||||||
|
|
||||||
class Repository extends Component {
|
const StyledText = styled(Text)({
|
||||||
public render(): ReactElement<HTMLElement> {
|
fontWeight: fontWeight.bold,
|
||||||
return (
|
textTransform: 'capitalize',
|
||||||
<DetailContextConsumer>
|
});
|
||||||
{context => {
|
|
||||||
return context && context.packageMeta && this.renderRepository(context.packageMeta);
|
const GithubLink = styled('a')<{ theme?: Theme }>(props => ({
|
||||||
}}
|
color: props.theme && props.theme.palette.primary.main,
|
||||||
</DetailContextConsumer>
|
}));
|
||||||
);
|
|
||||||
|
const RepositoryListItem = styled(ListItem)({
|
||||||
|
padding: 0,
|
||||||
|
':hover': {
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const RepositoryListItemText = styled(ListItemText)({
|
||||||
|
padding: '0 10px',
|
||||||
|
margin: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
/* eslint-disable react/jsx-wrap-multilines */
|
||||||
|
const Repository: React.FC = () => {
|
||||||
|
const detailContext = React.useContext(DetailContext);
|
||||||
|
|
||||||
|
const { packageMeta } = detailContext;
|
||||||
|
|
||||||
|
if (!packageMeta?.latest?.repository?.url || !isURL(packageMeta.latest.repository.url)) {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderRepositoryText(url: string): ReactElement<HTMLElement> {
|
const { url } = packageMeta.latest.repository;
|
||||||
return (
|
|
||||||
<GithubLink href={url} target="_blank">
|
|
||||||
{url}
|
|
||||||
</GithubLink>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private renderRepository = packageMeta => {
|
const getCorrectRepositoryURL = (): string => {
|
||||||
const { repository: { url = null } = {} } = packageMeta.latest;
|
if (!url.includes('git+')) {
|
||||||
|
return url;
|
||||||
if (!url || isURL(url) === false) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return url.split('git+')[1];
|
||||||
<Fragment>
|
|
||||||
<List dense={true} subheader={<StyledText variant="subtitle1">{'Repository'}</StyledText>}>
|
|
||||||
<RepositoryListItem button={true}>
|
|
||||||
<Avatar src={git} />
|
|
||||||
<RepositoryListItemText primary={this.renderContent(url)} />
|
|
||||||
</RepositoryListItem>
|
|
||||||
</List>
|
|
||||||
</Fragment>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderContent(url: string): ReactElement<HTMLElement> {
|
const repositoryURL = getCorrectRepositoryURL();
|
||||||
return <CopyToClipBoard text={url}>{this.renderRepositoryText(url)}</CopyToClipBoard>;
|
|
||||||
}
|
return (
|
||||||
}
|
<List dense={true} subheader={<StyledText variant="subtitle1">{'Repository'}</StyledText>}>
|
||||||
|
<RepositoryListItem button={true}>
|
||||||
|
<Avatar src={git} />
|
||||||
|
<RepositoryListItemText
|
||||||
|
primary={
|
||||||
|
<CopyToClipBoard text={repositoryURL}>
|
||||||
|
<GithubLink href={repositoryURL} target="_blank">
|
||||||
|
{repositoryURL}
|
||||||
|
</GithubLink>
|
||||||
|
</CopyToClipBoard>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</RepositoryListItem>
|
||||||
|
</List>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Repository;
|
export default Repository;
|
||||||
|
6406
src/components/Repository/__partials__/data.json
Normal file
6406
src/components/Repository/__partials__/data.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,3 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`<Repository /> component should render the component in default state 1`] = `"<ul class=\\"MuiList-root MuiList-dense MuiList-padding MuiList-subheader\\"><h6 class=\\"MuiTypography-root css-1na337r-StyledText e1wmjxnh0 MuiTypography-subtitle1\\">Repository</h6><div class=\\"MuiButtonBase-root MuiListItem-root css-719o4l-RepositoryListItem e1wmjxnh4 MuiListItem-dense MuiListItem-gutters MuiListItem-button\\" tabindex=\\"0\\" role=\\"button\\" aria-disabled=\\"false\\"><div class=\\"MuiAvatar-root MuiAvatar-circle MuiAvatar-colorDefault\\"></div><div class=\\"MuiListItemText-root css-1lp4n02-RepositoryListItemText e1wmjxnh5 MuiListItemText-dense\\"><span class=\\"MuiTypography-root MuiListItemText-primary MuiTypography-body2\\"><div class=\\"css-1in239f-ClipBoardCopy eb8w2fo0\\"><span class=\\"css-7gar9h-ClipBoardCopyText eb8w2fo1\\"><a href=\\"git+https://github.com/verdaccio/ui.git\\" target=\\"_blank\\" class=\\"css-6tc7qn-GithubLink e1wmjxnh2\\">git+https://github.com/verdaccio/ui.git</a></span><button class=\\"MuiButtonBase-root MuiIconButton-root css-1fs86cq-CopyIcon eb8w2fo2\\" tabindex=\\"0\\" type=\\"button\\" title=\\"Copy to Clipboard\\"><span class=\\"MuiIconButton-label\\"><svg class=\\"MuiSvgIcon-root\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\" role=\\"presentation\\"><path d=\\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm-1 4l6 6v10c0 1.1-.9 2-2 2H7.99C6.89 23 6 22.1 6 21l.01-14c0-1.1.89-2 1.99-2h7zm-1 7h5.5L14 6.5V12z\\"></path></svg></span><span class=\\"MuiTouchRipple-root\\"></span></button></div></span></div><span class=\\"MuiTouchRipple-root\\"></span></div></ul>"`;
|
exports[`<Repository /> component should load the component in default state 1`] = `null`;
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import Github from '../../icons/GitHub';
|
|
||||||
import { fontWeight } from '../../utils/styles/sizes';
|
|
||||||
import Text from '../../muiComponents/Text';
|
|
||||||
import ListItem from '../../muiComponents/ListItem';
|
|
||||||
import ListItemText from '../../muiComponents/ListItemText';
|
|
||||||
import Grid from '../../muiComponents/Grid';
|
|
||||||
import { Theme } from '../../design-tokens/theme';
|
|
||||||
|
|
||||||
export const StyledText = styled(Text)({
|
|
||||||
fontWeight: fontWeight.bold,
|
|
||||||
textTransform: 'capitalize',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const GridRepo = styled(Grid)({
|
|
||||||
alignItems: 'center',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const GithubLink = styled('a')<{ theme?: Theme }>(props => ({
|
|
||||||
color: props.theme && props.theme.palette.primary.main,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const GithubLogo = styled(Github)<{ theme?: Theme }>(props => ({
|
|
||||||
fontSize: 40,
|
|
||||||
color: props.theme && props.theme.palette.primary.main,
|
|
||||||
backgroundColor: props.theme && props.theme.palette.greySuperLight,
|
|
||||||
}));
|
|
||||||
|
|
||||||
export const RepositoryListItem = styled(ListItem)({
|
|
||||||
padding: 0,
|
|
||||||
':hover': {
|
|
||||||
backgroundColor: 'transparent',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const RepositoryListItemText = styled(ListItemText)({
|
|
||||||
padding: '0 10px',
|
|
||||||
margin: 0,
|
|
||||||
});
|
|
@ -15,6 +15,10 @@ export interface PackageMetaInterface {
|
|||||||
};
|
};
|
||||||
license?: Partial<LicenseInterface> | string;
|
license?: Partial<LicenseInterface> | string;
|
||||||
version: string;
|
version: string;
|
||||||
|
repository?: {
|
||||||
|
type?: string;
|
||||||
|
url?: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
_uplinks: {};
|
_uplinks: {};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user