Skip to content
This repository has been archived by the owner on Jan 16, 2022. It is now read-only.

Commit

Permalink
feat: version Component - Replaced classes by func. comp (#129)
Browse files Browse the repository at this point in the history
* refactor: replaced classes by func comp

* fix: fixed space margin

* refactor: changed display logic

* fix: fixed types

* fix: fixed Version test

* fix: fixed version style
  • Loading branch information
priscilawebdev authored and juanpicado committed Oct 3, 2019
1 parent 1a74c08 commit 1d705da
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 111 deletions.
46 changes: 13 additions & 33 deletions src/components/Versions/Versions.test.tsx
Original file line number Diff line number Diff line change
@@ -1,48 +1,39 @@
import React from 'react';
import { mount } from 'enzyme';
import { MemoryRouter } from 'react-router';
import { DetailContext, DetailContextProps } from '../../pages/Version';

import Versions, { LABEL_CURRENT_TAGS, LABEL_VERSION_HISTORY } from './Versions';
import data from './__partials__/data.json';

import { render, cleanup } from '@testing-library/react';

const mockPackageMeta = jest.fn(() => ({
const detailContextValue: Partial<DetailContextProps> = {
packageName: 'foo',
packageMeta: data,
}));
};

jest.mock('../../pages/Version', () => ({
DetailContextConsumer: component => {
return component.children({ ...mockPackageMeta() });
},
}));
const ComponentToBeRendered: React.FC<{ contextValue: Partial<DetailContextProps> }> = ({ contextValue }) => (
<MemoryRouter>
<DetailContext.Provider value={contextValue}>
<Versions />
</DetailContext.Provider>
</MemoryRouter>
);

describe('<Version /> component', () => {
beforeEach(() => {
jest.resetModules();
});

afterEach(() => {
cleanup();
});

// FIXME: this test is not deterministic (writes `N days ago` in the snapshot, where N is random number)
test.skip('should render the component in default state', () => {
const wrapper = mount(
<MemoryRouter>
<Versions />
</MemoryRouter>
);
const wrapper = mount(<ComponentToBeRendered contextValue={detailContextValue} />);
expect(wrapper.html()).toMatchSnapshot();
});

test('should render versions', () => {
const { getByText } = render(
<MemoryRouter>
<Versions />
</MemoryRouter>
);
const { getByText } = render(<ComponentToBeRendered contextValue={detailContextValue} />);

expect(getByText(LABEL_VERSION_HISTORY)).toBeTruthy();
expect(getByText(LABEL_CURRENT_TAGS)).toBeTruthy();
Expand All @@ -53,18 +44,7 @@ describe('<Version /> component', () => {
});

test('should not render versions', () => {
const request = {
packageName: 'foo',
};

// @ts-ignore
mockPackageMeta.mockImplementation(() => request);

const { queryByText } = render(
<MemoryRouter>
<Versions />
</MemoryRouter>
);
const { queryByText } = render(<ComponentToBeRendered contextValue={{ packageName: detailContextValue.packageName }} />);

expect(queryByText(LABEL_VERSION_HISTORY)).toBeFalsy();
expect(queryByText(LABEL_CURRENT_TAGS)).toBeFalsy();
Expand Down
110 changes: 33 additions & 77 deletions src/components/Versions/Versions.tsx
Original file line number Diff line number Diff line change
@@ -1,90 +1,46 @@
import React, { ReactElement } from 'react';
import List from '@material-ui/core/List';
import { Link as RouterLink } from 'react-router-dom';
import Link from '@material-ui/core/Link';
import ListItem from '@material-ui/core/ListItem';
import React, { useContext } from 'react';

import { DetailContextConsumer } from '../../pages/Version';
import { formatDateDistance } from '../../utils/package';
import { DIST_TAGS } from '../../../lib/constants';
import { DetailContext } from '../../pages/Version';

import { Heading } from './styles';

import { Heading, Spacer, ListItemText } from './styles';
import VersionsTagList from './VersionsTagList';
import VersionsHistoryList from './VersionsHistoryList';

import { DIST_TAGS } from '../../../lib/constants';

export const NOT_AVAILABLE = 'Not available';
export const LABEL_CURRENT_TAGS = 'Current Tags';
export const LABEL_VERSION_HISTORY = 'Version History';

class Versions extends React.PureComponent {
public render(): ReactElement<HTMLDivElement> {
return (
<DetailContextConsumer>
{context => {
const { packageMeta, packageName } = context;
const Versions: React.FC = () => {
const detailContext = useContext(DetailContext);

if (!packageMeta) {
return null;
}
const { packageMeta, packageName } = detailContext;

return this.renderContent(packageMeta, packageName);
}}
</DetailContextConsumer>
);
if (!packageMeta) {
return null;
}

public renderPackageList = (packages: {}, timeMap: Record<string, {}>, packageName): ReactElement<HTMLDivElement> => {
return (
<List dense={true}>
{Object.keys(packages)
.reverse()
.map(version => (
<ListItem className="version-item" key={version}>
<Link component={RouterLink} to={`/-/web/detail/${packageName}/v/${version}`}>
<ListItemText>{version}</ListItemText>
</Link>
<Spacer />
<ListItemText>{timeMap[version] ? `${formatDateDistance(timeMap[version])} ago` : NOT_AVAILABLE}</ListItemText>
</ListItem>
))}
</List>
);
};

public renderTagList = (packages: {}): ReactElement<HTMLDivElement> => {
return (
<List dense={true}>
{Object.keys(packages)
.reverse()
.map(tag => (
<ListItem className="version-item" key={tag}>
<ListItemText>{tag}</ListItemText>
<Spacer />
<ListItemText>{packages[tag]}</ListItemText>
</ListItem>
))}
</List>
);
};

public renderContent(packageMeta, packageName): ReactElement<HTMLDivElement> {
const { versions = {}, time: timeMap = {}, [DIST_TAGS]: distTags = {} } = packageMeta;

return (
<>
{distTags && (
<>
<Heading variant="subtitle1">{LABEL_CURRENT_TAGS}</Heading>
{this.renderTagList(distTags)}
</>
)}
{versions && (
<>
<Heading variant="subtitle1">{LABEL_VERSION_HISTORY}</Heading>
{this.renderPackageList(versions, timeMap, packageName)}
</>
)}
</>
);
}
}
// @ts-ignore - Property 'dist-tags' does not exist on type 'PackageMetaInterface'
const { versions = {}, time = {}, [DIST_TAGS]: distTags = {} } = packageMeta;

return (
<>
{distTags && Object.keys(distTags).length > 0 && (
<>
<Heading variant="subtitle1">{LABEL_CURRENT_TAGS}</Heading>
<VersionsTagList tags={distTags} />
</>
)}
{versions && Object.keys(versions).length > 0 && packageName && (
<>
<Heading variant="subtitle1">{LABEL_VERSION_HISTORY}</Heading>
<VersionsHistoryList packageName={packageName} time={time} versions={versions} />
</>
)}
</>
);
};

export default Versions;
35 changes: 35 additions & 0 deletions src/components/Versions/VersionsHistoryList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import List from '@material-ui/core/List';
import Link from '@material-ui/core/Link';
import ListItem from '@material-ui/core/ListItem';
import { Link as RouterLink } from 'react-router-dom';
import { Spacer, ListItemText } from './styles';

import { Versions, Time } from '../../../types/packageMeta';
import { formatDateDistance } from '../../utils/package';

export const NOT_AVAILABLE = 'Not available';

interface Props {
versions: Versions;
packageName: string;
time: Time;
}

const VersionsHistoryList: React.FC<Props> = ({ versions, packageName, time }) => (
<List dense={true}>
{Object.keys(versions)
.reverse()
.map(version => (
<ListItem className="version-item" key={version}>
<Link component={RouterLink} to={`/-/web/detail/${packageName}/v/${version}`}>
<ListItemText>{version}</ListItemText>
</Link>
<Spacer />
<ListItemText>{time[version] ? `${formatDateDistance(time[version])} ago` : NOT_AVAILABLE}</ListItemText>
</ListItem>
))}
</List>
);

export default VersionsHistoryList;
26 changes: 26 additions & 0 deletions src/components/Versions/VersionsTagList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
import { Spacer, ListItemText } from './styles';

import { DistTags } from '../../../types/packageMeta';

interface Props {
tags: DistTags;
}

const VersionsTagList: React.FC<Props> = ({ tags }) => (
<List dense={true}>
{Object.keys(tags)
.reverse()
.map(tag => (
<ListItem className="version-item" key={tag}>
<ListItemText>{tag}</ListItemText>
<Spacer />
<ListItemText>{tags[tag]}</ListItemText>
</ListItem>
))}
</List>
);

export default VersionsTagList;

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/components/Versions/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const Spacer = styled('div')({
borderBottom: '1px dotted rgba(0, 0, 0, 0.2)',
whiteSpace: 'nowrap',
height: '0.5em',
margin: '0 16px',
});

export const ListItemText = styled(MuiListItemText)({
Expand Down
37 changes: 37 additions & 0 deletions types/packageMeta.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export interface PackageMetaInterface {
versions?: Versions;
distTags?: DistTags;
time?: Time;
latest: {
name: string;
dist: {
Expand All @@ -14,3 +17,37 @@ interface LicenseInterface {
type: string;
url: string;
}

export interface DistTags {
[key: string]: string;
}

export interface Time {
[key: string]: string;
}

export interface Versions {
[key: string]: Version;
}

export interface Version {
name: string;
version: string;
author?: string | Author;
maintainers?: Maintainer[];
description?: string;
license?: string;
main?: string;
keywords?: string[];
}

interface Author {
name?: string;
email?: string;
url?: string;
}

interface Maintainer {
email?: string;
name?: string;
}

0 comments on commit 1d705da

Please sign in to comment.