fix: refactoring version page / fix issue not found page #100 (#117)

* chore: refactoring version page

* refactor: migrate version page to hooks

* refactor: Version page better imports

* fix: #100 render not found on click item

* test: add test for version page

* chore: update mocks

* test: add scenario for not found package

* chore: fix wrong mock path

* chore: update mock

* chore: add todo list
This commit is contained in:
Juan Picado @jotadeveloper
2019-08-25 14:34:27 +02:00
committed by GitHub
parent e7d3c461cd
commit 97e8448098
42 changed files with 25186 additions and 678 deletions

View File

@@ -19,7 +19,7 @@ describe('<ActionBar /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -35,7 +35,7 @@ describe('<ActionBar /> component', () => {
latest: {},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -57,7 +57,7 @@ describe('<ActionBar /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},

View File

@@ -6,7 +6,7 @@ import HomeIcon from '@material-ui/icons/Home';
import List from '@material-ui/core/List';
import Tooltip from '@material-ui/core/Tooltip';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/Version';
import { Fab, ActionListItem } from './styles';
import { isURL, extractFileName, downloadFile } from '../../utils/url';
import api from '../../utils/api';

View File

@@ -20,7 +20,7 @@ describe('<Author /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -39,7 +39,7 @@ describe('<Author /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -63,7 +63,7 @@ describe('<Author /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},

View File

@@ -4,7 +4,7 @@ import Avatar from '@material-ui/core/Avatar';
import List from '@material-ui/core/List';
import ListItemText from '@material-ui/core/ListItemText';
import { DetailContextConsumer } from '../../pages/version/Version';
import { DetailContextConsumer } from '../../pages/Version';
import { Heading, AuthorListItem } from './styles';
import { isEmail } from '../../utils/url';

View File

@@ -2,7 +2,7 @@ import React, { Component, Fragment, ReactElement } from 'react';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import CardContent from '@material-ui/core/CardContent';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/Version';
import { CardWrap, Heading, Tags, Tag } from './styles';
import NoItems from '../NoItems';

View File

@@ -1,6 +1,6 @@
import React, { Component, ReactElement, Fragment } from 'react';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/Version';
import Readme from '../Readme';
import Versions from '../Versions';
import { preventXSS } from '../../utils/sec-utils';
@@ -14,6 +14,11 @@ interface DetailContainerState {
tabPosition: number;
}
export const README_LABEL = 'Readme';
export const DEPS_LABEL = 'Dependencies';
export const VERSION_LABEL = 'Versions';
export const UPLINKS_LABEL = 'Uplinks';
class DetailContainer<P> extends Component<P, DetailContainerState> {
public state = {
tabPosition: 0,
@@ -37,10 +42,10 @@ class DetailContainer<P> extends Component<P, DetailContainerState> {
private renderListTabs(tabPosition: number): React.ReactElement<HTMLElement> {
return (
<Tabs indicatorColor={'primary'} onChange={this.handleChange} textColor={'primary'} value={tabPosition} variant={'fullWidth'}>
<Tab id={'readme-tab'} label={'Readme'} />
<Tab id={'dependencies-tab'} label={'Dependencies'} />
<Tab id={'versions-tab'} label={'Versions'} />
<Tab id={'uplinks-tab'} label={'Uplinks'} />
<Tab data-testid={'readme-tab'} id={'readme-tab'} label={README_LABEL} />
<Tab data-testid={'dependencies-tab'} id={'dependencies-tab'} label={DEPS_LABEL} />
<Tab data-testid={'versions-tab'} id={'versions-tab'} label={VERSION_LABEL} />
<Tab data-testid={'uplinks-tab'} id={'uplinks-tab'} label={UPLINKS_LABEL} />
</Tabs>
);
}

View File

@@ -1,4 +1,4 @@
import React, { Component, ReactElement } from 'react';
import React, { ReactElement } from 'react';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
@@ -12,76 +12,52 @@ import Engine from '../Engines/Engines';
import Install from '../Install';
import Repository from '../Repository/Repository';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { DetailContext } from '../../pages/Version';
import { TitleListItem, TitleListItemText } from './styles';
class DetailSidebar extends Component {
public render(): ReactElement<HTMLElement> {
return <DetailContextConsumer>{context => this.renderSideBar(context as VersionPageConsumerProps)}</DetailContextConsumer>;
}
const renderCopyCLI = () => <Install />;
const renderMaintainers = () => <Developers type="maintainers" />;
const renderContributors = () => <Developers type="contributors" />;
const renderRepository = () => <Repository />;
const renderAuthor = () => <Author />;
const renderEngine = () => <Engine />;
const renderDist = () => <Dist />;
const renderActionBar = () => <ActionBar />;
const renderTitle = (packageName, packageMeta) => {
return (
<List className="detail-info">
<TitleListItem alignItems="flex-start">
<TitleListItemText primary={<b>{packageName}</b>} secondary={packageMeta.latest.description} />
</TitleListItem>
</List>
);
};
private renderSideBar = ({ packageName, packageMeta }): ReactElement<HTMLElement> => {
return (
<div className={'sidebar-info'}>
<Card>
<CardContent>
{this.renderTitle(packageName, packageMeta)}
{this.renderActionBar()}
{this.renderCopyCLI()}
{this.renderRepository()}
{this.renderEngine()}
{this.renderDist()}
{this.renderAuthor()}
{this.renderMaintainers()}
{this.renderContributors()}
</CardContent>
</Card>
</div>
);
};
private renderTitle = (packageName, packageMeta) => {
return (
<List className="detail-info">
<TitleListItem alignItems="flex-start">
<TitleListItemText primary={<b>{packageName}</b>} secondary={packageMeta.latest.description} />
</TitleListItem>
</List>
);
};
private renderCopyCLI = () => {
return <Install />;
};
private renderMaintainers = () => {
return <Developers type="maintainers" />;
};
private renderContributors = () => {
return <Developers type="contributors" />;
};
private renderRepository = () => {
return <Repository />;
};
private renderAuthor = () => {
return <Author />;
};
private renderEngine = () => {
return <Engine />;
};
private renderDist = () => {
return <Dist />;
};
private renderActionBar = () => {
return <ActionBar />;
};
function renderSideBar(packageName, packageMeta): ReactElement<HTMLElement> {
return (
<div className={'sidebar-info'}>
<Card>
<CardContent>
{renderTitle(packageName, packageMeta)}
{renderActionBar()}
{renderCopyCLI()}
{renderRepository()}
{renderEngine()}
{renderDist()}
{renderAuthor()}
{renderMaintainers()}
{renderContributors()}
</CardContent>
</Card>
</div>
);
}
const DetailSidebar = () => {
const { packageName, packageMeta } = React.useContext(DetailContext);
return renderSideBar(packageName, packageMeta);
};
export default DetailSidebar;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { mount } from 'enzyme';
import Developers, { DevelopersType } from './Developers';
import { Fab } from './styles';
import { DetailContextProvider } from '../../pages/version/Version';
import { DetailContextProvider } from '../../pages/Version';
describe('test Developers', () => {
const packageMeta = {

View File

@@ -1,7 +1,7 @@
import React, { FC, Fragment } from 'react';
import Add from '@material-ui/icons/Add';
import { DetailContext } from '../../pages/version/Version';
import { DetailContext } from '../../pages/Version';
import { AvatarTooltip } from '../AvatarTooltip';
import { Details, Heading, Content, Fab } from './styles';

View File

@@ -18,7 +18,7 @@ describe('<Dist /> component', () => {
license: '',
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -41,7 +41,7 @@ describe('<Dist /> component', () => {
license: 'MIT',
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -67,7 +67,7 @@ describe('<Dist /> component', () => {
},
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},

View File

@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import List from '@material-ui/core/List';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { VersionPageConsumerProps, DetailContextConsumer } from '../../pages/Version';
import { Heading, DistListItem, DistChips } from './styles';
import fileSizeSI from '../../utils/file-size';
import { PackageMetaInterface } from 'types/packageMeta';

View File

@@ -19,7 +19,7 @@ describe('<Engines /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -35,7 +35,7 @@ describe('<Engines /> component', () => {
latest: {},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -53,7 +53,7 @@ describe('<Engines /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},

View File

@@ -5,7 +5,7 @@ import Grid from '@material-ui/core/Grid';
import List from '@material-ui/core/List';
import ListItemText from '@material-ui/core/ListItemText';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { VersionPageConsumerProps, DetailContextConsumer } from '../../pages/Version';
import { Heading, EngineListItem } from './styles';
// @ts-ignore
import node from './img/node.png';

View File

@@ -2,8 +2,8 @@ import List from '@material-ui/core/List';
import ListItemText from '@material-ui/core/ListItemText';
import React, { Component } from 'react';
// @ts-ignore
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/version/Version';
import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/Version';
import CopyToClipBoard from '../CopyToClipBoard';
// logos of package managers

View File

@@ -6,7 +6,7 @@ import Spinner from '../Spinner';
import { Wrapper, Badge } from './styles';
const Loading: React.FC = () => (
<Wrapper>
<Wrapper data-testid="loading">
<Badge>
<Logo size={Size.Big} />
</Badge>

View File

@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Loading /> component should render the component in default state 1`] = `"<div class=\\"css-1221txa eimgwje0\\"><div class=\\"css-bxochs eimgwje1\\"><div class=\\"css-ge0nak em793ed0\\"></div></div><div class=\\"css-vqrgi e1ag4h8b0\\"><div class=\\"MuiCircularProgress-root-1 MuiCircularProgress-colorPrimary-4 MuiCircularProgress-indeterminate-3 css-15gl0ho e1ag4h8b1\\" style=\\"width:50px;height:50px\\" role=\\"progressbar\\"><svg class=\\"MuiCircularProgress-svg-6\\" viewBox=\\"22 22 44 44\\"><circle class=\\"MuiCircularProgress-circle-7 MuiCircularProgress-circleIndeterminate-9\\" cx=\\"44\\" cy=\\"44\\" r=\\"20.2\\" fill=\\"none\\" stroke-width=\\"3.6\\"></circle></svg></div></div></div>"`;
exports[`<Loading /> component should render the component in default state 1`] = `"<div data-testid=\\"loading\\" class=\\"css-1221txa eimgwje0\\"><div class=\\"css-bxochs eimgwje1\\"><div class=\\"css-ge0nak em793ed0\\"></div></div><div class=\\"css-vqrgi e1ag4h8b0\\"><div class=\\"MuiCircularProgress-root-1 MuiCircularProgress-colorPrimary-4 MuiCircularProgress-indeterminate-3 css-15gl0ho e1ag4h8b1\\" style=\\"width:50px;height:50px\\" role=\\"progressbar\\"><svg class=\\"MuiCircularProgress-svg-6\\" viewBox=\\"22 22 44 44\\"><circle class=\\"MuiCircularProgress-circle-7 MuiCircularProgress-circleIndeterminate-9\\" cx=\\"44\\" cy=\\"44\\" r=\\"20.2\\" fill=\\"none\\" stroke-width=\\"3.6\\"></circle></svg></div></div></div>"`;

View File

@@ -1,46 +1,43 @@
import ListItem from '@material-ui/core/ListItem';
import Typography from '@material-ui/core/Typography';
import withWidth, { isWidthUp } from '@material-ui/core/withWidth';
import React from 'react';
import React, { useCallback } from 'react';
import { RouteComponentProps, withRouter } from 'react-router-dom';
import PackageImg from './img/package.svg';
import { Card, EmptyPackage, Heading, Inner, List, Wrapper } from './styles';
import { Breakpoint } from '@material-ui/core/styles/createBreakpoints';
export const NOT_FOUND_TEXT = "Sorry, we couldn't find it...";
export const NOT_FOUND_TEXT = `Sorry, we couldn't find it...`;
export const LABEL_NOT_FOUND = `The page you're looking for doesn't exist.`;
export const LABEL_FOOTER_NOT_FOUND = 'Perhaps these links will help find what you are looking for:';
export type NotFoundProps = RouteComponentProps & { width: Breakpoint; history };
const NotFound: React.FC<NotFoundProps> = ({ history, width }) => {
const handleGoTo = (to: string): (() => void | undefined) => () => {
history.push(to);
};
const HOME_LABEL = 'Home';
const handleGoBack = (): ((e: React.MouseEvent<HTMLElement, MouseEvent>) => void | undefined) => () => {
history.goBack();
};
const renderSubTitle = (): JSX.Element => (
<Typography variant="subtitle1">
<div>{LABEL_NOT_FOUND}</div>
<div>{LABEL_FOOTER_NOT_FOUND}</div>
</Typography>
);
const NotFound: React.FC<NotFoundProps> = ({ history, width }) => {
const handleGomHome = useCallback(() => {
history.push('/');
}, [history]);
const renderList = (): JSX.Element => (
<List>
<ListItem button={true} divider={true} onClick={handleGoTo('/')}>
{'Home'}
</ListItem>
<ListItem button={true} divider={true} onClick={handleGoBack()}>
{'Back'}
<ListItem button={true} divider={true} onClick={handleGomHome}>
{HOME_LABEL}
</ListItem>
</List>
);
const renderSubTitle = (): JSX.Element => (
<Typography variant="subtitle1">
<div>{"The page you're looking for doesn't exist."}</div>
<div>{'Perhaps these links will help find what you are looking for:'}</div>
</Typography>
);
return (
<Wrapper>
<Wrapper data-testid="404">
<Inner>
<EmptyPackage alt="404 - Page not found" src={PackageImg} />
<Heading className="not-found-text" variant={isWidthUp('sm', width) ? 'h2' : 'h4'}>

View File

@@ -18,7 +18,7 @@ describe('<Repository /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -34,7 +34,7 @@ describe('<Repository /> component', () => {
latest: {},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},
@@ -55,7 +55,7 @@ describe('<Repository /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},

View File

@@ -5,7 +5,7 @@ import Avatar from '@material-ui/core/Avatar';
import List from '@material-ui/core/List';
import ListItemText from '@material-ui/core/ListItemText';
import { DetailContextConsumer } from '../../pages/version/Version';
import { DetailContextConsumer } from '../../pages/Version';
import CopyToClipBoard from '../CopyToClipBoard';
import { Heading, GithubLink, RepositoryListItem } from './styles';

View File

@@ -2,7 +2,7 @@ import React, { ReactElement } from 'react';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import { DetailContextConsumer } from '../../pages/version/Version';
import { DetailContextConsumer } from '../../pages/Version';
import NoItems from '../NoItems';
import { formatDateDistance } from '../../utils/package';

View File

@@ -29,7 +29,7 @@ describe('<Version /> component', () => {
},
};
jest.doMock('../../pages/version/Version', () => ({
jest.doMock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ packageMeta });
},

View File

@@ -1,10 +1,11 @@
import { DetailContextConsumer } from '../../pages/version/Version';
import { formatDateDistance } from '../../utils/package';
import { Heading, Spacer, ListItemText } from './styles';
import React, { ReactElement } from 'react';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import React, { ReactElement } from 'react';
import { DetailContextConsumer } from '../../pages/Version';
import { formatDateDistance } from '../../utils/package';
import { DIST_TAGS } from '../../../lib/constants';
import { Heading, Spacer, ListItemText } from './styles';
const NOT_AVAILABLE = 'Not available';