mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-16 21:56:25 -05:00
chore: add ui tests (#4512)
* chore: ui test coverage * ui test coverage * add tests * add dep
This commit is contained in:
parent
82ae08e3c8
commit
1bae2c431a
27 changed files with 36159 additions and 352 deletions
2
.github/workflows/e2e-ci.yml
vendored
2
.github/workflows/e2e-ci.yml
vendored
|
@ -4,7 +4,7 @@ on: [pull_request]
|
|||
permissions:
|
||||
contents: read
|
||||
concurrency:
|
||||
group: e2e
|
||||
group: e2e-ci-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
prepare:
|
||||
|
|
2
.github/workflows/e2e-ui.yml
vendored
2
.github/workflows/e2e-ui.yml
vendored
|
@ -4,7 +4,7 @@ on: [pull_request]
|
|||
permissions:
|
||||
contents: read
|
||||
concurrency:
|
||||
group: e2e
|
||||
group: e2e-ui-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
test:
|
||||
|
|
|
@ -47,8 +47,10 @@
|
|||
"@emotion/react": "11.10.6",
|
||||
"@emotion/styled": "11.10.6",
|
||||
"@testing-library/dom": "9.3.4",
|
||||
"@testing-library/jest-dom": "6.3.0",
|
||||
"@testing-library/react": "14.1.2",
|
||||
"@testing-library/jest-dom": "6.4.2",
|
||||
"@testing-library/user-event": "14.5.2",
|
||||
"aria-query": "5.1.3",
|
||||
"@testing-library/react": "14.2.1",
|
||||
"@trivago/prettier-plugin-sort-imports": "4.3.0",
|
||||
"@types/body-parser": "1.19.5",
|
||||
"@types/connect": "3.4.38",
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
"raw-loader": "4.0.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-hook-form": "7.49.3",
|
||||
"react-hook-form": "7.50.1",
|
||||
"react-hot-loader": "4.13.1",
|
||||
"react-i18next": "13.5.0",
|
||||
"react-json-view": "1.21.3",
|
||||
|
|
12520
packages/ui-components/jest/api/glob-sidebar.json
Normal file
12520
packages/ui-components/jest/api/glob-sidebar.json
Normal file
File diff suppressed because it is too large
Load diff
23346
packages/ui-components/jest/api/got-sidebar.json
Normal file
23346
packages/ui-components/jest/api/got-sidebar.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -34,10 +34,10 @@ module.exports = Object.assign({}, config, {
|
|||
coverageReporters: ['text', 'html'],
|
||||
coverageThreshold: {
|
||||
global: {
|
||||
branches: 66,
|
||||
functions: 65,
|
||||
lines: 73,
|
||||
statements: 73,
|
||||
branches: 70,
|
||||
functions: 76,
|
||||
lines: 80,
|
||||
statements: 82,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -31,7 +31,18 @@ export const handlers = [
|
|||
rest.get('http://localhost:9000/-/verdaccio/data/sidebar/jquery', (req, res, ctx) => {
|
||||
return res(ctx.json(require('./api/jquery-sidebar.json')));
|
||||
}),
|
||||
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/sidebar/glob', (req, res, ctx) => {
|
||||
return res(ctx.json(require('./api/glob-sidebar.json')));
|
||||
}),
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/package/readme/glob', (req, res, ctx) => {
|
||||
return res(ctx.text('foo glob'));
|
||||
}),
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/sidebar/got', (req, res, ctx) => {
|
||||
return res(ctx.json(require('./api/got-sidebar.json')));
|
||||
}),
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/package/readme/got', (req, res, ctx) => {
|
||||
return res(ctx.text('foo got'));
|
||||
}),
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/package/readme/jquery', (req, res, ctx) => {
|
||||
return res(ctx.text(require('./api/jquery-readme')()));
|
||||
}),
|
||||
|
|
|
@ -6,7 +6,6 @@ import Dependencies from './Dependencies';
|
|||
|
||||
describe('<Dependencies /> component', () => {
|
||||
test('Renders a message when there are no dependencies', () => {
|
||||
// Given
|
||||
const packageMeta = {
|
||||
latest: {
|
||||
name: 'verdaccio',
|
||||
|
@ -25,15 +24,12 @@ describe('<Dependencies /> component', () => {
|
|||
_uplinks: {},
|
||||
};
|
||||
|
||||
// When
|
||||
const { getByText } = render(<Dependencies packageMeta={packageMeta} />);
|
||||
|
||||
// Then
|
||||
expect(getByText('dependencies.has-no-dependencies')).toBeDefined();
|
||||
});
|
||||
|
||||
test('Renders a link to each dependency', () => {
|
||||
// Given
|
||||
test('renders a link to each dependency', () => {
|
||||
const packageMeta = {
|
||||
latest: {
|
||||
name: 'verdaccio',
|
||||
|
@ -59,18 +55,12 @@ describe('<Dependencies /> component', () => {
|
|||
_uplinks: {},
|
||||
};
|
||||
|
||||
// When
|
||||
const { getByText } = render(
|
||||
<HashRouter>
|
||||
<Dependencies packageMeta={packageMeta} />
|
||||
</HashRouter>
|
||||
);
|
||||
|
||||
// Then
|
||||
// FIXME: currently MaterialUI chips do not support the children
|
||||
// prop, therefore it is impossible to use proper links for
|
||||
// dependencies. Those are for now clickable spans
|
||||
|
||||
expect(getByText('dependencies (2)')).toBeDefined();
|
||||
expect(getByText('devDependencies (1)')).toBeDefined();
|
||||
expect(getByText('peerDependencies (1)')).toBeDefined();
|
||||
|
|
|
@ -1,63 +1,21 @@
|
|||
import Box from '@mui/material/Box';
|
||||
import styled from '@emotion/styled';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import { useTheme } from '@mui/styles';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { PackageDependencies } from '../../types/packageMeta';
|
||||
import { Theme } from '../../Theme';
|
||||
import NoItems from '../NoItems';
|
||||
import { CardWrap, StyledText, Tag, Tags } from './styles';
|
||||
import { DependencyBlock } from './DependencyBlock';
|
||||
import { hasKeys } from './utits';
|
||||
|
||||
interface DependencyBlockProps {
|
||||
title: string;
|
||||
dependencies: PackageDependencies;
|
||||
}
|
||||
|
||||
const DependencyBlock: React.FC<DependencyBlockProps> = ({ title, dependencies }) => {
|
||||
const history = useHistory();
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
|
||||
const deps = Object.entries(dependencies);
|
||||
|
||||
function handleClick(name: string): void {
|
||||
history.push(`/-/web/detail/${name}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box data-testid={title} sx={{ margin: theme.spacing(2) }}>
|
||||
<StyledText sx={{ marginBottom: theme.spacing(1) }} variant="subtitle1">
|
||||
{`${title} (${deps.length})`}
|
||||
</StyledText>
|
||||
<Tags>
|
||||
{deps.map(([name, version]) => (
|
||||
<Tag
|
||||
className={'dep-tag'}
|
||||
clickable={true}
|
||||
data-testid={name}
|
||||
key={name}
|
||||
label={t('dependencies.dependency-block', { package: name, version })}
|
||||
// eslint-disable-next-line
|
||||
onClick={() => handleClick(name)}
|
||||
/>
|
||||
))}
|
||||
</Tags>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
function hasKeys(object?: { [key: string]: any }): boolean {
|
||||
return !!object && Object.keys(object).length > 0;
|
||||
}
|
||||
export const CardWrap = styled(Card)<{ theme?: Theme }>((props) => ({
|
||||
marginBottom: props.theme.spacing(2),
|
||||
}));
|
||||
|
||||
const Dependencies: React.FC<{ packageMeta: any }> = ({ packageMeta }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!packageMeta) {
|
||||
throw new Error(t('error.package-meta-is-required-at-detail-context'));
|
||||
}
|
||||
|
||||
const { latest } = packageMeta;
|
||||
// FIXME: add dependencies to package meta type
|
||||
// @ts-ignore
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { MemoryRouter, Route } from 'react-router';
|
||||
|
||||
import { render, screen } from '../../test/test-react-testing-library';
|
||||
import { DependencyBlock } from './DependencyBlock';
|
||||
|
||||
describe('<DependencyBlock /> component', () => {
|
||||
test('renders dependency block', () => {
|
||||
render(<DependencyBlock dependencies={{ jquery: '1.0.0' }} title="foo" />);
|
||||
|
||||
expect(screen.getByText('foo (1)')).toBeInTheDocument();
|
||||
expect(screen.getByText('dependencies.dependency-block')).toBeInTheDocument();
|
||||
|
||||
userEvent.click(screen.getByText('dependencies.dependency-block'));
|
||||
});
|
||||
|
||||
test.todo('test the click event');
|
||||
test.skip('handle change route handler', () => {
|
||||
render(
|
||||
<MemoryRouter
|
||||
initialEntries={[`/-/web/detail/some-dep`, `/-/web/detail/jquery`]}
|
||||
initialIndex={0}
|
||||
>
|
||||
<Route exact={true} path="/-/web/detail/:package">
|
||||
<DependencyBlock dependencies={{ jquery: '1.0.0' }} title="foo" />
|
||||
</Route>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
userEvent.click(screen.getByTestId('jquery'));
|
||||
});
|
||||
});
|
|
@ -0,0 +1,69 @@
|
|||
import styled from '@emotion/styled';
|
||||
import Box from '@mui/material/Box';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useTheme } from '@mui/styles';
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Theme } from '../../Theme';
|
||||
import { PackageDependencies } from '../../types/packageMeta';
|
||||
|
||||
interface DependencyBlockProps {
|
||||
title: string;
|
||||
dependencies: PackageDependencies;
|
||||
}
|
||||
|
||||
export const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({
|
||||
fontWeight: props.theme && props.theme.fontWeight.bold,
|
||||
textTransform: 'capitalize',
|
||||
}));
|
||||
|
||||
export const Tags = styled('div')<{ theme?: Theme }>((props) => ({
|
||||
display: 'flex',
|
||||
justifyContent: 'start',
|
||||
flexWrap: 'wrap',
|
||||
// force title to be on the same line as the title
|
||||
// could be better to avoid margin on the first element
|
||||
// but it is a bit tricky to do with flexbox
|
||||
marginLeft: props.theme.spacing(-0.6),
|
||||
}));
|
||||
|
||||
export const Tag = styled(Chip)<{ theme?: Theme }>((props) => ({
|
||||
margin: props.theme.spacing(0.6),
|
||||
}));
|
||||
|
||||
export const DependencyBlock: React.FC<DependencyBlockProps> = ({ title, dependencies }) => {
|
||||
const history = useHistory();
|
||||
const { t } = useTranslation();
|
||||
const theme = useTheme();
|
||||
const deps = Object.entries(dependencies);
|
||||
|
||||
function handleClick(name: string): void {
|
||||
history.push(`/-/web/detail/${name}`);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box data-testid={title} sx={{ margin: theme.spacing(2) }}>
|
||||
<StyledText sx={{ marginBottom: theme.spacing(1) }} variant="subtitle1">
|
||||
{`${title} (${deps.length})`}
|
||||
</StyledText>
|
||||
<Tags>
|
||||
{deps.map(([name, version]) => (
|
||||
<Tag
|
||||
className={'dep-tag'}
|
||||
clickable={true}
|
||||
data-testid={name}
|
||||
key={name}
|
||||
label={t('dependencies.dependency-block', { package: name, version })}
|
||||
// eslint-disable-next-line
|
||||
onClick={() => {
|
||||
handleClick(name);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Tags>
|
||||
</Box>
|
||||
);
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
import styled from '@emotion/styled';
|
||||
import Card from '@mui/material/Card';
|
||||
import Chip from '@mui/material/Chip';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
import { Theme } from '../../Theme';
|
||||
|
||||
export const CardWrap = styled(Card)({
|
||||
margin: '0 0 16px',
|
||||
});
|
||||
|
||||
export const StyledText = styled(Typography)<{ theme?: Theme }>((props) => ({
|
||||
fontWeight: props.theme && props.theme.fontWeight.bold,
|
||||
textTransform: 'capitalize',
|
||||
}));
|
||||
|
||||
export const Tags = styled('div')({
|
||||
display: 'flex',
|
||||
justifyContent: 'start',
|
||||
flexWrap: 'wrap',
|
||||
margin: '0 -5px',
|
||||
});
|
||||
|
||||
export const Tag = styled(Chip)({
|
||||
margin: '5px',
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export function hasKeys(object?: { [key: string]: any }): boolean {
|
||||
return !!object && Object.keys(object).length > 0;
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
import { render } from '../../test/test-react-testing-library';
|
||||
import { render, screen } from '../../test/test-react-testing-library';
|
||||
import Loading from './Loading';
|
||||
|
||||
describe('<Loading /> component', () => {
|
||||
test('should render the component in default state', () => {
|
||||
const { container } = render(<Loading />);
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
render(<Loading />);
|
||||
screen.debug();
|
||||
expect(screen.getByTestId('loading')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Loading /> component should render the component in default state 1`] = `
|
||||
@keyframes animation-0 {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
-moz-transform: rotate(0deg);
|
||||
-ms-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
-moz-transform: rotate(360deg);
|
||||
-ms-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes animation-1 {
|
||||
0% {
|
||||
stroke-dasharray: 1px,200px;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
|
||||
50% {
|
||||
stroke-dasharray: 100px,200px;
|
||||
stroke-dashoffset: -15px;
|
||||
}
|
||||
|
||||
100% {
|
||||
stroke-dasharray: 100px,200px;
|
||||
stroke-dashoffset: -125px;
|
||||
}
|
||||
}
|
||||
|
||||
.emotion-0 {
|
||||
-webkit-transform: translate(-50%, -50%);
|
||||
-moz-transform: translate(-50%, -50%);
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.emotion-2 {
|
||||
margin: 0 0 30px 0;
|
||||
border-radius: 25px;
|
||||
box-shadow: 0 10px 20px 0 rgba(69, 58, 100, 0.2);
|
||||
background: #f7f8f6;
|
||||
}
|
||||
|
||||
.emotion-4 {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
box-sizing: border-box;
|
||||
-webkit-background-position: center;
|
||||
background-position: center;
|
||||
-webkit-background-size: contain;
|
||||
background-size: contain;
|
||||
background-image: url([object Object]);
|
||||
background-repeat: no-repeat;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
}
|
||||
|
||||
.emotion-6 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: 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;
|
||||
}
|
||||
|
||||
.emotion-9 {
|
||||
display: inline-block;
|
||||
color: #4b5e40;
|
||||
-webkit-animation: animation-0 1.4s linear infinite;
|
||||
animation: animation-0 1.4s linear infinite;
|
||||
color: #4b5e40;
|
||||
}
|
||||
|
||||
.emotion-10 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.emotion-11 {
|
||||
stroke: currentColor;
|
||||
stroke-dasharray: 80px,200px;
|
||||
stroke-dashoffset: 0;
|
||||
-webkit-animation: animation-1 1.4s ease-in-out infinite;
|
||||
animation: animation-1 1.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
<div
|
||||
class="emotion-0 emotion-1"
|
||||
data-testid="loading"
|
||||
>
|
||||
<div
|
||||
class="emotion-2 emotion-3"
|
||||
>
|
||||
<div
|
||||
class="emotion-4 emotion-5"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="emotion-6 emotion-7"
|
||||
>
|
||||
<span
|
||||
class="MuiCircularProgress-root MuiCircularProgress-indeterminate MuiCircularProgress-colorPrimary emotion-8 emotion-9"
|
||||
role="progressbar"
|
||||
style="width: 50px; height: 50px;"
|
||||
>
|
||||
<svg
|
||||
class="MuiCircularProgress-svg emotion-10"
|
||||
viewBox="22 22 44 44"
|
||||
>
|
||||
<circle
|
||||
class="MuiCircularProgress-circle MuiCircularProgress-circleIndeterminate emotion-11"
|
||||
cx="44"
|
||||
cy="44"
|
||||
fill="none"
|
||||
r="20.2"
|
||||
stroke-width="3.6"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1 @@
|
|||
export { default } from './SideBarTitle';
|
|
@ -1 +0,0 @@
|
|||
export { default } from './SideBarTittle';
|
|
@ -14,7 +14,7 @@ export * as Icons from './components/Icons';
|
|||
export { default as Install } from './components/Install';
|
||||
export { default as RawViewer } from './components/RawViewer';
|
||||
export { default as Readme } from './components/Readme';
|
||||
export { default as SideBarTitle } from './components/SideBarTittle';
|
||||
export { default as SideBarTitle } from './components/SideBarTitle';
|
||||
export { default as UpLinks } from './components/UpLinks';
|
||||
export { default as Versions } from './components/Versions';
|
||||
export { default as TextField } from './components/TextField';
|
||||
|
|
29
packages/ui-components/src/sections/Home/Home.test.tsx
Normal file
29
packages/ui-components/src/sections/Home/Home.test.tsx
Normal file
|
@ -0,0 +1,29 @@
|
|||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
|
||||
import { store } from '../../store';
|
||||
import { renderWithStore, screen, waitFor } from '../../test/test-react-testing-library';
|
||||
import Home from './Home';
|
||||
|
||||
// force the windows to expand to display items
|
||||
// https://github.com/bvaughn/react-virtualized/issues/493#issuecomment-640084107
|
||||
jest.spyOn(HTMLElement.prototype, 'offsetHeight', 'get').mockReturnValue(600);
|
||||
jest.spyOn(HTMLElement.prototype, 'offsetWidth', 'get').mockReturnValue(600);
|
||||
|
||||
const ComponentSideBar: React.FC = () => (
|
||||
<MemoryRouter>
|
||||
<Home />
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
describe('Home', () => {
|
||||
test('should render titles', async () => {
|
||||
renderWithStore(<ComponentSideBar />, store);
|
||||
await waitFor(() => expect(screen.getAllByTestId('package-item-list')).toHaveLength(5));
|
||||
});
|
||||
|
||||
test('should render loading', async () => {
|
||||
renderWithStore(<ComponentSideBar />, store);
|
||||
await waitFor(() => expect(screen.getByTestId('loading')).toBeInTheDocument());
|
||||
});
|
||||
});
|
|
@ -11,7 +11,6 @@ const Home: React.FC = () => {
|
|||
// @ts-ignore
|
||||
dispatch.packages.getPackages();
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<div className="container content" data-testid="home-page-container">
|
||||
{isLoading ? <Loading /> : <PackageList packages={packages} />}
|
||||
|
|
|
@ -1,110 +1,67 @@
|
|||
import { rest } from 'msw';
|
||||
import React from 'react';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
|
||||
import { server } from '../../../jest/server';
|
||||
import { VersionProvider } from '../../providers';
|
||||
import { store } from '../../store';
|
||||
import { renderWithStore, screen, waitFor } from '../../test/test-react-testing-library';
|
||||
import DetailSidebar from './Sidebar';
|
||||
import Sidebar from './Sidebar';
|
||||
|
||||
jest.mock('marked');
|
||||
jest.mock('marked');
|
||||
jest.mock('marked-highlight');
|
||||
|
||||
const ComponentToBeRendered: React.FC = () => (
|
||||
const ComponentSideBar: React.FC = () => (
|
||||
<MemoryRouter>
|
||||
<VersionProvider>
|
||||
<DetailSidebar />
|
||||
<Sidebar />
|
||||
</VersionProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
|
||||
// https://stackoverflow.com/a/54010619/308341
|
||||
jest.mock('react', () => {
|
||||
const React = jest.requireActual('react');
|
||||
React.Suspense = ({ children }) => children;
|
||||
return React;
|
||||
});
|
||||
|
||||
const packageMeta = {
|
||||
_uplinks: {},
|
||||
latest: {
|
||||
name: 'verdaccio-ui/local-storage',
|
||||
version: '8.0.1-next.1',
|
||||
dist: {
|
||||
fileCount: 0,
|
||||
unpackedSize: 0,
|
||||
tarball: 'http://localhost:8080/bootstrap/-/bootstrap-4.3.1.tgz',
|
||||
},
|
||||
homepage: 'https://verdaccio.org',
|
||||
bugs: {
|
||||
url: 'https://github.com/verdaccio/monorepo/issues',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// const detailContextValue = {
|
||||
// packageName: 'foo',
|
||||
// readMe: 'test',
|
||||
// isLoading: false,
|
||||
// hasNotBeenFound: false,
|
||||
// packageMeta: ,
|
||||
// };
|
||||
const mockPkgName = jest.fn().mockReturnValue('jquery');
|
||||
|
||||
jest.mock('react-router-dom', () => ({
|
||||
...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
|
||||
useParams: () => ({
|
||||
package: 'jquery',
|
||||
package: mockPkgName(),
|
||||
}),
|
||||
}));
|
||||
|
||||
server.use(
|
||||
...[
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/sidebar/jquery', (req, res, ctx) => {
|
||||
return res(ctx.json(packageMeta));
|
||||
}),
|
||||
rest.get('http://localhost:9000/-/verdaccio/data/package/readme/jquery', (req, res, ctx) => {
|
||||
return res(ctx.text('foo readme'));
|
||||
}),
|
||||
]
|
||||
);
|
||||
// describe('DetailSidebar', () => {
|
||||
test.skip('should render commonjs module icon', async () => {
|
||||
const { getByText } = renderWithStore(<ComponentToBeRendered />, store);
|
||||
screen.debug();
|
||||
await waitFor(() => expect(getByText('jquery')).toBeInTheDocument());
|
||||
describe('Sidebar', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
test('should render titles', async () => {
|
||||
renderWithStore(<ComponentSideBar />, store);
|
||||
await waitFor(() => expect(screen.getByText('jquery')).toBeInTheDocument());
|
||||
|
||||
expect(screen.getByText(`jquery`)).toBeInTheDocument();
|
||||
expect(screen.getByText(`sidebar.detail.latest-version`, { exact: false })).toBeInTheDocument();
|
||||
expect(
|
||||
screen.getByText(`sidebar.detail.published a year ago`, { exact: false })
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(`sidebar.installation.title`, { exact: false })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render commonJS', async () => {
|
||||
renderWithStore(<ComponentSideBar />, store);
|
||||
|
||||
await waitFor(() => expect(screen.getByText('jquery')).toBeInTheDocument());
|
||||
expect(screen.getByAltText('commonjs')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render typescript', async () => {
|
||||
mockPkgName.mockReturnValue('glob');
|
||||
renderWithStore(<ComponentSideBar />, store);
|
||||
|
||||
await waitFor(() => expect(screen.getByText('glob')).toBeInTheDocument());
|
||||
expect(screen.getByAltText('typescript')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should render es modules', async () => {
|
||||
mockPkgName.mockReturnValue('got');
|
||||
renderWithStore(<ComponentSideBar />, store);
|
||||
|
||||
await waitFor(() => expect(screen.getByText('got')).toBeInTheDocument());
|
||||
expect(screen.getByAltText('es6 modules')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
// test('should render ts module icon', () => {
|
||||
// renderWithStore(
|
||||
// <ComponentToBeRendered
|
||||
// contextValue={_.merge(detailContextValue, {
|
||||
// packageMeta: {
|
||||
// latest: {
|
||||
// types: './src/index.d.ts',
|
||||
// },
|
||||
// },
|
||||
// })}
|
||||
// />,
|
||||
// store
|
||||
// );
|
||||
// expect(screen.getByAltText('typescript')).toBeInTheDocument();
|
||||
// });
|
||||
|
||||
// test('should render es6 module icon', () => {
|
||||
// renderWithStore(
|
||||
// <ComponentToBeRendered
|
||||
// contextValue={_.merge(detailContextValue, {
|
||||
// packageMeta: {
|
||||
// latest: {
|
||||
// type: 'module',
|
||||
// },
|
||||
// },
|
||||
// })}
|
||||
// />,
|
||||
// store
|
||||
// );
|
||||
// expect(screen.getByAltText('es6 modules')).toBeInTheDocument();
|
||||
// });
|
||||
// });
|
||||
|
|
|
@ -6,25 +6,15 @@ import { Theme } from '../../Theme';
|
|||
import ActionBar from '../../components/ActionBar';
|
||||
import Author from '../../components/Author';
|
||||
import Developers, { DeveloperType } from '../../components/Developers';
|
||||
import Dist from '../../components/Distribution';
|
||||
import Engines from '../../components/Engines';
|
||||
import FundButton from '../../components/FundButton';
|
||||
import SideBarTittle from '../../components/SideBarTittle';
|
||||
import Install from '../../components/Install';
|
||||
import Repository from '../../components/Repository';
|
||||
import SideBarTitle from '../../components/SideBarTitle';
|
||||
import { useConfig } from '../../providers';
|
||||
import { useVersion } from '../../providers';
|
||||
import { PackageMetaInterface } from '../../types/packageMeta';
|
||||
import loadable from '../../utils/loadable';
|
||||
|
||||
const Engines = loadable(
|
||||
() => import(/* webpackChunkName: "Engines" */ '../../components/Engines')
|
||||
);
|
||||
const Dist = loadable(
|
||||
() => import(/* webpackChunkName: "Distribution" */ '../../components/Distribution')
|
||||
);
|
||||
const Install = loadable(
|
||||
() => import(/* webpackChunkName: "Install" */ '../../components/Install')
|
||||
);
|
||||
const Repository = loadable(
|
||||
() => import(/* webpackChunkName: "Repository" */ '../../components/Repository')
|
||||
);
|
||||
|
||||
const getModuleType = (manifest: PackageMetaInterface) => {
|
||||
if (manifest.latest.main) {
|
||||
|
@ -40,14 +30,13 @@ const DetailSidebar: React.FC = () => {
|
|||
const { configOptions } = useConfig();
|
||||
const version = packageVersion || packageMeta?.latest.version || '';
|
||||
const time = packageMeta?.time ? packageMeta.time[version] : '';
|
||||
|
||||
if (!packageMeta || !packageName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<StyledPaper sx={{ position: 'sticky', top: 0 }}>
|
||||
<SideBarTittle
|
||||
<SideBarTitle
|
||||
description={packageMeta.latest?.description}
|
||||
hasTypes={typeof packageMeta.latest?.types === 'string'}
|
||||
isLatest={typeof packageVersion === 'undefined'}
|
||||
|
|
|
@ -105,11 +105,14 @@ importers:
|
|||
specifier: 9.3.4
|
||||
version: 9.3.4
|
||||
'@testing-library/jest-dom':
|
||||
specifier: 6.3.0
|
||||
version: 6.3.0(@types/jest@29.5.11)(jest@29.7.0)(vitest@0.34.6)
|
||||
specifier: 6.4.2
|
||||
version: 6.4.2(@types/jest@29.5.11)(jest@29.7.0)(vitest@0.34.6)
|
||||
'@testing-library/react':
|
||||
specifier: 14.1.2
|
||||
version: 14.1.2(react-dom@18.2.0)(react@18.2.0)
|
||||
specifier: 14.2.1
|
||||
version: 14.2.1(react-dom@18.2.0)(react@18.2.0)
|
||||
'@testing-library/user-event':
|
||||
specifier: 14.5.2
|
||||
version: 14.5.2(@testing-library/dom@9.3.4)
|
||||
'@trivago/prettier-plugin-sort-imports':
|
||||
specifier: 4.3.0
|
||||
version: 4.3.0(prettier@3.2.2)
|
||||
|
@ -224,6 +227,9 @@ importers:
|
|||
'@vitest/coverage-v8':
|
||||
specifier: 0.34.6
|
||||
version: 0.34.6(vitest@0.34.6)
|
||||
aria-query:
|
||||
specifier: 5.1.3
|
||||
version: 5.1.3
|
||||
babel-core:
|
||||
specifier: 7.0.0-bridge.0
|
||||
version: 7.0.0-bridge.0(@babel/core@7.23.9)
|
||||
|
@ -1305,8 +1311,8 @@ importers:
|
|||
specifier: 18.2.0
|
||||
version: 18.2.0(react@18.2.0)
|
||||
react-hook-form:
|
||||
specifier: 7.49.3
|
||||
version: 7.49.3(react@18.2.0)
|
||||
specifier: 7.50.1
|
||||
version: 7.50.1(react@18.2.0)
|
||||
react-hot-loader:
|
||||
specifier: 4.13.1
|
||||
version: 4.13.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||
|
@ -11472,6 +11478,40 @@ packages:
|
|||
vitest: 0.34.6
|
||||
dev: true
|
||||
|
||||
/@testing-library/jest-dom@6.4.2(@types/jest@29.5.11)(jest@29.7.0)(vitest@0.34.6):
|
||||
resolution: {integrity: sha512-CzqH0AFymEMG48CpzXFriYYkOjk6ZGPCLMhW9e9jg3KMCn5OfJecF8GtGW7yGfR/IgCe3SX8BSwjdzI6BBbZLw==}
|
||||
engines: {node: '>=14', npm: '>=6', yarn: '>=1'}
|
||||
peerDependencies:
|
||||
'@jest/globals': '>= 28'
|
||||
'@types/bun': latest
|
||||
'@types/jest': '>= 28'
|
||||
jest: '>= 28'
|
||||
vitest: '>= 0.32'
|
||||
peerDependenciesMeta:
|
||||
'@jest/globals':
|
||||
optional: true
|
||||
'@types/bun':
|
||||
optional: true
|
||||
'@types/jest':
|
||||
optional: true
|
||||
jest:
|
||||
optional: true
|
||||
vitest:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@adobe/css-tools': 4.3.2
|
||||
'@babel/runtime': 7.23.9
|
||||
'@types/jest': 29.5.11
|
||||
aria-query: 5.1.3
|
||||
chalk: 3.0.0
|
||||
css.escape: 1.5.1
|
||||
dom-accessibility-api: 0.6.3
|
||||
jest: 29.7.0(@types/node@20.11.7)(ts-node@10.9.2)
|
||||
lodash: 4.17.21
|
||||
redent: 3.0.0
|
||||
vitest: 0.34.6
|
||||
dev: true
|
||||
|
||||
/@testing-library/react@14.1.2(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-z4p7DVBTPjKM5qDZ0t5ZjzkpSNb+fZy1u6bzO7kk8oeGagpPCAtgh4cx1syrfp7a+QWkM021jGqjJaxJJnXAZg==}
|
||||
engines: {node: '>=14'}
|
||||
|
@ -11486,6 +11526,20 @@ packages:
|
|||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: true
|
||||
|
||||
/@testing-library/react@14.2.1(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-sGdjws32ai5TLerhvzThYFbpnF9XtL65Cjf+gB0Dhr29BGqK+mAeN7SURSdu+eqgET4ANcWoC7FQpkaiGvBr+A==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
react: ^18.0.0
|
||||
react-dom: ^18.0.0
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
'@testing-library/dom': 9.3.4
|
||||
'@types/react-dom': 18.2.18
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
dev: true
|
||||
|
||||
/@testing-library/user-event@14.5.2(@testing-library/dom@9.3.4):
|
||||
resolution: {integrity: sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
|
@ -12097,7 +12151,7 @@ packages:
|
|||
resolution: {integrity: sha512-bnreXCgus6IIadyHNlN/oI5FfX4dWgvGhOPvpr7zzCYDGAPIfvyIoAozMBINmhmsVuqV0cncejF2y5KC7ScqOg==}
|
||||
deprecated: This is a stub types definition. @testing-library/jest-dom provides its own type definitions, so you do not need this installed.
|
||||
dependencies:
|
||||
'@testing-library/jest-dom': 6.3.0(@types/jest@29.5.11)(jest@29.7.0)(vitest@0.34.6)
|
||||
'@testing-library/jest-dom': 6.4.2(@types/jest@29.5.11)(jest@29.7.0)(vitest@0.34.6)
|
||||
transitivePeerDependencies:
|
||||
- '@jest/globals'
|
||||
- '@types/bun'
|
||||
|
@ -25721,6 +25775,16 @@ packages:
|
|||
react: ^16.8.0 || ^17 || ^18
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/react-hook-form@7.50.1(react@18.2.0):
|
||||
resolution: {integrity: sha512-3PCY82oE0WgeOgUtIr3nYNNtNvqtJ7BZjsbxh6TnYNbXButaD5WpjOmTjdxZfheuHKR68qfeFnEDVYoSSFPMTQ==}
|
||||
engines: {node: '>=12.22.0'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: true
|
||||
|
||||
/react-hot-loader@4.13.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ZlqCfVRqDJmMXTulUGic4lN7Ic1SXgHAFw7y/Jb7t25GBgTR0fYAJ8uY4mrpxjRyWGWmqw77qJQGnYbzCvBU7g==}
|
||||
|
@ -25982,7 +26046,7 @@ packages:
|
|||
peerDependencies:
|
||||
react: '>=15'
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.9
|
||||
'@babel/runtime': 7.21.0
|
||||
history: 4.10.1
|
||||
hoist-non-react-statics: 3.3.2
|
||||
loose-envify: 1.4.0
|
||||
|
|
Loading…
Reference in a new issue