mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
refactor: <Package /> , <Footer /> and package sidebar code refactoring
refactor: variable naming
This commit is contained in:
parent
4a6383d05f
commit
263b0f78a9
33 changed files with 605 additions and 353 deletions
|
@ -42,7 +42,8 @@ module.exports = {
|
|||
moduleNameMapper: {
|
||||
'\\.(scss)$': '<rootDir>/node_modules/identity-obj-proxy',
|
||||
'github-markdown-css': '<rootDir>/node_modules/identity-obj-proxy',
|
||||
'\\.(png)$': '<rootDir>/node_modules/identity-obj-proxy'
|
||||
'\\.(png)$': '<rootDir>/node_modules/identity-obj-proxy',
|
||||
'\\.(svg)$': '<rootDir>/test/unit/empty.js'
|
||||
},
|
||||
transformIgnorePatterns: [
|
||||
'<rootDir>/node_modules/(?!react-syntax-highlighter)'
|
||||
|
|
|
@ -10,14 +10,7 @@
|
|||
},
|
||||
"rules": {
|
||||
"require-jsdoc": 0,
|
||||
"no-console": [
|
||||
1,
|
||||
{
|
||||
"allow": [
|
||||
"log"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-console": 2,
|
||||
"no-unused-vars": [
|
||||
2,
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, {Component} from 'react';
|
||||
|
||||
import classes from './footer.scss';
|
||||
import logo from './logo.svg';
|
||||
|
@ -12,7 +12,7 @@ import nicaraguaFlag from './flags/nicaragua-1f1f3-1f1ee.svg';
|
|||
import pakistanFlag from './flags/pakistan-1f1f5-1f1f0.svg';
|
||||
import spainFlag from './flags/spain-1f1ea-1f1f8.svg';
|
||||
|
||||
export default class Footer extends React.Component {
|
||||
export default class Footer extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.handleEarthIconClick = this.handleEarthIconClick.bind(this);
|
||||
|
|
|
@ -2,81 +2,51 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import {Tag} from 'element-react';
|
||||
import {Link} from 'react-router-dom';
|
||||
import isNil from 'lodash/isNil';
|
||||
import {formatDateDistance} from '../../utils/DateUtils';
|
||||
|
||||
import {formatDateDistance} from '../../utils/package';
|
||||
|
||||
import classes from './package.scss';
|
||||
|
||||
export default class Package extends React.Component {
|
||||
static propTypes = {
|
||||
package: PropTypes.object
|
||||
}
|
||||
|
||||
render() {
|
||||
const {package: pkg} = this.props;
|
||||
|
||||
return (
|
||||
<section className={classes.package}>
|
||||
<Link to={`detail/${pkg.name}`}>
|
||||
<div className={classes.header}>
|
||||
{this.renderTitle(pkg)}
|
||||
{this.renderAuthor(pkg)}
|
||||
</div>
|
||||
<div className={classes.footer}>
|
||||
{this.renderDescription(pkg)}
|
||||
</div>
|
||||
<div className={classes.details}>
|
||||
{this.renderPublished(pkg)}
|
||||
{this.renderLicense(pkg)}
|
||||
</div>
|
||||
</Link>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
renderPublished(pkg) {
|
||||
return (<div className={classes.homepage}>
|
||||
{pkg.time ? `Published ${formatDateDistance(pkg.time)} ago`: ''}
|
||||
</div>);
|
||||
}
|
||||
|
||||
renderLicense(pkg) {
|
||||
if (pkg.license) {
|
||||
return (<div className={classes.license}>
|
||||
{pkg.license}
|
||||
</div>);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
renderDescription(pkg) {
|
||||
return (
|
||||
<p className={classes.description}>
|
||||
{pkg.description}
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
renderTitle(pkg) {
|
||||
return (
|
||||
<div className={classes.title}>
|
||||
<h1>
|
||||
{pkg.name} {this.renderTag(pkg)}
|
||||
</h1>
|
||||
const Package = ({name, version, author, description, license, time}) => {
|
||||
return (<section className={classes.package}>
|
||||
<Link to={`detail/${name}`}>
|
||||
<div className={classes.header}>
|
||||
<div className={classes.title}>
|
||||
<h1>
|
||||
{name} <Tag type="gray">v{version}</Tag>
|
||||
</h1>
|
||||
</div>
|
||||
<div role="author" className={classes.author}>
|
||||
{ author ? `By: ${author}`: ''}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
<div className={classes.footer}>
|
||||
<p className={classes.description}>
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
<div className={classes.details}>
|
||||
<div className={classes.homepage}>
|
||||
{time ? `Published ${formatDateDistance(time)} ago` : ''}
|
||||
</div>
|
||||
<div className={classes.license}>
|
||||
{license}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</section>);
|
||||
};
|
||||
|
||||
renderTag(pkg) {
|
||||
return <Tag type="gray">v{pkg.version}</Tag>;
|
||||
}
|
||||
Package.propTypes = {
|
||||
name: PropTypes.string,
|
||||
version: PropTypes.string,
|
||||
author: PropTypes.string,
|
||||
description: PropTypes.string,
|
||||
license: PropTypes.string,
|
||||
time: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.instanceOf(Date)
|
||||
])
|
||||
};
|
||||
|
||||
renderAuthor(pkg) {
|
||||
if (isNil(pkg.author) || isNil(pkg.author.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return <div role="author" className={classes.author}>{`By: ${pkg.author.name}`}</div>;
|
||||
}
|
||||
}
|
||||
export default Package;
|
||||
|
|
|
@ -6,27 +6,22 @@ import Readme from '../Readme';
|
|||
|
||||
import classes from './packageDetail.scss';
|
||||
|
||||
const PackageDetail = (props) => {
|
||||
const displayState = (readMe) => {
|
||||
if (isNil(readMe)) {
|
||||
return;
|
||||
}
|
||||
return <Readme readMe={readMe}/>;
|
||||
};
|
||||
const displayState = (readMe) => {
|
||||
return !isNil(readMe) ? <Readme readMe={readMe} /> : '';
|
||||
};
|
||||
|
||||
const PackageDetail = ({packageName, readMe}) => {
|
||||
return (
|
||||
<div className={classes.pkgDetail}>
|
||||
<h1 className={ classes.title }>{ props.package }</h1>
|
||||
<div className={classes.readme}>
|
||||
{displayState(props.readMe)}
|
||||
</div>
|
||||
<h1 className={classes.title}>{packageName}</h1>
|
||||
<div className={classes.readme}>{displayState(readMe)}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
PackageDetail.propTypes = {
|
||||
readMe: PropTypes.string,
|
||||
package: PropTypes.string.isRequired
|
||||
packageName: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
export default PackageDetail;
|
||||
|
|
|
@ -5,6 +5,7 @@ import isEmpty from 'lodash/isEmpty';
|
|||
import Package from '../Package';
|
||||
import Help from '../Help';
|
||||
import NoItems from '../NoItems';
|
||||
import {formatAuthor, formatLicense} from '../../utils/package';
|
||||
|
||||
import classes from './packageList.scss';
|
||||
|
||||
|
@ -12,14 +13,14 @@ export default class PackageList extends React.Component {
|
|||
static propTypes = {
|
||||
packages: PropTypes.array,
|
||||
help: PropTypes.bool
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="package-list-items">
|
||||
<div className={classes.pkgContainer}>
|
||||
{this.renderTitle()}
|
||||
{this.isTherePackages() ? this.renderList(): this.renderOptions()}
|
||||
{this.isTherePackages() ? this.renderList() : this.renderOptions()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -30,13 +31,20 @@ export default class PackageList extends React.Component {
|
|||
return;
|
||||
}
|
||||
|
||||
return <h1 className={ classes.listTitle }>Available Packages</h1>;
|
||||
return <h1 className={classes.listTitle}>Available Packages</h1>;
|
||||
}
|
||||
|
||||
renderList() {
|
||||
return this.props.packages.map((pkg, i)=> (
|
||||
<li key={i}><Package package={pkg} /></li>
|
||||
));
|
||||
return this.props.packages.map((pkg, i) => {
|
||||
const {name, version, description, time} = pkg;
|
||||
const author = formatAuthor(pkg.author);
|
||||
const license = formatLicense(pkg.license);
|
||||
return (
|
||||
<li key={i}>
|
||||
<Package {...{name, version, author, description, license, time}} />
|
||||
</li>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
renderOptions() {
|
||||
|
@ -48,14 +56,19 @@ export default class PackageList extends React.Component {
|
|||
}
|
||||
|
||||
renderNoItems() {
|
||||
return <NoItems className="package-no-items" text={'No items were found with that query'}/>;
|
||||
return (
|
||||
<NoItems
|
||||
className="package-no-items"
|
||||
text={'No items were found with that query'}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
renderHelp() {
|
||||
if (this.props.help === false) {
|
||||
return;
|
||||
}
|
||||
return <Help/>;
|
||||
return <Help />;
|
||||
}
|
||||
|
||||
isTherePackages() {
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import get from 'lodash/get';
|
||||
import LastSync from './modules/LastSync';
|
||||
import Maintainers from './modules/Maintainers';
|
||||
import Dependencies from './modules/Dependencies';
|
||||
import Infos from './modules/Infos';
|
||||
|
||||
import {
|
||||
formatLicense,
|
||||
formatRepository,
|
||||
getLastUpdatedPackageTime,
|
||||
getRecentReleases
|
||||
} from '../../utils/package';
|
||||
import API from '../../utils/api';
|
||||
|
||||
export default class PackageSidebar extends React.Component {
|
||||
|
@ -23,7 +30,7 @@ export default class PackageSidebar extends React.Component {
|
|||
await this.loadPackageData(this.props.packageName);
|
||||
}
|
||||
|
||||
async componentWillReceiveProps(newProps) {
|
||||
async UNSAFE_componentWillReceiveProps(newProps) {
|
||||
if (newProps.packageName !== this.props.packageName) {
|
||||
await this.loadPackageData(newProps.packageName);
|
||||
}
|
||||
|
@ -38,7 +45,6 @@ export default class PackageSidebar extends React.Component {
|
|||
this.setState({
|
||||
failed: true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -49,14 +55,46 @@ export default class PackageSidebar extends React.Component {
|
|||
render() {
|
||||
let {packageMeta} = this.state;
|
||||
|
||||
return packageMeta ?
|
||||
(<aside className="sidebar-info">
|
||||
<LastSync packageMeta={packageMeta} />
|
||||
<Infos packageMeta={packageMeta} />
|
||||
<Maintainers packageMeta={packageMeta} />
|
||||
<Dependencies packageMeta={packageMeta} />
|
||||
{/* Package management module? Help us implement it! */}
|
||||
</aside>):
|
||||
(<aside className="sidebar-loading">Loading package information...</aside>);
|
||||
if (packageMeta) {
|
||||
const {time, _uplinks} = packageMeta;
|
||||
|
||||
// Infos component
|
||||
const license = formatLicense(get(packageMeta, 'latest.license', null));
|
||||
const repository = formatRepository(
|
||||
get(packageMeta, 'latest.repository', null)
|
||||
);
|
||||
const homepage = get(packageMeta, 'latest.homepage', null);
|
||||
|
||||
// Lastsync component
|
||||
const recentReleases = getRecentReleases(time);
|
||||
const lastUpdated = getLastUpdatedPackageTime(_uplinks);
|
||||
|
||||
// Dependencies component
|
||||
const dependencies = get(packageMeta, 'latest.dependencies', {});
|
||||
|
||||
// Maintainers component
|
||||
return (
|
||||
<aside className="sidebar-info">
|
||||
{time && (
|
||||
<LastSync
|
||||
recentReleases={recentReleases}
|
||||
lastUpdated={lastUpdated}
|
||||
/>
|
||||
)}
|
||||
<Infos
|
||||
homepage={homepage}
|
||||
repository={repository}
|
||||
license={license}
|
||||
/>
|
||||
{/* TODO: Refacor later, when we decide to show only maintainers/authors */}
|
||||
<Maintainers packageMeta={packageMeta} />
|
||||
<Dependencies dependencies={dependencies} />
|
||||
{/* Package management module? Help us implement it! */}
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<aside className="sidebar-loading">Loading package information...</aside>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,47 +1,46 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import get from 'lodash/get';
|
||||
import Module from '../../Module';
|
||||
|
||||
import classes from './style.scss';
|
||||
import {getDetailPageURL} from '../../../../utils/url';
|
||||
import ModuleContentPlaceholder from '../../ModuleContentPlaceholder';
|
||||
|
||||
export default class Dependencies extends React.Component {
|
||||
static propTypes = {
|
||||
packageMeta: PropTypes.object.isRequired
|
||||
};
|
||||
import classes from './style.scss';
|
||||
|
||||
get dependencies() {
|
||||
return get(this, 'props.packageMeta.latest.dependencies', {});
|
||||
}
|
||||
const renderDependenciesList = (dependencies, dependenciesList) => {
|
||||
return (
|
||||
<ul>
|
||||
{dependenciesList.map((dependenceName, index) => {
|
||||
return (
|
||||
<li
|
||||
className="dependency-item"
|
||||
key={index}
|
||||
title={`Depend on version: ${dependencies[dependenceName]}`}
|
||||
>
|
||||
<a href={getDetailPageURL(dependenceName)}>{dependenceName}</a>
|
||||
{index < dependenciesList.length - 1 && <span>, </span>}
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
let dependencies = this.dependencies;
|
||||
let dependenciesList = Object.keys(dependencies);
|
||||
const Dependencies = ({dependencies = {}}) => {
|
||||
const dependenciesList = Object.keys(dependencies);
|
||||
return (
|
||||
<Module title="Dependencies" className={classes.dependenciesModule}>
|
||||
{dependenciesList.length > 1 ? (
|
||||
renderDependenciesList(dependencies, dependenciesList)
|
||||
) : (
|
||||
<ModuleContentPlaceholder text="Zero Dependencies!" />
|
||||
)}
|
||||
</Module>
|
||||
);
|
||||
};
|
||||
|
||||
if (!dependenciesList.length) {
|
||||
return <ModuleContentPlaceholder text="Zero Dependencies!"/>;
|
||||
}
|
||||
Dependencies.propTypes = {
|
||||
dependencies: PropTypes.object
|
||||
};
|
||||
|
||||
return (
|
||||
<Module
|
||||
title="Dependencies"
|
||||
className={classes.dependenciesModule}
|
||||
>
|
||||
<ul>
|
||||
{
|
||||
dependenciesList.map((dependenceName, index) => {
|
||||
return (
|
||||
<li className="dependency-item" key={index} title={`Depend on version: ${dependencies[dependenceName]}`}>
|
||||
<a href={getDetailPageURL(dependenceName)}>{dependenceName}</a>
|
||||
{index < dependenciesList.length - 1 && <span>, </span>}
|
||||
</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
</Module>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default Dependencies;
|
||||
|
|
|
@ -1,69 +1,37 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import get from 'lodash/get';
|
||||
import Module from '../../Module';
|
||||
import isString from 'lodash/isString';
|
||||
import isNil from 'lodash/isNil';
|
||||
import ModuleContentPlaceholder from '../../ModuleContentPlaceholder';
|
||||
|
||||
import classes from './style.scss';
|
||||
|
||||
export default class Infos extends React.Component {
|
||||
static propTypes = {
|
||||
packageMeta: PropTypes.object.isRequired
|
||||
};
|
||||
const renderSection = (title, url) => (
|
||||
<li>
|
||||
<span>{title}</span>
|
||||
<a href={url} target="_blank">
|
||||
{url}
|
||||
</a>
|
||||
</li>
|
||||
);
|
||||
|
||||
get infos() {
|
||||
const homepage = this.normalizeInfo(get(this, 'props.packageMeta.latest.homepage', null));
|
||||
const repo = this.normalizeInfo(get(this, 'props.packageMeta.latest.repository', null));
|
||||
const license = get(this, 'props.packageMeta.latest.license', 'N/A');
|
||||
const Infos = ({homepage, repository, license}) => {
|
||||
const showInfo = homepage || repository || license;
|
||||
return <Module title="Infos" className={classes.infosModule}>
|
||||
{showInfo ? <ul>
|
||||
{homepage && renderSection('Homepage', homepage)}
|
||||
{repository && renderSection('Repository', repository)}
|
||||
{license && <li>
|
||||
<span>License</span>
|
||||
<span>{license}</span>
|
||||
</li>}
|
||||
</ul> : <ModuleContentPlaceholder text="Not Available!" />}
|
||||
</Module>;
|
||||
};
|
||||
|
||||
return {homepage, repo, license};
|
||||
}
|
||||
Infos.propTypes = {
|
||||
homepage: PropTypes.string,
|
||||
repository: PropTypes.string,
|
||||
license: PropTypes.string
|
||||
};
|
||||
|
||||
normalizeInfo(infoObj) {
|
||||
if (isString(infoObj)) {
|
||||
return {url: infoObj};
|
||||
} else if (isNil(infoObj)) {
|
||||
return {url: ''};
|
||||
}
|
||||
|
||||
infoObj.url = this.normalizeGitUrl(infoObj);
|
||||
|
||||
return infoObj;
|
||||
}
|
||||
|
||||
normalizeGitUrl(infoObj) {
|
||||
return infoObj.url.replace(/^git\+/, '');
|
||||
}
|
||||
|
||||
render() {
|
||||
const infos = this.infos;
|
||||
|
||||
if (infos.homepage.url === '' && infos.repo.url === '' && infos.license === 'N/A') {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<Module
|
||||
title="Infos"
|
||||
className={classes.infosModule}
|
||||
>
|
||||
<ul>
|
||||
{infos.homepage.url && this.renderSection('Homepage', infos.homepage.url)}
|
||||
|
||||
{infos.repo.url && this.renderSection('Repository', infos.repo.url)}
|
||||
|
||||
{infos.license &&
|
||||
<li><span>License</span><span>{infos.license}</span></li>
|
||||
}
|
||||
</ul>
|
||||
</Module>
|
||||
);
|
||||
}
|
||||
|
||||
renderSection(title, url) {
|
||||
return (
|
||||
<li><span>{title}</span><a href={url} target="_blank">{url}</a></li>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default Infos;
|
||||
|
|
|
@ -1,61 +1,45 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import propTypes from 'prop-types';
|
||||
import Module from '../../Module';
|
||||
import {formatDate} from '../../../../utils/DateUtils';
|
||||
import ModuleContentPlaceholder from '../../ModuleContentPlaceholder';
|
||||
|
||||
import classes from './style.scss';
|
||||
|
||||
export default class LastSync extends React.Component {
|
||||
static propTypes = {
|
||||
packageMeta: PropTypes.object.isRequired
|
||||
};
|
||||
const renderRecentReleases = (recentReleases) => {
|
||||
return (
|
||||
<ul>
|
||||
{recentReleases.map((versionInfo) => {
|
||||
const {version, time} = versionInfo;
|
||||
return (
|
||||
<li className="last-sync-item" key={version}>
|
||||
<span>{version}</span>
|
||||
<span>{time}</span>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
get lastUpdate() {
|
||||
let lastUpdate = 0;
|
||||
Object.keys(this.props.packageMeta._uplinks).forEach((upLinkName) => {
|
||||
const status = this.props.packageMeta._uplinks[upLinkName];
|
||||
const LastSync = ({recentReleases = [], lastUpdated = ''}) => {
|
||||
return (
|
||||
<Module
|
||||
title="Last Sync"
|
||||
description={lastUpdated}
|
||||
className={classes.releasesModule}
|
||||
>
|
||||
{recentReleases.length ? (
|
||||
renderRecentReleases(recentReleases)
|
||||
) : (
|
||||
<ModuleContentPlaceholder text="Not Available!" />
|
||||
)}
|
||||
</Module>
|
||||
);
|
||||
};
|
||||
|
||||
if (status.fetched > lastUpdate) {
|
||||
lastUpdate = status.fetched;
|
||||
}
|
||||
});
|
||||
LastSync.propTypes = {
|
||||
recentReleases: propTypes.array,
|
||||
lastUpdated: propTypes.string
|
||||
};
|
||||
|
||||
const time = formatDate(lastUpdate);
|
||||
|
||||
return lastUpdate ? time : '';
|
||||
}
|
||||
|
||||
get recentReleases() {
|
||||
let recentReleases = Object.keys(this.props.packageMeta.time).map((version) => {
|
||||
const time = formatDate(this.props.packageMeta.time[version]);
|
||||
return {version, time};
|
||||
});
|
||||
|
||||
return recentReleases.slice(recentReleases.length - 3, recentReleases.length).reverse();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.packageMeta.time) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Module
|
||||
title="Last Sync"
|
||||
description={this.lastUpdate}
|
||||
className={classes.releasesModule}
|
||||
>
|
||||
<ul>
|
||||
{this.recentReleases.map((versionInfo) => {
|
||||
return (
|
||||
<li className="last-sync-item" key={versionInfo.version}>
|
||||
<span>{versionInfo.version}</span>
|
||||
<span>{versionInfo.time}</span>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</Module>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default LastSync;
|
||||
|
|
|
@ -3,11 +3,16 @@ import PropTypes from 'prop-types';
|
|||
import get from 'lodash/get';
|
||||
import filter from 'lodash/filter';
|
||||
import size from 'lodash/size';
|
||||
import has from 'lodash/has';
|
||||
import uniqBy from 'lodash/uniqBy';
|
||||
|
||||
import Module from '../../Module';
|
||||
import MaintainerInfo from './MaintainerInfo';
|
||||
import ModuleContentPlaceholder from '../../ModuleContentPlaceholder';
|
||||
|
||||
import classes from './style.scss';
|
||||
import MaintainerInfo from './MaintainerInfo';
|
||||
|
||||
const CONTRIBUTORS_TO_SHOW = 5;
|
||||
|
||||
export default class Maintainers extends React.Component {
|
||||
static propTypes = {
|
||||
|
@ -44,7 +49,10 @@ export default class Maintainers extends React.Component {
|
|||
return [];
|
||||
}
|
||||
|
||||
return uniqBy(this.contributors, (contributor) => contributor.name).slice(0, 5);
|
||||
return uniqBy(this.contributors, (contributor) => contributor.name).slice(
|
||||
0,
|
||||
CONTRIBUTORS_TO_SHOW
|
||||
);
|
||||
}
|
||||
|
||||
handleShowAllContributors() {
|
||||
|
@ -56,26 +64,33 @@ export default class Maintainers extends React.Component {
|
|||
renderContributors() {
|
||||
if (!this.contributors) return null;
|
||||
|
||||
return (this.showAllContributors ? this.contributors : this.uniqueContributors)
|
||||
.map((contributor, index) => {
|
||||
return <MaintainerInfo
|
||||
return (this.showAllContributors
|
||||
? this.contributors
|
||||
: this.uniqueContributors
|
||||
).map((contributor, index) => {
|
||||
return (
|
||||
<MaintainerInfo
|
||||
key={index}
|
||||
title="Contributors"
|
||||
name={contributor.name}
|
||||
avatar={contributor.avatar}/>;
|
||||
});
|
||||
avatar={contributor.avatar}
|
||||
/>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
let author = this.author;
|
||||
|
||||
renderAuthorAndContributors(author) {
|
||||
return (
|
||||
<Module
|
||||
title="Maintainers"
|
||||
className={classes.maintainersModule}
|
||||
>
|
||||
<div>
|
||||
<ul className="maintainer-author">
|
||||
{author && <MaintainerInfo title="Author" name={author.name} avatar={author.avatar}/>}
|
||||
{author &&
|
||||
author.name && (
|
||||
<MaintainerInfo
|
||||
title="Author"
|
||||
name={author.name}
|
||||
avatar={author.avatar}
|
||||
/>
|
||||
)}
|
||||
{this.renderContributors()}
|
||||
</ul>
|
||||
{!this.showAllContributors && (
|
||||
|
@ -87,6 +102,20 @@ export default class Maintainers extends React.Component {
|
|||
Show all contributor
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
let author = this.author;
|
||||
const contributors = this.renderContributors();
|
||||
return (
|
||||
<Module title="Maintainers" className={classes.maintainersModule}>
|
||||
{contributors.length || has(author, 'name') ? (
|
||||
this.renderAuthorAndContributors(author)
|
||||
) : (
|
||||
<ModuleContentPlaceholder text="Not Available!" />
|
||||
)}
|
||||
</Module>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ export default class Detail extends React.Component {
|
|||
}
|
||||
return (
|
||||
<div className={classes.twoColumn}>
|
||||
<PackageDetail readMe={readMe} package={this.packageName}/>
|
||||
<PackageDetail readMe={readMe} packageName={this.packageName}/>
|
||||
<PackageSidebar packageName={this.packageName} />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
export const TIMEFORMAT = 'YYYY/MM/DD, HH:mm:ss';
|
||||
import format from 'date-fns/format';
|
||||
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
|
||||
|
||||
|
||||
export function formatDate(lastUpdate) {
|
||||
return format(new Date(lastUpdate), TIMEFORMAT);
|
||||
}
|
||||
|
||||
export function formatDateDistance(lastUpdate) {
|
||||
return distanceInWordsToNow(new Date(lastUpdate));
|
||||
}
|
92
src/webui/utils/package.js
Normal file
92
src/webui/utils/package.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
import isString from 'lodash/isString';
|
||||
import isObject from 'lodash/isObject';
|
||||
export const TIMEFORMAT = 'YYYY/MM/DD, HH:mm:ss';
|
||||
import format from 'date-fns/format';
|
||||
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
|
||||
|
||||
/**
|
||||
* Formats license field for webui.
|
||||
* @see https://docs.npmjs.com/files/package.json#license
|
||||
*/
|
||||
export function formatLicense(license) {
|
||||
if (isString(license)) {
|
||||
return license;
|
||||
}
|
||||
|
||||
if (isObject(license) && license.type) {
|
||||
return license.type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats repository field for webui.
|
||||
* @see https://docs.npmjs.com/files/package.json#repository
|
||||
*/
|
||||
export function formatRepository(repository) {
|
||||
if (isString(repository)) {
|
||||
return repository;
|
||||
}
|
||||
|
||||
if (isObject(repository) && repository.url) {
|
||||
return repository.url;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Formats author field for webui.
|
||||
* @see https://docs.npmjs.com/files/package.json#author
|
||||
*/
|
||||
export function formatAuthor(author) {
|
||||
if (isString(author)) {
|
||||
return author;
|
||||
}
|
||||
|
||||
if (isObject(author) && author.name) {
|
||||
return author.name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For <LastSync /> component
|
||||
* @param {array} uplinks
|
||||
*/
|
||||
export function getLastUpdatedPackageTime(uplinks = {}) {
|
||||
let lastUpdate = 0;
|
||||
Object.keys(uplinks).forEach((upLinkName) => {
|
||||
const status = uplinks[upLinkName];
|
||||
if (status.fetched > lastUpdate) {
|
||||
lastUpdate = status.fetched;
|
||||
}
|
||||
});
|
||||
|
||||
return lastUpdate ? formatDate(lastUpdate) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* For <LastSync /> component
|
||||
* @param {Object} time
|
||||
* @returns {Array} last 3 releases
|
||||
*/
|
||||
export function getRecentReleases(time = {}) {
|
||||
const recent = Object.keys(time).map((version) => ({
|
||||
version,
|
||||
time: formatDate(time[version])
|
||||
}));
|
||||
return recent.slice(recent.length - 3, recent.length).reverse();
|
||||
}
|
||||
|
||||
|
||||
export function formatDate(lastUpdate) {
|
||||
return format(new Date(lastUpdate), TIMEFORMAT);
|
||||
}
|
||||
|
||||
export function formatDateDistance(lastUpdate) {
|
||||
return distanceInWordsToNow(new Date(lastUpdate));
|
||||
}
|
1
test/unit/empty.js
Normal file
1
test/unit/empty.js
Normal file
|
@ -0,0 +1 @@
|
|||
export default {};
|
|
@ -7,3 +7,5 @@ import { configure } from 'enzyme';
|
|||
import Adapter from 'enzyme-adapter-react-16';
|
||||
|
||||
configure({ adapter: new Adapter() });
|
||||
|
||||
global.__APP_VERSION__ = '1.0.0';
|
|
@ -1,3 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PackageSidebar /> : <Dependencies /> should load the package and match snapshot 1`] = `"<div class=\\"module dependenciesModule\\"><h2 class=\\"moduleTitle\\">Dependencies</h2><div><ul><li class=\\"dependency-item\\" title=\\"Depend on version: 0.0.3\\"><a href=\\"http://localhost/#/detail/@verdaccio/file-locking\\">@verdaccio/file-locking</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 0.0.2\\"><a href=\\"http://localhost/#/detail/@verdaccio/streams\\">@verdaccio/streams</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.1.1\\"><a href=\\"http://localhost/#/detail/JSONStream\\">JSONStream</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.1.2\\"><a href=\\"http://localhost/#/detail/apache-md5\\">apache-md5</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.0.1\\"><a href=\\"http://localhost/#/detail/async\\">async</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.15.0\\"><a href=\\"http://localhost/#/detail/body-parser\\">body-parser</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.8.0\\"><a href=\\"http://localhost/#/detail/bunyan\\">bunyan</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.0.1\\"><a href=\\"http://localhost/#/detail/chalk\\">chalk</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.11.0\\"><a href=\\"http://localhost/#/detail/commander\\">commander</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 1.6.2\\"><a href=\\"http://localhost/#/detail/compression\\">compression</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.7.0\\"><a href=\\"http://localhost/#/detail/cookies\\">cookies</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.8.3\\"><a href=\\"http://localhost/#/detail/cors\\">cors</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 4.15.3\\"><a href=\\"http://localhost/#/detail/express\\">express</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^4.3.2\\"><a href=\\"http://localhost/#/detail/global\\">global</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 4.0.5\\"><a href=\\"http://localhost/#/detail/handlebars\\">handlebars</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.4.0\\"><a href=\\"http://localhost/#/detail/http-errors\\">http-errors</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 1.0.1\\"><a href=\\"http://localhost/#/detail/js-string-escape\\">js-string-escape</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^3.6.0\\"><a href=\\"http://localhost/#/detail/js-yaml\\">js-yaml</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^7.4.1\\"><a href=\\"http://localhost/#/detail/jsonwebtoken\\">jsonwebtoken</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.0.1\\"><a href=\\"http://localhost/#/detail/lockfile\\">lockfile</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 4.17.4\\"><a href=\\"http://localhost/#/detail/lodash\\">lodash</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.7.0\\"><a href=\\"http://localhost/#/detail/lunr\\">lunr</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 0.3.6\\"><a href=\\"http://localhost/#/detail/marked\\">marked</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.3.6\\"><a href=\\"http://localhost/#/detail/mime\\">mime</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^3.0.2\\"><a href=\\"http://localhost/#/detail/minimatch\\">minimatch</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.5.1\\"><a href=\\"http://localhost/#/detail/mkdirp\\">mkdirp</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.4.0\\"><a href=\\"http://localhost/#/detail/pkginfo\\">pkginfo</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.72.0\\"><a href=\\"http://localhost/#/detail/request\\">request</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^5.1.0\\"><a href=\\"http://localhost/#/detail/semver\\">semver</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.0.0\\"><a href=\\"http://localhost/#/detail/unix-crypt-td-js\\">unix-crypt-td-js</a></li></ul></div></div>"`;
|
||||
exports[`<PackageSidebar /> : <Dependencies /> should load dependencies 1`] = `"<div class=\\"module dependenciesModule\\"><h2 class=\\"moduleTitle\\">Dependencies</h2><div><ul><li class=\\"dependency-item\\" title=\\"Depend on version: 0.0.3\\"><a href=\\"http://localhost/#/detail/@verdaccio/file-locking\\">@verdaccio/file-locking</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 0.0.2\\"><a href=\\"http://localhost/#/detail/@verdaccio/streams\\">@verdaccio/streams</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.1.1\\"><a href=\\"http://localhost/#/detail/JSONStream\\">JSONStream</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.1.2\\"><a href=\\"http://localhost/#/detail/apache-md5\\">apache-md5</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.0.1\\"><a href=\\"http://localhost/#/detail/async\\">async</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.15.0\\"><a href=\\"http://localhost/#/detail/body-parser\\">body-parser</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.8.0\\"><a href=\\"http://localhost/#/detail/bunyan\\">bunyan</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.0.1\\"><a href=\\"http://localhost/#/detail/chalk\\">chalk</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.11.0\\"><a href=\\"http://localhost/#/detail/commander\\">commander</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 1.6.2\\"><a href=\\"http://localhost/#/detail/compression\\">compression</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.7.0\\"><a href=\\"http://localhost/#/detail/cookies\\">cookies</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.8.3\\"><a href=\\"http://localhost/#/detail/cors\\">cors</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 4.15.3\\"><a href=\\"http://localhost/#/detail/express\\">express</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^4.3.2\\"><a href=\\"http://localhost/#/detail/global\\">global</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 4.0.5\\"><a href=\\"http://localhost/#/detail/handlebars\\">handlebars</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.4.0\\"><a href=\\"http://localhost/#/detail/http-errors\\">http-errors</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 1.0.1\\"><a href=\\"http://localhost/#/detail/js-string-escape\\">js-string-escape</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^3.6.0\\"><a href=\\"http://localhost/#/detail/js-yaml\\">js-yaml</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^7.4.1\\"><a href=\\"http://localhost/#/detail/jsonwebtoken\\">jsonwebtoken</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.0.1\\"><a href=\\"http://localhost/#/detail/lockfile\\">lockfile</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 4.17.4\\"><a href=\\"http://localhost/#/detail/lodash\\">lodash</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.7.0\\"><a href=\\"http://localhost/#/detail/lunr\\">lunr</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: 0.3.6\\"><a href=\\"http://localhost/#/detail/marked\\">marked</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.3.6\\"><a href=\\"http://localhost/#/detail/mime\\">mime</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^3.0.2\\"><a href=\\"http://localhost/#/detail/minimatch\\">minimatch</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.5.1\\"><a href=\\"http://localhost/#/detail/mkdirp\\">mkdirp</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^0.4.0\\"><a href=\\"http://localhost/#/detail/pkginfo\\">pkginfo</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^2.72.0\\"><a href=\\"http://localhost/#/detail/request\\">request</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^5.1.0\\"><a href=\\"http://localhost/#/detail/semver\\">semver</a><span>, </span></li><li class=\\"dependency-item\\" title=\\"Depend on version: ^1.0.0\\"><a href=\\"http://localhost/#/detail/unix-crypt-td-js\\">unix-crypt-td-js</a></li></ul></div></div>"`;
|
||||
|
||||
exports[`<PackageSidebar /> : <Dependencies /> should load the package without dependecnies 1`] = `"<div class=\\"module dependenciesModule\\"><h2 class=\\"moduleTitle\\">Dependencies</h2><div><p class=\\"emptyPlaceholder\\">Zero Dependencies!</p></div></div>"`;
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the Info component and match snapshot 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>Homepage</span><a href=\\"https://github.com/verdaccio/verdaccio#readme\\" target=\\"_blank\\">https://github.com/verdaccio/verdaccio#readme</a></li><li><span>Repository</span><a href=\\"git://github.com/verdaccio/verdaccio.git\\" target=\\"_blank\\">git://github.com/verdaccio/verdaccio.git</a></li><li><span>License</span><span>WTFPL</span></li></ul></div></div>"`;
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the Info component with homepage only 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>Homepage</span><a href=\\"https://www.verdaccio.org\\" target=\\"_blank\\">https://www.verdaccio.org</a></li></ul></div></div>"`;
|
||||
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the Info component with license only 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>License</span><span>MIT</span></li></ul></div></div>"`;
|
||||
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the Info component with props 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>Homepage</span><a href=\\"https://www.verdaccio.org\\" target=\\"_blank\\">https://www.verdaccio.org</a></li><li><span>Repository</span><a href=\\"https://github.com/verdaccio/verdaccio\\" target=\\"_blank\\">https://github.com/verdaccio/verdaccio</a></li><li><span>License</span><span>MIT</span></li></ul></div></div>"`;
|
||||
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the Info component with repository only 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><ul><li><span>Repository</span><a href=\\"https://github.com/verdaccio/verdaccio\\" target=\\"_blank\\">https://github.com/verdaccio/verdaccio</a></li></ul></div></div>"`;
|
||||
|
||||
exports[`<PackageSidebar /> : <Infos /> should load the component without props 1`] = `"<div class=\\"module infosModule\\"><h2 class=\\"moduleTitle\\">Infos</h2><div><p class=\\"emptyPlaceholder\\">Not Available!</p></div></div>"`;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PackageSidebar /> : <LastSync /> should check the default props condition 1`] = `"<div class=\\"module releasesModule\\"><h2 class=\\"moduleTitle\\">Last Sync</h2><div><p class=\\"emptyPlaceholder\\">Not Available!</p></div></div>"`;
|
||||
|
||||
exports[`<PackageSidebar /> : <LastSync /> should load the LastSync component and match snapshot 1`] = `"<div class=\\"module releasesModule\\"><h2 class=\\"moduleTitle\\">Last Sync<span>2017/12/14, 15:43:52</span></h2><div><ul><li class=\\"last-sync-item\\"><span>2.7.1</span><span>2017/12/14, 15:43:27</span></li><li class=\\"last-sync-item\\"><span>2.7.0</span><span>2017/12/05, 23:25:06</span></li><li class=\\"last-sync-item\\"><span>2.6.6</span><span>2017/11/08, 22:47:16</span></li></ul></div></div>"`;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PackageSidebar /> : <Maintainers /> should match with the props 1`] = `"<div class=\\"module maintainersModule\\"><h2 class=\\"moduleTitle\\">Maintainers</h2><div><ul class=\\"maintainer-author\\"><div class=\\"maintainer\\" title=\\"User NPM\\"><img src=\\"https://www.gravatar.com/avatar/a5a236ba477ee98908600c40cda74f4a\\" alt=\\"Author User NPM's avatar\\" title=\\"Author User NPM's avatar\\"><span class=\\"maintainer-name\\">User NPM</span></div><div class=\\"maintainer\\" title=\\"030\\"><img src=\\"https://www.gravatar.com/avatar/4ef03c2bf8d8689527903212d96fb45b\\" alt=\\"Contributors 030's avatar\\" title=\\"Contributors 030's avatar\\"><span class=\\"maintainer-name\\">030</span></div><div class=\\"maintainer\\" title=\\"Alex Vernacchia\\"><img src=\\"https://www.gravatar.com/avatar/06975001f7f2be7052bcf978700c6112\\" alt=\\"Contributors Alex Vernacchia's avatar\\" title=\\"Contributors Alex Vernacchia's avatar\\"><span class=\\"maintainer-name\\">Alex Vernacchia</span></div><div class=\\"maintainer\\" title=\\"Alexander Makarenko\\"><img src=\\"https://www.gravatar.com/avatar/d9acfc4ed4e49a436738ff26a722dce4\\" alt=\\"Contributors Alexander Makarenko's avatar\\" title=\\"Contributors Alexander Makarenko's avatar\\"><span class=\\"maintainer-name\\">Alexander Makarenko</span></div><div class=\\"maintainer\\" title=\\"Alexandre-io\\"><img src=\\"https://www.gravatar.com/avatar/2e095c7cfd278f72825d0fed6e12e3b1\\" alt=\\"Contributors Alexandre-io's avatar\\" title=\\"Contributors Alexandre-io's avatar\\"><span class=\\"maintainer-name\\">Alexandre-io</span></div><div class=\\"maintainer\\" title=\\"Aram Drevekenin\\"><img src=\\"https://www.gravatar.com/avatar/371edff6d79c39bb9e36bde39d41a4b0\\" alt=\\"Contributors Aram Drevekenin's avatar\\" title=\\"Contributors Aram Drevekenin's avatar\\"><span class=\\"maintainer-name\\">Aram Drevekenin</span></div></ul><button class=\\"showAllContributors\\" title=\\"Current list only show the author and first 5 contributors unique by name\\">Show all contributor</button></div></div>"`;
|
||||
exports[`<PackageSidebar /> : <Maintainers /> should match with the props 1`] = `"<div class=\\"module maintainersModule\\"><h2 class=\\"moduleTitle\\">Maintainers</h2><div><div><ul class=\\"maintainer-author\\"><div class=\\"maintainer\\" title=\\"User NPM\\"><img src=\\"https://www.gravatar.com/avatar/a5a236ba477ee98908600c40cda74f4a\\" alt=\\"Author User NPM's avatar\\" title=\\"Author User NPM's avatar\\"><span class=\\"maintainer-name\\">User NPM</span></div><div class=\\"maintainer\\" title=\\"030\\"><img src=\\"https://www.gravatar.com/avatar/4ef03c2bf8d8689527903212d96fb45b\\" alt=\\"Contributors 030's avatar\\" title=\\"Contributors 030's avatar\\"><span class=\\"maintainer-name\\">030</span></div><div class=\\"maintainer\\" title=\\"Alex Vernacchia\\"><img src=\\"https://www.gravatar.com/avatar/06975001f7f2be7052bcf978700c6112\\" alt=\\"Contributors Alex Vernacchia's avatar\\" title=\\"Contributors Alex Vernacchia's avatar\\"><span class=\\"maintainer-name\\">Alex Vernacchia</span></div><div class=\\"maintainer\\" title=\\"Alexander Makarenko\\"><img src=\\"https://www.gravatar.com/avatar/d9acfc4ed4e49a436738ff26a722dce4\\" alt=\\"Contributors Alexander Makarenko's avatar\\" title=\\"Contributors Alexander Makarenko's avatar\\"><span class=\\"maintainer-name\\">Alexander Makarenko</span></div><div class=\\"maintainer\\" title=\\"Alexandre-io\\"><img src=\\"https://www.gravatar.com/avatar/2e095c7cfd278f72825d0fed6e12e3b1\\" alt=\\"Contributors Alexandre-io's avatar\\" title=\\"Contributors Alexandre-io's avatar\\"><span class=\\"maintainer-name\\">Alexandre-io</span></div><div class=\\"maintainer\\" title=\\"Aram Drevekenin\\"><img src=\\"https://www.gravatar.com/avatar/371edff6d79c39bb9e36bde39d41a4b0\\" alt=\\"Contributors Aram Drevekenin's avatar\\" title=\\"Contributors Aram Drevekenin's avatar\\"><span class=\\"maintainer-name\\">Aram Drevekenin</span></div></ul><button class=\\"showAllContributors\\" title=\\"Current list only show the author and first 5 contributors unique by name\\">Show all contributor</button></div></div></div>"`;
|
||||
|
|
|
@ -3,22 +3,13 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import Dependencies from '../../../../../src/webui/components/PackageSidebar/modules/Dependencies/index';
|
||||
import { packageMeta } from '../store/packageMeta';
|
||||
|
||||
console.error = jest.fn();
|
||||
|
||||
describe('<PackageSidebar /> : <Dependencies />', () => {
|
||||
it('should throw error for the required props', () => {
|
||||
mount(<Dependencies />);
|
||||
expect(console.error).toBeCalled();
|
||||
});
|
||||
|
||||
it('getter: should get dependencies from package meta', () => {
|
||||
const wrapper = mount(<Dependencies packageMeta={packageMeta} />);
|
||||
const dependencies = wrapper.instance().dependencies;
|
||||
const result = {
|
||||
it('should load dependencies', () => {
|
||||
const dependencies = {
|
||||
'@verdaccio/file-locking': '0.0.3',
|
||||
'@verdaccio/streams': '0.0.2',
|
||||
JSONStream: '^1.1.1',
|
||||
|
@ -50,11 +41,12 @@ describe('<PackageSidebar /> : <Dependencies />', () => {
|
|||
semver: '^5.1.0',
|
||||
'unix-crypt-td-js': '^1.0.0'
|
||||
};
|
||||
expect(dependencies).toEqual(result);
|
||||
const wrapper = shallow(<Dependencies dependencies={dependencies} />);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the package and match snapshot', () => {
|
||||
const wrapper = shallow(<Dependencies packageMeta={packageMeta} />);
|
||||
it('should load the package without dependecnies', () => {
|
||||
const wrapper = shallow(<Dependencies />);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,27 +3,44 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import Infos from '../../../../../src/webui/components/PackageSidebar/modules/Infos/index';
|
||||
import { packageMeta } from '../store/packageMeta';
|
||||
|
||||
console.error = jest.fn();
|
||||
|
||||
describe('<PackageSidebar /> : <Infos />', () => {
|
||||
it('should load the component and check getter: info with package data', () => {
|
||||
const wrapper = mount(<Infos packageMeta={packageMeta} />);
|
||||
const instance = wrapper.instance();
|
||||
const result = {
|
||||
repo: { type: 'git', url: 'git://github.com/verdaccio/verdaccio.git' },
|
||||
homepage: { url: 'https://github.com/verdaccio/verdaccio#readme' },
|
||||
license: 'WTFPL'
|
||||
};
|
||||
|
||||
expect(instance.infos).toEqual(result);
|
||||
it('should load the component without props', () => {
|
||||
const wrapper = shallow(<Infos/>);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the Info component and match snapshot', () => {
|
||||
const wrapper = shallow(<Infos packageMeta={packageMeta} />);
|
||||
it('should load the Info component with props', () => {
|
||||
const props = {
|
||||
homepage: 'https://www.verdaccio.org',
|
||||
license: 'MIT',
|
||||
repository: 'https://github.com/verdaccio/verdaccio'
|
||||
}
|
||||
const wrapper = shallow(<Infos {...props}/>);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the Info component with homepage only', () => {
|
||||
const props = {
|
||||
homepage: 'https://www.verdaccio.org'
|
||||
}
|
||||
const wrapper = shallow(<Infos {...props} />);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the Info component with license only', () => {
|
||||
const props = {
|
||||
license: 'MIT',
|
||||
}
|
||||
const wrapper = shallow(<Infos {...props} />);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the Info component with repository only', () => {
|
||||
const props = { repository: 'https://github.com/verdaccio/verdaccio' };
|
||||
const wrapper = shallow(<Infos {...props} />);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,28 +3,25 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import LastSync from '../../../../../src/webui/components/PackageSidebar/modules/LastSync/index';
|
||||
import { packageMeta } from '../store/packageMeta';
|
||||
|
||||
console.error = jest.fn();
|
||||
|
||||
describe('<PackageSidebar /> : <LastSync />', () => {
|
||||
it('should load the component and check getters: lastUpdate, recentReleases with package data', () => {
|
||||
const wrapper = mount(<LastSync packageMeta={packageMeta} />);
|
||||
const instance = wrapper.instance();
|
||||
const result = [
|
||||
{ time: '2017/12/14, 15:43:27', version: '2.7.1' },
|
||||
{ time: '2017/12/05, 23:25:06', version: '2.7.0' },
|
||||
{ time: '2017/11/08, 22:47:16', version: '2.6.6' }
|
||||
];
|
||||
const lastUpdated = '2017/12/14, 15:43:52';
|
||||
expect(instance.lastUpdate).toEqual(lastUpdated);
|
||||
expect(instance.recentReleases).toEqual(result);
|
||||
it('should check the default props condition', () => {
|
||||
const wrapper = shallow(<LastSync/>);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the LastSync component and match snapshot', () => {
|
||||
const wrapper = shallow(<LastSync packageMeta={packageMeta} />);
|
||||
const props = {
|
||||
lastUpdated: '2017/12/14, 15:43:52',
|
||||
recentReleases: [
|
||||
{ time: '2017/12/14, 15:43:27', version: '2.7.1' },
|
||||
{ time: '2017/12/05, 23:25:06', version: '2.7.0' },
|
||||
{ time: '2017/11/08, 22:47:16', version: '2.6.6' }
|
||||
]
|
||||
};
|
||||
const wrapper = shallow(<LastSync {...props}/>);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,8 +7,6 @@ import { mount } from 'enzyme';
|
|||
import Maintainers from '../../../../../src/webui/components/PackageSidebar/modules/Maintainers/index';
|
||||
import { packageMeta } from '../store/packageMeta';
|
||||
|
||||
console.error = jest.fn();
|
||||
|
||||
describe('<PackageSidebar /> : <Maintainers />', () => {
|
||||
let wrapper;
|
||||
let instance;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Footer /> component should load the inital state of Footer component 1`] = `"<div class=\\"wrap\\"><footer class=\\"container footer false\\"><span>Made with </span><span>❤</span><span> on</span><img class=\\"earth emoji\\" src=\\"[object Object]\\" alt=\\"Earth\\"><div class=\\"tooltip\\"><img src=\\"[object Object]\\" alt=\\"Brazil\\" title=\\"Brazil\\" class=\\"emoji\\"><img src=\\"[object Object]\\" alt=\\"China\\" title=\\"China\\" class=\\"emoji\\"><img src=\\"[object Object]\\" alt=\\"India\\" title=\\"India\\" class=\\"emoji\\"><img src=\\"[object Object]\\" alt=\\"Nicaragua\\" title=\\"Nicaragua\\" class=\\"emoji\\"><img src=\\"[object Object]\\" alt=\\"Pakistan\\" title=\\"Pakistan\\" class=\\"emoji\\"><img src=\\"[object Object]\\" alt=\\"Spain\\" title=\\"Spain\\" class=\\"emoji\\"></div><div class=\\"right\\">Powered by <a href=\\"http://www.verdaccio.org/\\"><img class=\\"logo\\" src=\\"[object Object]\\" alt=\\"Verdaccio\\" title=\\"Verdaccio\\"></a> / 1.0.0</div></footer></div>"`;
|
|
@ -1,3 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Package /> component should load the component 1`] = `"<section class=\\"package\\"><a href=\\"detail/verdaccio\\"><div class=\\"header\\"><div class=\\"title\\"><h1>verdaccio <span class=\\"el-tag el-tag--gray\\">v1.0.0</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Sam</div></div><div class=\\"footer\\"><p class=\\"description\\">Private NPM repository</p></div><div class=\\"details\\"><div class=\\"homepage\\">Published about 1 month ago</div><div class=\\"license\\">MIT</div></div></a></section>"`;
|
||||
|
||||
exports[`<Package /> component should load the component without author 1`] = `"<section class=\\"package\\"><a href=\\"detail/verdaccio\\"><div class=\\"header\\"><div class=\\"title\\"><h1>verdaccio <span class=\\"el-tag el-tag--gray\\">v1.0.0</span></h1></div><div role=\\"author\\" class=\\"author\\"></div></div><div class=\\"footer\\"><p class=\\"description\\">Private NPM repository</p></div><div class=\\"details\\"><div class=\\"homepage\\">Published about 1 month ago</div><div class=\\"license\\">MIT</div></div></a></section>"`;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<PackageList /> component should load the component with packages 1`] = `"<div class=\\"package-list-items\\"><div class=\\"pkgContainer\\"><h1 class=\\"listTitle\\">Available Packages</h1><li><section class=\\"package\\"><a href=\\"detail/verdaccio\\"><div class=\\"header\\"><div class=\\"title\\"><h1>verdaccio <span class=\\"el-tag el-tag--gray\\">v1.0.0</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Sam</div></div><div class=\\"footer\\"><p class=\\"description\\">Private NPM repository</p></div><div class=\\"details\\"><div class=\\"homepage\\">Published less than a minute ago</div></div></a></section></li><li><section class=\\"package\\"><a href=\\"detail/abc\\"><div class=\\"header\\"><div class=\\"title\\"><h1>abc <span class=\\"el-tag el-tag--gray\\">v1.0.1</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Rose</div></div><div class=\\"footer\\"><p class=\\"description\\">abc description</p></div><div class=\\"details\\"><div class=\\"homepage\\">Published less than a minute ago</div></div></a></section></li><li><section class=\\"package\\"><a href=\\"detail/xyz\\"><div class=\\"header\\"><div class=\\"title\\"><h1>xyz <span class=\\"el-tag el-tag--gray\\">v1.1.0</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Martin</div></div><div class=\\"footer\\"><p class=\\"description\\">xyz description</p></div><div class=\\"details\\"><div class=\\"homepage\\"></div></div></a></section></li></div></div>"`;
|
||||
exports[`<PackageList /> component should load the component with packages 1`] = `"<div class=\\"package-list-items\\"><div class=\\"pkgContainer\\"><h1 class=\\"listTitle\\">Available Packages</h1><li><section class=\\"package\\"><a href=\\"detail/verdaccio\\"><div class=\\"header\\"><div class=\\"title\\"><h1>verdaccio <span class=\\"el-tag el-tag--gray\\">v1.0.0</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Sam</div></div><div class=\\"footer\\"><p class=\\"description\\">Private NPM repository</p></div><div class=\\"details\\"><div class=\\"homepage\\">Published less than a minute ago</div><div class=\\"license\\"></div></div></a></section></li><li><section class=\\"package\\"><a href=\\"detail/abc\\"><div class=\\"header\\"><div class=\\"title\\"><h1>abc <span class=\\"el-tag el-tag--gray\\">v1.0.1</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Rose</div></div><div class=\\"footer\\"><p class=\\"description\\">abc description</p></div><div class=\\"details\\"><div class=\\"homepage\\">Published less than a minute ago</div><div class=\\"license\\"></div></div></a></section></li><li><section class=\\"package\\"><a href=\\"detail/xyz\\"><div class=\\"header\\"><div class=\\"title\\"><h1>xyz <span class=\\"el-tag el-tag--gray\\">v1.1.0</span></h1></div><div role=\\"author\\" class=\\"author\\">By: Martin</div></div><div class=\\"footer\\"><p class=\\"description\\">xyz description</p></div><div class=\\"details\\"><div class=\\"homepage\\"></div><div class=\\"license\\"></div></div></a></section></li></div></div>"`;
|
||||
|
|
22
test/unit/webui/components/footer.spec.js
Normal file
22
test/unit/webui/components/footer.spec.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
|
||||
import Footer from '../../../../src/webui/components/Footer/index';
|
||||
|
||||
describe('<Footer /> component', () => {
|
||||
let wrapper;
|
||||
beforeEach(() => {
|
||||
wrapper = mount(<Footer />);
|
||||
});
|
||||
|
||||
it('should load the inital state of Footer component', () => {
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should hover the earth in footer', () => {
|
||||
const earth = wrapper.find('img[alt="Earth"]');
|
||||
earth.simulate('click');
|
||||
expect(wrapper.state('showAuthorsGeographic')).toEqual(true);
|
||||
});
|
||||
});
|
|
@ -25,19 +25,14 @@ describe('<Package /> component', () => {
|
|||
time: dateOneMonthAgo(),
|
||||
license: 'MIT',
|
||||
description: 'Private NPM repository',
|
||||
author: { name: 'Sam' }
|
||||
author: 'Sam'
|
||||
};
|
||||
const wrapper = mount(
|
||||
<BrowserRouter>
|
||||
<Package package={props} />
|
||||
<Package {...props}/>
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
// renderAuthor method
|
||||
const renderAuthor = wrapper.find(Package).instance().renderAuthor;
|
||||
expect(renderAuthor({ author: {} })).toBeUndefined();
|
||||
expect(renderAuthor({ author: { name: 'sam' } })).toBeDefined();
|
||||
|
||||
// integration expectations
|
||||
expect(wrapper.find('a').prop('href')).toEqual('detail/verdaccio');
|
||||
expect(wrapper.find('h1').text()).toEqual('verdaccio v1.0.0');
|
||||
|
@ -50,4 +45,27 @@ describe('<Package /> component', () => {
|
|||
expect(wrapper.find('.license').text()).toMatch(/MIT/);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load the component without author', () => {
|
||||
const props = {
|
||||
name: 'verdaccio',
|
||||
version: '1.0.0',
|
||||
time: dateOneMonthAgo(),
|
||||
license: 'MIT',
|
||||
description: 'Private NPM repository'
|
||||
};
|
||||
const wrapper = mount(
|
||||
<BrowserRouter>
|
||||
<Package {...props} />
|
||||
</BrowserRouter>
|
||||
);
|
||||
|
||||
// integration expectations
|
||||
expect(
|
||||
wrapper.find('div').filterWhere(n => n.prop('role') === 'author')
|
||||
.text()
|
||||
).toEqual('');
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -18,7 +18,7 @@ describe('<PackageDetail /> component', () => {
|
|||
it('should load the component', () => {
|
||||
const props = {
|
||||
readMe: 'Test readme',
|
||||
package: WEB_TITLE
|
||||
packageName: WEB_TITLE
|
||||
};
|
||||
const wrapper = shallow(<PackageDetail {...props} />);
|
||||
|
||||
|
|
|
@ -53,7 +53,11 @@ export const packageMeta = {
|
|||
'2.7.0': '2017-12-05T23:25:06.372Z',
|
||||
'2.7.1': '2017-12-14T15:43:27.317Z'
|
||||
},
|
||||
_uplinks: { npmjs: { etag: '"5a272ad2-4f6b1"', fetched: 1513266232741 } },
|
||||
_uplinks: {
|
||||
abc: { etag: 'ddfdxjn8m8n6gn70-8m', fetched: 1532297472000},
|
||||
npmjs: { etag: '"5a272ad2-4f6b1"', fetched: 1513266232741 },
|
||||
xyz: { etag: '564748hydydygs-s7ehj', fetched: 1532124672000}
|
||||
},
|
||||
_rev: '16-ba1b806df0298246',
|
||||
_attachments: {},
|
||||
latest: {
|
||||
|
|
110
test/unit/webui/utils/package.spec.js
Normal file
110
test/unit/webui/utils/package.spec.js
Normal file
|
@ -0,0 +1,110 @@
|
|||
import {
|
||||
formatLicense,
|
||||
formatRepository,
|
||||
formatAuthor,
|
||||
formatDate,
|
||||
formatDateDistance,
|
||||
getLastUpdatedPackageTime,
|
||||
getRecentReleases
|
||||
} from '../../../../src/webui/utils/package';
|
||||
|
||||
import { packageMeta } from '../components/store/packageMeta';
|
||||
|
||||
describe('formatLicense', () => {
|
||||
it('should check license field different values', () => {
|
||||
expect(formatLicense('MIT')).toEqual('MIT');
|
||||
});
|
||||
it('should check license field for object value', () => {
|
||||
const license = { type: 'ISC', url: 'https://opensource.org/licenses/ISC' };
|
||||
expect(formatLicense(license)).toEqual('ISC');
|
||||
});
|
||||
it('should check license field for other value', () => {
|
||||
expect(formatLicense(null)).toBeNull();
|
||||
expect(formatLicense({})).toBeNull();
|
||||
expect(formatLicense([])).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatRepository', () => {
|
||||
it('should check repository field different values', () => {
|
||||
const repository = 'https://github.com/verdaccio/verdaccio';
|
||||
expect(formatRepository(repository)).toEqual(repository);
|
||||
});
|
||||
it('should check repository field for object value', () => {
|
||||
const license = {
|
||||
type: 'git',
|
||||
url: 'https://github.com/verdaccio/verdaccio'
|
||||
};
|
||||
expect(formatRepository(license)).toEqual(license.url);
|
||||
});
|
||||
it('should check repository field for other value', () => {
|
||||
expect(formatRepository(null)).toBeNull();
|
||||
expect(formatRepository({})).toBeNull();
|
||||
expect(formatRepository([])).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatAuthor', () => {
|
||||
it('should check author field different values', () => {
|
||||
const author = 'verdaccioNpm';
|
||||
expect(formatAuthor(author)).toEqual(author);
|
||||
});
|
||||
it('should check author field for object value', () => {
|
||||
const license = {
|
||||
name: 'Verdaccion NPM',
|
||||
email: 'verdaccio@verdaccio.org',
|
||||
url: 'https://verdaccio.org'
|
||||
};
|
||||
expect(formatAuthor(license)).toEqual('Verdaccion NPM');
|
||||
});
|
||||
it('should check author field for other value', () => {
|
||||
expect(formatAuthor(null)).toBeNull();
|
||||
expect(formatAuthor({})).toBeNull();
|
||||
expect(formatAuthor([])).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatDate', () => {
|
||||
it('should format the date', () => {
|
||||
const date = 1532211072138;
|
||||
expect(formatDate(date)).toEqual('2018/07/21, 22:11:12');
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatDateDistance', () => {
|
||||
it('should calculate the distance', () => {
|
||||
const dateOneMonthAgo = () => {
|
||||
const date = new Date();
|
||||
date.setMonth(date.getMonth() - 1);
|
||||
return date;
|
||||
};
|
||||
const date = dateOneMonthAgo();
|
||||
expect(formatDateDistance(date)).toEqual('about 1 month');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLastUpdatedPackageTime', () => {
|
||||
it('should get the last update time', () => {
|
||||
const lastUpdated = packageMeta._uplinks;
|
||||
expect(getLastUpdatedPackageTime(lastUpdated)).toEqual(
|
||||
'2018/07/22, 22:11:12'
|
||||
);
|
||||
});
|
||||
it('should get the last update time for blank uplink', () => {
|
||||
const lastUpdated = {};
|
||||
expect(getLastUpdatedPackageTime(lastUpdated)).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getRecentReleases', () => {
|
||||
it('should get the recent releases', () => {
|
||||
const { time } = packageMeta;
|
||||
const result = [
|
||||
{ time: '2017/12/14, 15:43:27', version: '2.7.1' },
|
||||
{ time: '2017/12/05, 23:25:06', version: '2.7.0' },
|
||||
{ time: '2017/11/08, 22:47:16', version: '2.6.6' }
|
||||
];
|
||||
expect(getRecentReleases(time)).toEqual(result);
|
||||
expect(getRecentReleases()).toEqual([]);
|
||||
});
|
||||
});
|
|
@ -30,6 +30,10 @@ new WebpackDevServer(compiler, {
|
|||
chunks: true,
|
||||
chunkModules: false,
|
||||
},
|
||||
proxy: [{
|
||||
context: ['/-/verdaccio/logo', '/-/verdaccio/packages', '/-/static/logo.png'],
|
||||
target: 'http://localhost:4873',
|
||||
}],
|
||||
}).listen(4872, 'localhost', function(err) {
|
||||
if (err) {
|
||||
return console.log(err);
|
||||
|
|
Loading…
Reference in a new issue