diff --git a/.changeset/tough-days-search.md b/.changeset/tough-days-search.md new file mode 100644 index 000000000..dd5b5cc9b --- /dev/null +++ b/.changeset/tough-days-search.md @@ -0,0 +1,6 @@ +--- +'@verdaccio/ui-theme': patch +'@verdaccio/ui-components': patch +--- + +fix: undefined field on missing count diff --git a/packages/plugins/ui-theme/src/App/App.tsx b/packages/plugins/ui-theme/src/App/App.tsx index a72d910c2..81d1e1db3 100644 --- a/packages/plugins/ui-theme/src/App/App.tsx +++ b/packages/plugins/ui-theme/src/App/App.tsx @@ -89,6 +89,7 @@ const App: React.FC = () => { useEffect(() => { loadDayJSLocale(); }, []); + return ( diff --git a/packages/plugins/ui-theme/src/i18n/config.ts b/packages/plugins/ui-theme/src/i18n/config.ts index f0e434f55..5a3cba2b0 100644 --- a/packages/plugins/ui-theme/src/i18n/config.ts +++ b/packages/plugins/ui-theme/src/i18n/config.ts @@ -29,7 +29,6 @@ i18n whitelist: [...listLanguagesAsString], load: 'currentOnly', react: { - wait: true, useSuspense: false, }, resources: languages, diff --git a/packages/ui-components/jest/jest.config.js b/packages/ui-components/jest/jest.config.js index 5799b9b88..ec0f5a636 100644 --- a/packages/ui-components/jest/jest.config.js +++ b/packages/ui-components/jest/jest.config.js @@ -10,11 +10,17 @@ module.exports = Object.assign({}, config, { url: 'http://localhost:9000/', }, rootDir: '..', + collectCoverage: true, setupFilesAfterEnv: ['@testing-library/jest-dom/extend-expect', '/jest/setup-env.ts'], setupFiles: ['/jest/setup.ts'], transformIgnorePatterns: ['/node_modules/(?!react-syntax-highlighter)'], snapshotSerializers: ['@emotion/jest/serializer'], - collectCoverageFrom: ['src/**/*.{ts,tsx}', '!**/node_modules/**'], + collectCoverageFrom: [ + 'src/**/*.{ts,tsx}', + '!**/node_modules/**', + '!src/**/*.stories.{ts,tsx}', + '!src/types/**', + ], modulePathIgnorePatterns: ['/build/'], moduleNameMapper: { '\\.(s?css)$': '/jest/identity.js', @@ -26,7 +32,7 @@ module.exports = Object.assign({}, config, { 'react-markdown': '/src/__mocks__/react-markdown.tsx', 'remark-*': '/src/__mocks__/remark-plugin.ts', }, - coverageReporters: [['text', { skipFull: true }]], + coverageReporters: ['text', 'html'], coverageThreshold: { global: { branches: 68, diff --git a/packages/ui-components/src/components/Distribution/Dist.stories.tsx b/packages/ui-components/src/components/Distribution/Dist.stories.tsx index 1c1fc504f..8b6b7ada9 100644 --- a/packages/ui-components/src/components/Distribution/Dist.stories.tsx +++ b/packages/ui-components/src/components/Distribution/Dist.stories.tsx @@ -6,7 +6,7 @@ export default { title: 'Dist', }; -export const DistFileAll: any = () => ( +export const AllProperties: any = () => ( ( fileCount: 7, unpackedSize: 10, }, - license: '', + license: 'MIT', + }, + _uplinks: {}, + }} + /> +); + +export const NoFileSize: any = () => ( + +); + +export const OnlyLicense: any = () => ( + +); + +export const NoRender: any = () => ( + component', () => { }); test('should render the component in default state', () => { - const wrapper = render( + const { getByText } = render( withDistComponent({ latest: { name: 'verdaccio1', @@ -28,11 +28,16 @@ describe(' component', () => { _uplinks: {}, }) ); - expect(wrapper).toMatchSnapshot(); + expect(getByText('sidebar.distribution.title')).toBeInTheDocument(); + expect(getByText('sidebar.distribution.file-count')).toBeInTheDocument(); + expect(getByText('sidebar.distribution.size')).toBeInTheDocument(); + expect(getByText('sidebar.distribution.size')).toBeInTheDocument(); + expect(getByText('7', { exact: false })).toBeInTheDocument(); + expect(getByText('10.00 Bytes', { exact: false })).toBeInTheDocument(); }); test('should render the component with license as string', () => { - const wrapper = render( + const { getByText } = render( withDistComponent({ latest: { name: 'verdaccio2', @@ -46,11 +51,11 @@ describe(' component', () => { _uplinks: {}, }) ); - expect(wrapper).toMatchSnapshot(); + expect(getByText('MIT', { exact: false })).toBeInTheDocument(); }); test('should render the component with license as object', () => { - const wrapper = render( + const { getByText } = render( withDistComponent({ latest: { name: 'verdaccio3', @@ -67,6 +72,28 @@ describe(' component', () => { _uplinks: {}, }) ); - expect(wrapper).toMatchSnapshot(); + expect(getByText('MIT', { exact: false })).toBeInTheDocument(); + }); + + test('should not render if latest is missing', () => { + const { queryAllByText } = render( + withDistComponent({ + // @ts-ignore + latest: undefined, + _uplinks: {}, + }) + ); + expect(queryAllByText('sidebar.distribution.title')).toHaveLength(0); + }); + + test('should not render if latest content is missing', () => { + const { queryAllByText } = render( + withDistComponent({ + // @ts-expect-error + latest: { dist: undefined, license: undefined }, + _uplinks: {}, + }) + ); + expect(queryAllByText('sidebar.distribution.title')).toHaveLength(0); }); }); diff --git a/packages/ui-components/src/components/Distribution/Dist.tsx b/packages/ui-components/src/components/Distribution/Dist.tsx index 8130bd7cf..87e153bf4 100644 --- a/packages/ui-components/src/components/Distribution/Dist.tsx +++ b/packages/ui-components/src/components/Distribution/Dist.tsx @@ -25,23 +25,31 @@ const DistChip: FC<{ name: string; children?: React.ReactElement | string }> = ( const Dist: FC<{ packageMeta: PackageMetaInterface }> = ({ packageMeta }) => { const { t } = useTranslation(); - if (!packageMeta) { + if (!packageMeta?.latest) { return null; } - const { dist, license } = packageMeta && packageMeta.latest; + const { dist, license } = packageMeta.latest; + + if (!dist && !license) { + return null; + } return ( {t('sidebar.distribution.title')}} > - {`${dist.fileCount}`} - {dist.unpackedSize ? ( + {dist?.fileCount && ( + {`${dist.fileCount}`} + )} + {dist?.unpackedSize ? ( {fileSizeSI(dist.unpackedSize)} ) : null} - {formatLicense(license)} + + {formatLicense(license as string)} + ); diff --git a/packages/ui-components/src/components/Distribution/__snapshots__/Dist.test.tsx.snap b/packages/ui-components/src/components/Distribution/__snapshots__/Dist.test.tsx.snap deleted file mode 100644 index 80e27f1e2..000000000 --- a/packages/ui-components/src/components/Distribution/__snapshots__/Dist.test.tsx.snap +++ /dev/null @@ -1,1436 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` component should render the component in default state 1`] = ` -{ - "asFragment": [Function], - "baseElement": .emotion-0 { - list-style: none; - margin: 0; - padding: 0; - position: relative; - padding-top: 0; - padding-bottom: 8px; -} - -.emotion-2 { - margin: 0; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-weight: 400; - font-size: 1rem; - line-height: 1.75; - font-weight: 700; - text-transform: capitalize; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; - -webkit-text-decoration: none; - text-decoration: none; - width: 100%; - box-sizing: border-box; - text-align: left; - padding-top: 8px; - padding-bottom: 8px; - padding-left: 16px; - padding-right: 16px; - padding-left: 0; - padding-right: 0; - -webkit-box-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.emotion-4.Mui-focusVisible { - background-color: rgba(0, 0, 0, 0.12); -} - -.emotion-4.Mui-selected { - background-color: rgba(75, 94, 64, 0.08); -} - -.emotion-4.Mui-selected.Mui-focusVisible { - background-color: rgba(75, 94, 64, 0.2); -} - -.emotion-4.Mui-disabled { - opacity: 0.38; -} - -.emotion-6 { - max-width: 100%; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-size: 0.8125rem; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - -webkit-justify-content: center; - justify-content: center; - height: 32px; - color: rgba(0, 0, 0, 0.87); - background-color: rgba(0, 0, 0, 0.08); - border-radius: 16px; - white-space: nowrap; - -webkit-transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - cursor: default; - outline: 0; - -webkit-text-decoration: none; - text-decoration: none; - border: 0; - padding: 0; - vertical-align: middle; - box-sizing: border-box; - margin-right: 5px; - text-transform: capitalize; - margin-top: 5px; -} - -.emotion-6.Mui-disabled { - opacity: 0.38; - pointer-events: none; -} - -.emotion-6 .MuiChip-avatar { - margin-left: 5px; - margin-right: -6px; - width: 24px; - height: 24px; - color: #616161; - font-size: 0.75rem; -} - -.emotion-6 .MuiChip-avatarColorPrimary { - color: #fff; - background-color: rgb(52, 65, 44); -} - -.emotion-6 .MuiChip-avatarColorSecondary { - color: #fff; - background-color: rgb(22, 24, 29); -} - -.emotion-6 .MuiChip-avatarSmall { - margin-left: 4px; - margin-right: -4px; - width: 18px; - height: 18px; - font-size: 0.625rem; -} - -.emotion-6 .MuiChip-icon { - margin-left: 5px; - margin-right: -6px; - color: #616161; -} - -.emotion-6 .MuiChip-deleteIcon { - -webkit-tap-highlight-color: transparent; - color: rgba(0, 0, 0, 0.26); - font-size: 22px; - cursor: pointer; - margin: 0 5px 0 -6px; -} - -.emotion-6 .MuiChip-deleteIcon:hover { - color: rgba(0, 0, 0, 0.4); -} - -.emotion-7 { - overflow: hidden; - text-overflow: ellipsis; - padding-left: 12px; - padding-right: 12px; - white-space: nowrap; -} - - -
-
    -
    - sidebar.distribution.title -
    -
  • -
    - - - sidebar.distribution.file-count - - : - 7 - -
    -
    - - - sidebar.distribution.size - - : - 10.00 Bytes - -
    -
  • -
-
- , - "container": .emotion-0 { - list-style: none; - margin: 0; - padding: 0; - position: relative; - padding-top: 0; - padding-bottom: 8px; -} - -.emotion-2 { - margin: 0; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-weight: 400; - font-size: 1rem; - line-height: 1.75; - font-weight: 700; - text-transform: capitalize; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; - -webkit-text-decoration: none; - text-decoration: none; - width: 100%; - box-sizing: border-box; - text-align: left; - padding-top: 8px; - padding-bottom: 8px; - padding-left: 16px; - padding-right: 16px; - padding-left: 0; - padding-right: 0; - -webkit-box-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.emotion-4.Mui-focusVisible { - background-color: rgba(0, 0, 0, 0.12); -} - -.emotion-4.Mui-selected { - background-color: rgba(75, 94, 64, 0.08); -} - -.emotion-4.Mui-selected.Mui-focusVisible { - background-color: rgba(75, 94, 64, 0.2); -} - -.emotion-4.Mui-disabled { - opacity: 0.38; -} - -.emotion-6 { - max-width: 100%; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-size: 0.8125rem; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - -webkit-justify-content: center; - justify-content: center; - height: 32px; - color: rgba(0, 0, 0, 0.87); - background-color: rgba(0, 0, 0, 0.08); - border-radius: 16px; - white-space: nowrap; - -webkit-transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - cursor: default; - outline: 0; - -webkit-text-decoration: none; - text-decoration: none; - border: 0; - padding: 0; - vertical-align: middle; - box-sizing: border-box; - margin-right: 5px; - text-transform: capitalize; - margin-top: 5px; -} - -.emotion-6.Mui-disabled { - opacity: 0.38; - pointer-events: none; -} - -.emotion-6 .MuiChip-avatar { - margin-left: 5px; - margin-right: -6px; - width: 24px; - height: 24px; - color: #616161; - font-size: 0.75rem; -} - -.emotion-6 .MuiChip-avatarColorPrimary { - color: #fff; - background-color: rgb(52, 65, 44); -} - -.emotion-6 .MuiChip-avatarColorSecondary { - color: #fff; - background-color: rgb(22, 24, 29); -} - -.emotion-6 .MuiChip-avatarSmall { - margin-left: 4px; - margin-right: -4px; - width: 18px; - height: 18px; - font-size: 0.625rem; -} - -.emotion-6 .MuiChip-icon { - margin-left: 5px; - margin-right: -6px; - color: #616161; -} - -.emotion-6 .MuiChip-deleteIcon { - -webkit-tap-highlight-color: transparent; - color: rgba(0, 0, 0, 0.26); - font-size: 22px; - cursor: pointer; - margin: 0 5px 0 -6px; -} - -.emotion-6 .MuiChip-deleteIcon:hover { - color: rgba(0, 0, 0, 0.4); -} - -.emotion-7 { - overflow: hidden; - text-overflow: ellipsis; - padding-left: 12px; - padding-right: 12px; - white-space: nowrap; -} - -
-
    -
    - sidebar.distribution.title -
    -
  • -
    - - - sidebar.distribution.file-count - - : - 7 - -
    -
    - - - sidebar.distribution.size - - : - 10.00 Bytes - -
    -
  • -
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; - -exports[` component should render the component with license as object 1`] = ` -{ - "asFragment": [Function], - "baseElement": .emotion-0 { - list-style: none; - margin: 0; - padding: 0; - position: relative; - padding-top: 0; - padding-bottom: 8px; -} - -.emotion-2 { - margin: 0; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-weight: 400; - font-size: 1rem; - line-height: 1.75; - font-weight: 700; - text-transform: capitalize; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; - -webkit-text-decoration: none; - text-decoration: none; - width: 100%; - box-sizing: border-box; - text-align: left; - padding-top: 8px; - padding-bottom: 8px; - padding-left: 16px; - padding-right: 16px; - padding-left: 0; - padding-right: 0; - -webkit-box-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.emotion-4.Mui-focusVisible { - background-color: rgba(0, 0, 0, 0.12); -} - -.emotion-4.Mui-selected { - background-color: rgba(75, 94, 64, 0.08); -} - -.emotion-4.Mui-selected.Mui-focusVisible { - background-color: rgba(75, 94, 64, 0.2); -} - -.emotion-4.Mui-disabled { - opacity: 0.38; -} - -.emotion-6 { - max-width: 100%; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-size: 0.8125rem; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - -webkit-justify-content: center; - justify-content: center; - height: 32px; - color: rgba(0, 0, 0, 0.87); - background-color: rgba(0, 0, 0, 0.08); - border-radius: 16px; - white-space: nowrap; - -webkit-transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - cursor: default; - outline: 0; - -webkit-text-decoration: none; - text-decoration: none; - border: 0; - padding: 0; - vertical-align: middle; - box-sizing: border-box; - margin-right: 5px; - text-transform: capitalize; - margin-top: 5px; -} - -.emotion-6.Mui-disabled { - opacity: 0.38; - pointer-events: none; -} - -.emotion-6 .MuiChip-avatar { - margin-left: 5px; - margin-right: -6px; - width: 24px; - height: 24px; - color: #616161; - font-size: 0.75rem; -} - -.emotion-6 .MuiChip-avatarColorPrimary { - color: #fff; - background-color: rgb(52, 65, 44); -} - -.emotion-6 .MuiChip-avatarColorSecondary { - color: #fff; - background-color: rgb(22, 24, 29); -} - -.emotion-6 .MuiChip-avatarSmall { - margin-left: 4px; - margin-right: -4px; - width: 18px; - height: 18px; - font-size: 0.625rem; -} - -.emotion-6 .MuiChip-icon { - margin-left: 5px; - margin-right: -6px; - color: #616161; -} - -.emotion-6 .MuiChip-deleteIcon { - -webkit-tap-highlight-color: transparent; - color: rgba(0, 0, 0, 0.26); - font-size: 22px; - cursor: pointer; - margin: 0 5px 0 -6px; -} - -.emotion-6 .MuiChip-deleteIcon:hover { - color: rgba(0, 0, 0, 0.4); -} - -.emotion-7 { - overflow: hidden; - text-overflow: ellipsis; - padding-left: 12px; - padding-right: 12px; - white-space: nowrap; -} - - -
-
    -
    - sidebar.distribution.title -
    -
  • -
    - - - sidebar.distribution.file-count - - : - 7 - -
    -
    - - - sidebar.distribution.size - - : - 10.00 Bytes - -
    -
    - - - sidebar.distribution.license - - : - MIT - -
    -
  • -
-
- , - "container": .emotion-0 { - list-style: none; - margin: 0; - padding: 0; - position: relative; - padding-top: 0; - padding-bottom: 8px; -} - -.emotion-2 { - margin: 0; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-weight: 400; - font-size: 1rem; - line-height: 1.75; - font-weight: 700; - text-transform: capitalize; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; - -webkit-text-decoration: none; - text-decoration: none; - width: 100%; - box-sizing: border-box; - text-align: left; - padding-top: 8px; - padding-bottom: 8px; - padding-left: 16px; - padding-right: 16px; - padding-left: 0; - padding-right: 0; - -webkit-box-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.emotion-4.Mui-focusVisible { - background-color: rgba(0, 0, 0, 0.12); -} - -.emotion-4.Mui-selected { - background-color: rgba(75, 94, 64, 0.08); -} - -.emotion-4.Mui-selected.Mui-focusVisible { - background-color: rgba(75, 94, 64, 0.2); -} - -.emotion-4.Mui-disabled { - opacity: 0.38; -} - -.emotion-6 { - max-width: 100%; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-size: 0.8125rem; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - -webkit-justify-content: center; - justify-content: center; - height: 32px; - color: rgba(0, 0, 0, 0.87); - background-color: rgba(0, 0, 0, 0.08); - border-radius: 16px; - white-space: nowrap; - -webkit-transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - cursor: default; - outline: 0; - -webkit-text-decoration: none; - text-decoration: none; - border: 0; - padding: 0; - vertical-align: middle; - box-sizing: border-box; - margin-right: 5px; - text-transform: capitalize; - margin-top: 5px; -} - -.emotion-6.Mui-disabled { - opacity: 0.38; - pointer-events: none; -} - -.emotion-6 .MuiChip-avatar { - margin-left: 5px; - margin-right: -6px; - width: 24px; - height: 24px; - color: #616161; - font-size: 0.75rem; -} - -.emotion-6 .MuiChip-avatarColorPrimary { - color: #fff; - background-color: rgb(52, 65, 44); -} - -.emotion-6 .MuiChip-avatarColorSecondary { - color: #fff; - background-color: rgb(22, 24, 29); -} - -.emotion-6 .MuiChip-avatarSmall { - margin-left: 4px; - margin-right: -4px; - width: 18px; - height: 18px; - font-size: 0.625rem; -} - -.emotion-6 .MuiChip-icon { - margin-left: 5px; - margin-right: -6px; - color: #616161; -} - -.emotion-6 .MuiChip-deleteIcon { - -webkit-tap-highlight-color: transparent; - color: rgba(0, 0, 0, 0.26); - font-size: 22px; - cursor: pointer; - margin: 0 5px 0 -6px; -} - -.emotion-6 .MuiChip-deleteIcon:hover { - color: rgba(0, 0, 0, 0.4); -} - -.emotion-7 { - overflow: hidden; - text-overflow: ellipsis; - padding-left: 12px; - padding-right: 12px; - white-space: nowrap; -} - -
-
    -
    - sidebar.distribution.title -
    -
  • -
    - - - sidebar.distribution.file-count - - : - 7 - -
    -
    - - - sidebar.distribution.size - - : - 10.00 Bytes - -
    -
    - - - sidebar.distribution.license - - : - MIT - -
    -
  • -
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; - -exports[` component should render the component with license as string 1`] = ` -{ - "asFragment": [Function], - "baseElement": .emotion-0 { - list-style: none; - margin: 0; - padding: 0; - position: relative; - padding-top: 0; - padding-bottom: 8px; -} - -.emotion-2 { - margin: 0; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-weight: 400; - font-size: 1rem; - line-height: 1.75; - font-weight: 700; - text-transform: capitalize; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; - -webkit-text-decoration: none; - text-decoration: none; - width: 100%; - box-sizing: border-box; - text-align: left; - padding-top: 8px; - padding-bottom: 8px; - padding-left: 16px; - padding-right: 16px; - padding-left: 0; - padding-right: 0; - -webkit-box-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.emotion-4.Mui-focusVisible { - background-color: rgba(0, 0, 0, 0.12); -} - -.emotion-4.Mui-selected { - background-color: rgba(75, 94, 64, 0.08); -} - -.emotion-4.Mui-selected.Mui-focusVisible { - background-color: rgba(75, 94, 64, 0.2); -} - -.emotion-4.Mui-disabled { - opacity: 0.38; -} - -.emotion-6 { - max-width: 100%; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-size: 0.8125rem; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - -webkit-justify-content: center; - justify-content: center; - height: 32px; - color: rgba(0, 0, 0, 0.87); - background-color: rgba(0, 0, 0, 0.08); - border-radius: 16px; - white-space: nowrap; - -webkit-transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - cursor: default; - outline: 0; - -webkit-text-decoration: none; - text-decoration: none; - border: 0; - padding: 0; - vertical-align: middle; - box-sizing: border-box; - margin-right: 5px; - text-transform: capitalize; - margin-top: 5px; -} - -.emotion-6.Mui-disabled { - opacity: 0.38; - pointer-events: none; -} - -.emotion-6 .MuiChip-avatar { - margin-left: 5px; - margin-right: -6px; - width: 24px; - height: 24px; - color: #616161; - font-size: 0.75rem; -} - -.emotion-6 .MuiChip-avatarColorPrimary { - color: #fff; - background-color: rgb(52, 65, 44); -} - -.emotion-6 .MuiChip-avatarColorSecondary { - color: #fff; - background-color: rgb(22, 24, 29); -} - -.emotion-6 .MuiChip-avatarSmall { - margin-left: 4px; - margin-right: -4px; - width: 18px; - height: 18px; - font-size: 0.625rem; -} - -.emotion-6 .MuiChip-icon { - margin-left: 5px; - margin-right: -6px; - color: #616161; -} - -.emotion-6 .MuiChip-deleteIcon { - -webkit-tap-highlight-color: transparent; - color: rgba(0, 0, 0, 0.26); - font-size: 22px; - cursor: pointer; - margin: 0 5px 0 -6px; -} - -.emotion-6 .MuiChip-deleteIcon:hover { - color: rgba(0, 0, 0, 0.4); -} - -.emotion-7 { - overflow: hidden; - text-overflow: ellipsis; - padding-left: 12px; - padding-right: 12px; - white-space: nowrap; -} - - -
-
    -
    - sidebar.distribution.title -
    -
  • -
    - - - sidebar.distribution.file-count - - : - 7 - -
    -
    - - - sidebar.distribution.size - - : - 10.00 Bytes - -
    -
    - - - sidebar.distribution.license - - : - MIT - -
    -
  • -
-
- , - "container": .emotion-0 { - list-style: none; - margin: 0; - padding: 0; - position: relative; - padding-top: 0; - padding-bottom: 8px; -} - -.emotion-2 { - margin: 0; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-weight: 400; - font-size: 1rem; - line-height: 1.75; - font-weight: 700; - text-transform: capitalize; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: start; - -ms-flex-pack: start; - -webkit-justify-content: flex-start; - justify-content: flex-start; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; - -webkit-text-decoration: none; - text-decoration: none; - width: 100%; - box-sizing: border-box; - text-align: left; - padding-top: 8px; - padding-bottom: 8px; - padding-left: 16px; - padding-right: 16px; - padding-left: 0; - padding-right: 0; - -webkit-box-flex-wrap: wrap; - -webkit-flex-wrap: wrap; - -ms-flex-wrap: wrap; - flex-wrap: wrap; -} - -.emotion-4.Mui-focusVisible { - background-color: rgba(0, 0, 0, 0.12); -} - -.emotion-4.Mui-selected { - background-color: rgba(75, 94, 64, 0.08); -} - -.emotion-4.Mui-selected.Mui-focusVisible { - background-color: rgba(75, 94, 64, 0.2); -} - -.emotion-4.Mui-disabled { - opacity: 0.38; -} - -.emotion-6 { - max-width: 100%; - font-family: -apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; - font-size: 0.8125rem; - display: -webkit-inline-box; - display: -webkit-inline-flex; - display: -ms-inline-flexbox; - display: inline-flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -ms-flex-pack: center; - -webkit-justify-content: center; - justify-content: center; - height: 32px; - color: rgba(0, 0, 0, 0.87); - background-color: rgba(0, 0, 0, 0.08); - border-radius: 16px; - white-space: nowrap; - -webkit-transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; - cursor: default; - outline: 0; - -webkit-text-decoration: none; - text-decoration: none; - border: 0; - padding: 0; - vertical-align: middle; - box-sizing: border-box; - margin-right: 5px; - text-transform: capitalize; - margin-top: 5px; -} - -.emotion-6.Mui-disabled { - opacity: 0.38; - pointer-events: none; -} - -.emotion-6 .MuiChip-avatar { - margin-left: 5px; - margin-right: -6px; - width: 24px; - height: 24px; - color: #616161; - font-size: 0.75rem; -} - -.emotion-6 .MuiChip-avatarColorPrimary { - color: #fff; - background-color: rgb(52, 65, 44); -} - -.emotion-6 .MuiChip-avatarColorSecondary { - color: #fff; - background-color: rgb(22, 24, 29); -} - -.emotion-6 .MuiChip-avatarSmall { - margin-left: 4px; - margin-right: -4px; - width: 18px; - height: 18px; - font-size: 0.625rem; -} - -.emotion-6 .MuiChip-icon { - margin-left: 5px; - margin-right: -6px; - color: #616161; -} - -.emotion-6 .MuiChip-deleteIcon { - -webkit-tap-highlight-color: transparent; - color: rgba(0, 0, 0, 0.26); - font-size: 22px; - cursor: pointer; - margin: 0 5px 0 -6px; -} - -.emotion-6 .MuiChip-deleteIcon:hover { - color: rgba(0, 0, 0, 0.4); -} - -.emotion-7 { - overflow: hidden; - text-overflow: ellipsis; - padding-left: 12px; - padding-right: 12px; - white-space: nowrap; -} - -
-
    -
    - sidebar.distribution.title -
    -
  • -
    - - - sidebar.distribution.file-count - - : - 7 - -
    -
    - - - sidebar.distribution.size - - : - 10.00 Bytes - -
    -
    - - - sidebar.distribution.license - - : - MIT - -
    -
  • -
-
, - "debug": [Function], - "findAllByAltText": [Function], - "findAllByDisplayValue": [Function], - "findAllByLabelText": [Function], - "findAllByPlaceholderText": [Function], - "findAllByRole": [Function], - "findAllByTestId": [Function], - "findAllByText": [Function], - "findAllByTitle": [Function], - "findByAltText": [Function], - "findByDisplayValue": [Function], - "findByLabelText": [Function], - "findByPlaceholderText": [Function], - "findByRole": [Function], - "findByTestId": [Function], - "findByText": [Function], - "findByTitle": [Function], - "getAllByAltText": [Function], - "getAllByDisplayValue": [Function], - "getAllByLabelText": [Function], - "getAllByPlaceholderText": [Function], - "getAllByRole": [Function], - "getAllByTestId": [Function], - "getAllByText": [Function], - "getAllByTitle": [Function], - "getByAltText": [Function], - "getByDisplayValue": [Function], - "getByLabelText": [Function], - "getByPlaceholderText": [Function], - "getByRole": [Function], - "getByTestId": [Function], - "getByText": [Function], - "getByTitle": [Function], - "queryAllByAltText": [Function], - "queryAllByDisplayValue": [Function], - "queryAllByLabelText": [Function], - "queryAllByPlaceholderText": [Function], - "queryAllByRole": [Function], - "queryAllByTestId": [Function], - "queryAllByText": [Function], - "queryAllByTitle": [Function], - "queryByAltText": [Function], - "queryByDisplayValue": [Function], - "queryByLabelText": [Function], - "queryByPlaceholderText": [Function], - "queryByRole": [Function], - "queryByTestId": [Function], - "queryByText": [Function], - "queryByTitle": [Function], - "rerender": [Function], - "unmount": [Function], -} -`; diff --git a/packages/ui-components/src/components/Distribution/utils.ts b/packages/ui-components/src/components/Distribution/utils.ts index 09a2a3cc3..249c7e4c7 100644 --- a/packages/ui-components/src/components/Distribution/utils.ts +++ b/packages/ui-components/src/components/Distribution/utils.ts @@ -1,10 +1,11 @@ +import { LicenseInterface } from '../../types/packageMeta'; + /** * Formats license field for webui. * @see https://docs.npmjs.com/files/package.json#license */ // 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 | undefined { +export function formatLicense(license: string | LicenseInterface): string | undefined { if (typeof license === 'string') { return license; } diff --git a/packages/ui-components/src/components/Distribution/utilts.spec.ts b/packages/ui-components/src/components/Distribution/utilts.spec.ts new file mode 100644 index 000000000..cbec4449c --- /dev/null +++ b/packages/ui-components/src/components/Distribution/utilts.spec.ts @@ -0,0 +1,17 @@ +import { fileSizeSI, formatLicense } from './utils'; + +test('formatLicense as string', () => { + expect(formatLicense('MIT')).toEqual('MIT'); +}); + +test('formatLicense as format object', () => { + expect(formatLicense({ type: 'MIT' })).toEqual('MIT'); +}); + +test('fileSizeSI as number 1000', () => { + expect(fileSizeSI(1000)).toEqual('1.00 kB'); +}); + +test('fileSizeSI as number 0', () => { + expect(fileSizeSI(0)).toEqual('0.00 Bytes'); +}); diff --git a/packages/ui-components/src/components/Package/Package.tsx b/packages/ui-components/src/components/Package/Package.tsx index 61ac5588a..ff4e07417 100644 --- a/packages/ui-components/src/components/Package/Package.tsx +++ b/packages/ui-components/src/components/Package/Package.tsx @@ -122,7 +122,7 @@ const Package: React.FC = ({ license && ( - {license} + {license as string} ); diff --git a/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.spec.tsx b/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.spec.tsx new file mode 100644 index 000000000..7be442275 --- /dev/null +++ b/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.spec.tsx @@ -0,0 +1,52 @@ +import { render } from '@testing-library/react'; +import i18n from 'i18next'; +import React from 'react'; +import { initReactI18next } from 'react-i18next'; +import { useTranslation } from 'react-i18next'; + +import TranslatorProvider, { useLanguage } from './TranslatorProvider'; + +i18n.use(initReactI18next).init({ + lng: 'en-US', + fallbackLng: 'en-US', + whitelist: ['en-US'], + load: 'currentOnly', + react: { + useSuspense: false, + }, + resources: { + 'en-US': { + translation: { + 'copy-to-clipboard': 'Copy to clipboard', + 'author-anonymous': 'Anonymous', + 'author-unknown': 'Unknown', + }, + }, + }, + debug: false, + interpolation: { + escapeValue: false, + }, +}); + +const RandomComponent = () => { + const { language } = useLanguage(); + const { t } = useTranslation(); + return ( +
+
{language}
+
{t('copy-to-clipboard')}
+
+ ); +}; + +test('should provide translation', () => { + const mount = jest.fn(); + const { getByText } = render( + + + + ); + expect(getByText('en-US')).toBeInTheDocument(); + expect(getByText('Copy to clipboard')).toBeInTheDocument(); +}); diff --git a/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.tsx b/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.tsx index 2fdceff8e..dde6355bc 100644 --- a/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.tsx +++ b/packages/ui-components/src/providers/TranslatorProvider/TranslatorProvider.tsx @@ -1,3 +1,4 @@ +import { i18n } from 'i18next'; import React, { FunctionComponent, createContext, useCallback, useContext, useEffect } from 'react'; import { I18nextProvider } from 'react-i18next'; @@ -24,7 +25,7 @@ const I18nTranslatorContext = createContext({ */ const TranslatorProvider: FunctionComponent<{ children: React.ReactElement; - i18n: any; + i18n: i18n; listLanguages: any; onMount: () => {}; }> = ({ children, onMount, i18n, listLanguages }) => { diff --git a/packages/ui-components/src/providers/VersionProvider/VersionProvider.test.tsx b/packages/ui-components/src/providers/VersionProvider/VersionProvider.test.tsx index 9966f1b3f..73d76892d 100644 --- a/packages/ui-components/src/providers/VersionProvider/VersionProvider.test.tsx +++ b/packages/ui-components/src/providers/VersionProvider/VersionProvider.test.tsx @@ -16,7 +16,7 @@ function CustomComponent() { const { packageMeta, packageName, packageVersion } = useVersion(); return (
-
{packageMeta?.latest?.license}
+
{packageMeta?.latest?.license as string}
{packageName}
{packageVersion}
diff --git a/packages/ui-components/src/types/packageMeta.ts b/packages/ui-components/src/types/packageMeta.ts index 88fdd569d..1966731f6 100644 --- a/packages/ui-components/src/types/packageMeta.ts +++ b/packages/ui-components/src/types/packageMeta.ts @@ -4,7 +4,7 @@ export type Latest = { author?: Author; deprecated?: string; name: string; - dist: { + dist?: { fileCount: number; unpackedSize: number; tarball?: string; @@ -15,7 +15,7 @@ export type Latest = { pnpm?: string; yarn?: string; }; - license?: Partial | string; + license?: undefined | LicenseInterface | string; version: string; homepage?: string; bugs?: { @@ -50,12 +50,12 @@ export interface Developer { interface Funding { type?: string; - url: string; + url?: string; } -interface LicenseInterface { - type: string; - url: string; +export interface LicenseInterface { + type?: string; + url?: string; } export interface DistTags { diff --git a/packages/ui-components/tsconfig.build.json b/packages/ui-components/tsconfig.build.json index 2398a36ed..bc83a0ecf 100644 --- a/packages/ui-components/tsconfig.build.json +++ b/packages/ui-components/tsconfig.build.json @@ -13,6 +13,7 @@ "jsx": "react" }, "include": ["src/**/*", "./src/types/index.d.ts"], + "types": ["node", "jest", "@testing-library/jest-dom"], "typedocOptions": { "categoryOrder": ["Model", "Component", "Provider", "*"], "defaultCategory": "Component",