From b2e420dbd9eebfa8f33c99eb6804d533e4af4039 Mon Sep 17 00:00:00 2001 From: Griffithtp Date: Sat, 6 Jul 2019 10:50:09 +0100 Subject: [PATCH 1/3] fix: support deprecated license object properties --- src/components/Dist/Dist.tsx | 30 ++++++++++---------- src/components/Package/Package.tsx | 44 ++++++++++++++---------------- src/utils/package.ts | 5 ---- types/packageMeta.ts | 7 ++++- 4 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/components/Dist/Dist.tsx b/src/components/Dist/Dist.tsx index 3b05cf4..088a085 100644 --- a/src/components/Dist/Dist.tsx +++ b/src/components/Dist/Dist.tsx @@ -6,6 +6,7 @@ import { DetailContextConsumer, VersionPageConsumerProps } from '../../pages/ver import { Heading, DistListItem, DistChips } from './styles'; import fileSizeSI from '../../utils/file-size'; import { PackageMetaInterface } from 'types/packageMeta'; +import { formatLicense } from '../../utils/package'; class Dist extends Component { public render(): JSX.Element { @@ -18,28 +19,25 @@ class Dist extends Component { ); } - private renderChips(dist, license: string): JSX.Element | never[] { + private renderChips(dist, license: PackageMetaInterface['latest']['license']): (JSX.Element | undefined)[] { const distDict = { 'file-count': dist.fileCount, size: dist.unpackedSize && fileSizeSI(dist.unpackedSize), license, }; - const chipsList = Object.keys(distDict).reduce((componentList, title, key) => { - // @ts-ignore - const value = distDict[title]; - if (value) { - const label = ( - - {/* eslint-disable-next-line */} - {title.split('-').join(' ')}:{value} - - ); - // @ts-ignore is not assignable to parameter of type 'never' - componentList.push(); - } - return componentList; - }, []); + const chipsList = Object.keys(distDict).map((dist, key) => { + if (!distDict[dist]) return; + + const value = dist === 'license' ? formatLicense(distDict[dist]) : distDict[dist]; + const label = ( + + {/* eslint-disable-next-line */} + {dist.replace('-', ' ')}: {value} + + ); + return ; + }); return chipsList; } diff --git a/src/components/Package/Package.tsx b/src/components/Package/Package.tsx index 006d55f..8c76d66 100644 --- a/src/components/Package/Package.tsx +++ b/src/components/Package/Package.tsx @@ -6,10 +6,29 @@ import HomeIcon from '@material-ui/icons/Home'; import ListItem from '@material-ui/core/ListItem'; import Tooltip from '@material-ui/core/Tooltip'; +import { PackageMetaInterface } from 'types/packageMeta'; import Tag from '../Tag'; import fileSizeSI from '../../utils/file-size'; import { formatDate, formatDateDistance } from '../../utils/package'; - +import { + Author, + Avatar, + Description, + Details, + GridRightAligned, + Icon, + IconButton, + OverviewItem, + PackageList, + PackageListItem, + PackageListItemText, + PackageTitle, + Published, + TagContainer, + Text, + WrapperLink, +} from './styles'; +import { isURL } from '../../utils/url'; interface Author { name: string; avatar?: string; @@ -30,32 +49,11 @@ export interface PackageInterface { author: Author; description?: string; keywords?: string[]; - license?: string | null; + license?: PackageMetaInterface['latest']['license']; homepage?: string; bugs?: Bugs; dist?: Dist; } -// interface Props {} & PackageInterface; - -import { - Author, - Avatar, - Description, - Details, - GridRightAligned, - Icon, - IconButton, - OverviewItem, - PackageList, - PackageListItem, - PackageListItemText, - PackageTitle, - Published, - TagContainer, - Text, - WrapperLink, -} from './styles'; -import { isURL } from '../../utils/url'; const Package: React.FC = ({ author: { name: authorName, avatar: authorAvatar }, diff --git a/src/utils/package.ts b/src/utils/package.ts index 8565e99..485885a 100644 --- a/src/utils/package.ts +++ b/src/utils/package.ts @@ -6,11 +6,6 @@ import { isObject } from 'util'; export const TIMEFORMAT = 'DD.MM.YYYY, HH:mm:ss'; -export interface License { - type: string; - url: string; -} - /** * Formats license field for webui. * @see https://docs.npmjs.com/files/package.json#license diff --git a/types/packageMeta.ts b/types/packageMeta.ts index 473c331..bc86360 100644 --- a/types/packageMeta.ts +++ b/types/packageMeta.ts @@ -5,7 +5,12 @@ export interface PackageMetaInterface { fileCount: number; unpackedSize: number; }; - license: string; + license?: Partial | string | null; }; _uplinks: {}; } + +interface LicenseInterface { + type: string; + url: string; +} From cf1f47e86ca78493e91a6b5dae888777cc830ba1 Mon Sep 17 00:00:00 2001 From: Griffithtp Date: Sat, 6 Jul 2019 17:43:00 +0100 Subject: [PATCH 2/3] chore: add unit test for component --- src/components/Dist/Dist.test.tsx | 80 +++++++++++++++++++ src/components/Dist/Dist.tsx | 4 +- .../Dist/__snapshots__/Dist.test.tsx.snap | 7 ++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/components/Dist/Dist.test.tsx create mode 100644 src/components/Dist/__snapshots__/Dist.test.tsx.snap diff --git a/src/components/Dist/Dist.test.tsx b/src/components/Dist/Dist.test.tsx new file mode 100644 index 0000000..5a3a10b --- /dev/null +++ b/src/components/Dist/Dist.test.tsx @@ -0,0 +1,80 @@ +import React from 'react'; +import { shallow } from 'enzyme'; + +describe(' component', () => { + beforeEach(() => { + jest.resetModules(); + }); + + test('should render the component in default state', () => { + const packageMeta = { + latest: { + name: 'verdaccio', + version: '4.0.0', + dist: { + fileCount: 7, + unpackedSize: 10, + }, + license: '', + }, + }; + jest.doMock('../../pages/version/Version', () => ({ + DetailContextConsumer: component => { + return component.children({ packageMeta }); + }, + })); + + const Dist = require('./Dist').default; + const wrapper = shallow(); + expect(wrapper.html()).toMatchSnapshot(); + }); + + test('should render the component with license as string', () => { + const packageMeta = { + latest: { + name: 'verdaccio', + version: '4.0.0', + dist: { + fileCount: 7, + unpackedSize: 10, + }, + license: 'MIT', + }, + }; + jest.doMock('../../pages/version/Version', () => ({ + DetailContextConsumer: component => { + return component.children({ packageMeta }); + }, + })); + + const Dist = require('./Dist').default; + const wrapper = shallow(); + expect(wrapper.html()).toMatchSnapshot(); + }); + + test('should render the component with license as object', () => { + const packageMeta = { + latest: { + name: 'verdaccio', + version: '4.0.0', + dist: { + fileCount: 7, + unpackedSize: 10, + }, + license: { + type: 'MIT', + url: 'https://www.opensource.org/licenses/mit-license.php', + }, + }, + }; + jest.doMock('../../pages/version/Version', () => ({ + DetailContextConsumer: component => { + return component.children({ packageMeta }); + }, + })); + + const Dist = require('./Dist').default; + const wrapper = shallow(); + expect(wrapper.html()).toMatchSnapshot(); + }); +}); diff --git a/src/components/Dist/Dist.tsx b/src/components/Dist/Dist.tsx index 088a085..2edcfee 100644 --- a/src/components/Dist/Dist.tsx +++ b/src/components/Dist/Dist.tsx @@ -31,10 +31,10 @@ class Dist extends Component { const value = dist === 'license' ? formatLicense(distDict[dist]) : distDict[dist]; const label = ( - + <> {/* eslint-disable-next-line */} {dist.replace('-', ' ')}: {value} - + ); return ; }); diff --git a/src/components/Dist/__snapshots__/Dist.test.tsx.snap b/src/components/Dist/__snapshots__/Dist.test.tsx.snap new file mode 100644 index 0000000..15ebd6c --- /dev/null +++ b/src/components/Dist/__snapshots__/Dist.test.tsx.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` component should render the component in default state 1`] = `"

    Latest Distribution

  • file count: 7
    size: 10.00 Bytes
"`; + +exports[` component should render the component with license as object 1`] = `"

    Latest Distribution

  • file count: 7
    size: 10.00 Bytes
    license: MIT
"`; + +exports[` component should render the component with license as string 1`] = `"

    Latest Distribution

  • file count: 7
    size: 10.00 Bytes
    license: MIT
"`; From 13c7aa6d03b11fbcb70bb94a81206d10d22f7a05 Mon Sep 17 00:00:00 2001 From: Griffithtp Date: Sun, 7 Jul 2019 11:17:22 +0100 Subject: [PATCH 3/3] refactor: formatLicense to return undefined instead of null --- src/utils/package.test.ts | 6 +++--- src/utils/package.ts | 4 ++-- types/packageMeta.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/utils/package.test.ts b/src/utils/package.test.ts index 52de2f7..3674156 100644 --- a/src/utils/package.test.ts +++ b/src/utils/package.test.ts @@ -13,9 +13,9 @@ describe('formatLicense', (): void => { }); test('should check license field for other value', (): void => { - expect(formatLicense(null)).toBeNull(); - expect(formatLicense({})).toBeNull(); - expect(formatLicense([])).toBeNull(); + expect(formatLicense(null)).toBeUndefined(); + expect(formatLicense({})).toBeUndefined(); + expect(formatLicense([])).toBeUndefined(); }); }); diff --git a/src/utils/package.ts b/src/utils/package.ts index 485885a..eacd5ab 100644 --- a/src/utils/package.ts +++ b/src/utils/package.ts @@ -12,7 +12,7 @@ export const TIMEFORMAT = 'DD.MM.YYYY, HH:mm:ss'; */ // License should use type License defined above, but conflicts with the unit test that provide array or empty object /* eslint-disable @typescript-eslint/no-explicit-any */ -export function formatLicense(license: any): string | null { +export function formatLicense(license: any): string | undefined { if (isString(license)) { return license; } @@ -21,7 +21,7 @@ export function formatLicense(license: any): string | null { return license.type; } - return null; + return; } export interface Repository { diff --git a/types/packageMeta.ts b/types/packageMeta.ts index bc86360..171095d 100644 --- a/types/packageMeta.ts +++ b/types/packageMeta.ts @@ -5,7 +5,7 @@ export interface PackageMetaInterface { fileCount: number; unpackedSize: number; }; - license?: Partial | string | null; + license?: Partial | string; }; _uplinks: {}; }