mirror of
https://github.com/SomboChea/ui
synced 2024-12-25 13:44:31 +07:00
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 { mount } from '../../utils/test-enzyme';
|
||||
import { render } from '../../utils/test-react-testing-library';
|
||||
import { DetailContext, DetailContextProps } from '../../pages/Version';
|
||||
|
||||
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(() => ({
|
||||
latest: {
|
||||
homepage: 'https://verdaccio.tld',
|
||||
bugs: {
|
||||
url: 'https://verdaccio.tld/bugs',
|
||||
},
|
||||
dist: {
|
||||
tarball: 'https://verdaccio.tld/download',
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('../../pages/Version', () => ({
|
||||
DetailContextConsumer: component => {
|
||||
return component.children({ packageMeta: mockPackageMeta() });
|
||||
},
|
||||
}));
|
||||
const ComponentToBeRendered: React.FC<{ contextValue: DetailContextProps }> = ({ contextValue }) => (
|
||||
<DetailContext.Provider value={contextValue}>
|
||||
<Repository />
|
||||
</DetailContext.Provider>
|
||||
);
|
||||
|
||||
describe('<Repository /> component', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
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 load the component in default state', () => {
|
||||
const { container } = render(<ComponentToBeRendered contextValue={detailContextValue} />);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('should render the component in with no repository data', () => {
|
||||
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(wrapper.html()).toEqual('');
|
||||
expect(queryByText('Repository')).toBeFalsy();
|
||||
});
|
||||
|
||||
test('should render the component in with invalid url', () => {
|
||||
const packageMeta = {
|
||||
...detailContextValue.packageMeta,
|
||||
latest: {
|
||||
...detailContextValue.packageMeta?.latest,
|
||||
repository: {
|
||||
type: '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(wrapper.html()).toEqual('');
|
||||
expect(queryByText('Repository')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
@ -1,57 +1,80 @@
|
||||
/* 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 { 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 CopyToClipBoard from '../CopyToClipBoard';
|
||||
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 { GithubLink, StyledText, RepositoryListItem, RepositoryListItemText } from './styles';
|
||||
|
||||
class Repository extends Component {
|
||||
public render(): ReactElement<HTMLElement> {
|
||||
return (
|
||||
<DetailContextConsumer>
|
||||
{context => {
|
||||
return context && context.packageMeta && this.renderRepository(context.packageMeta);
|
||||
}}
|
||||
</DetailContextConsumer>
|
||||
);
|
||||
const StyledText = styled(Text)({
|
||||
fontWeight: fontWeight.bold,
|
||||
textTransform: 'capitalize',
|
||||
});
|
||||
|
||||
const GithubLink = styled('a')<{ theme?: Theme }>(props => ({
|
||||
color: props.theme && props.theme.palette.primary.main,
|
||||
}));
|
||||
|
||||
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> {
|
||||
return (
|
||||
<GithubLink href={url} target="_blank">
|
||||
{url}
|
||||
</GithubLink>
|
||||
);
|
||||
}
|
||||
const { url } = packageMeta.latest.repository;
|
||||
|
||||
private renderRepository = packageMeta => {
|
||||
const { repository: { url = null } = {} } = packageMeta.latest;
|
||||
|
||||
if (!url || isURL(url) === false) {
|
||||
return null;
|
||||
const getCorrectRepositoryURL = (): string => {
|
||||
if (!url.includes('git+')) {
|
||||
return url;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<List dense={true} subheader={<StyledText variant="subtitle1">{'Repository'}</StyledText>}>
|
||||
<RepositoryListItem button={true}>
|
||||
<Avatar src={git} />
|
||||
<RepositoryListItemText primary={this.renderContent(url)} />
|
||||
</RepositoryListItem>
|
||||
</List>
|
||||
</Fragment>
|
||||
);
|
||||
return url.split('git+')[1];
|
||||
};
|
||||
|
||||
private renderContent(url: string): ReactElement<HTMLElement> {
|
||||
return <CopyToClipBoard text={url}>{this.renderRepositoryText(url)}</CopyToClipBoard>;
|
||||
}
|
||||
}
|
||||
const repositoryURL = getCorrectRepositoryURL();
|
||||
|
||||
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;
|
||||
|
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
|
||||
|
||||
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;
|
||||
version: string;
|
||||
repository?: {
|
||||
type?: string;
|
||||
url?: string;
|
||||
};
|
||||
};
|
||||
_uplinks: {};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user