fix(ui-components): remove test warnings (#5113)
This commit is contained in:
5
.changeset/popular-trees-grin.md
Normal file
5
.changeset/popular-trees-grin.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'@verdaccio/ui-components': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix(ui-components): remove test warnings
|
||||||
@@ -34,13 +34,17 @@ describe('AppRoute', () => {
|
|||||||
|
|
||||||
test('renders VersionPage component for PACKAGE path', async () => {
|
test('renders VersionPage component for PACKAGE path', async () => {
|
||||||
act(() => appTest('/-/web/detail/jquery'));
|
act(() => appTest('/-/web/detail/jquery'));
|
||||||
await waitFor(() => screen.getByTestId('readme-tab'));
|
await waitFor(() => expect(screen.getByTestId('readme-tab')).toBeInTheDocument(), {
|
||||||
|
timeout: 3000,
|
||||||
|
});
|
||||||
expect(screen.getByTestId('sidebar')).toBeInTheDocument();
|
expect(screen.getByTestId('sidebar')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders VersionPage component for PACKAGE VERSION path', async () => {
|
test('renders VersionPage component for PACKAGE VERSION path', async () => {
|
||||||
act(() => appTest('/-/web/detail/jquery/v/3.6.3'));
|
act(() => appTest('/-/web/detail/jquery/v/3.6.3'));
|
||||||
await waitFor(() => screen.getByTestId('readme-tab'));
|
await waitFor(() => expect(screen.getByTestId('readme-tab')).toBeInTheDocument(), {
|
||||||
|
timeout: 3000,
|
||||||
|
});
|
||||||
expect(screen.getByTestId('sidebar')).toBeInTheDocument();
|
expect(screen.getByTestId('sidebar')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { cleanupDownloadMocks, setupDownloadMocks } from '../../../vitest/vitestHelpers';
|
||||||
import { store } from '../../store/store';
|
import { store } from '../../store/store';
|
||||||
import { cleanup, fireEvent, renderWithStore, screen } from '../../test/test-react-testing-library';
|
import {
|
||||||
|
cleanup,
|
||||||
|
fireEvent,
|
||||||
|
renderWithStore,
|
||||||
|
screen,
|
||||||
|
waitFor,
|
||||||
|
} from '../../test/test-react-testing-library';
|
||||||
import ActionBar from './ActionBar';
|
import ActionBar from './ActionBar';
|
||||||
|
|
||||||
const defaultPackageMeta = {
|
const defaultPackageMeta = {
|
||||||
@@ -21,25 +28,37 @@ const defaultPackageMeta = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
setupDownloadMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
cleanupDownloadMocks();
|
||||||
|
});
|
||||||
|
|
||||||
describe('<ActionBar /> component', () => {
|
describe('<ActionBar /> component', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render the component in default state', () => {
|
test('should render the component in default state', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} />, store);
|
||||||
expect(screen.getByTestId('download-tarball-btn')).toBeInTheDocument();
|
await waitFor(() => {
|
||||||
expect(screen.getByTestId('BugReportIcon')).toBeInTheDocument();
|
expect(screen.getByTestId('download-tarball-btn')).toBeInTheDocument();
|
||||||
expect(screen.getByTestId('HomeIcon')).toBeInTheDocument();
|
expect(screen.getByTestId('BugReportIcon')).toBeInTheDocument();
|
||||||
|
expect(screen.getByTestId('HomeIcon')).toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not render if data is missing', () => {
|
test('should not render if data is missing', async () => {
|
||||||
// @ts-ignore - testing with missing data
|
// @ts-ignore - testing with missing data
|
||||||
renderWithStore(<ActionBar packageMeta={undefined} />, store);
|
renderWithStore(<ActionBar packageMeta={undefined} />, store);
|
||||||
expect(screen.queryByTestId('HomeIcon')).toBeNull();
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByTestId('HomeIcon')).toBeNull();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when there is no action bar data', () => {
|
test('when there is no action bar data', async () => {
|
||||||
const packageMeta = {
|
const packageMeta = {
|
||||||
...defaultPackageMeta,
|
...defaultPackageMeta,
|
||||||
latest: {
|
latest: {
|
||||||
@@ -54,60 +73,80 @@ describe('<ActionBar /> component', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
renderWithStore(<ActionBar packageMeta={packageMeta} />, store);
|
renderWithStore(<ActionBar packageMeta={packageMeta} />, store);
|
||||||
expect(screen.queryByTestId('download-tarball-btn')).not.toBeInTheDocument();
|
await waitFor(() => {
|
||||||
expect(screen.queryByTestId('BugReportIcon')).not.toBeInTheDocument();
|
expect(screen.queryByTestId('download-tarball-btn')).not.toBeInTheDocument();
|
||||||
expect(screen.queryByTestId('HomeIcon')).not.toBeInTheDocument();
|
expect(screen.queryByTestId('BugReportIcon')).not.toBeInTheDocument();
|
||||||
|
expect(screen.queryByTestId('HomeIcon')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when there is a button to download a tarball', () => {
|
test('when there is a button to download a tarball', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} />, store);
|
||||||
expect(screen.getByLabelText('action-bar-action.download-tarball')).toBeTruthy();
|
await waitFor(() => {
|
||||||
|
expect(screen.getByLabelText('action-bar-action.download-tarball')).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when button to download is disabled', () => {
|
test('when button to download is disabled', async () => {
|
||||||
renderWithStore(
|
renderWithStore(
|
||||||
<ActionBar packageMeta={defaultPackageMeta} showDownloadTarball={false} />,
|
<ActionBar packageMeta={defaultPackageMeta} showDownloadTarball={false} />,
|
||||||
store
|
store
|
||||||
);
|
);
|
||||||
expect(screen.queryByTestId('download-tarball-btn')).not.toBeInTheDocument();
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByTestId('download-tarball-btn')).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when there is a button to raw manifest', () => {
|
test('when there is a button to raw manifest', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={true} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={true} />, store);
|
||||||
expect(screen.getByLabelText('action-bar-action.raw')).toBeTruthy();
|
await waitFor(() => {
|
||||||
|
expect(screen.getByLabelText('action-bar-action.raw')).toBeTruthy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when click button to raw manifest open a dialog with viewer', async () => {
|
test('when click button to raw manifest open a dialog with viewer', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={true} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={true} />, store);
|
||||||
expect(screen.queryByTestId('rawViewer--dialog')).toBeFalsy();
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByTestId('rawViewer--dialog')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
fireEvent.click(screen.getByLabelText('action-bar-action.raw'));
|
fireEvent.click(screen.getByLabelText('action-bar-action.raw'));
|
||||||
await screen.findByTestId('rawViewer--dialog');
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('rawViewer--dialog')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
fireEvent.click(screen.getByTestId('close-raw-viewer'));
|
fireEvent.click(screen.getByTestId('close-raw-viewer'));
|
||||||
await screen.getByLabelText('action-bar-action.raw');
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByTestId('rawViewer--dialog')).toBeFalsy();
|
||||||
expect(screen.queryByTestId('rawViewer--dialog')).toBeFalsy();
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not display download tarball button', () => {
|
test('should not display download tarball button', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
|
||||||
expect(screen.queryByLabelText('Download tarball')).toBeFalsy();
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByLabelText('Download tarball')).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when click button to download ', async () => {
|
test('when click button to download ', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
|
||||||
fireEvent.click(screen.getByTestId('download-tarball-btn'));
|
fireEvent.click(screen.getByTestId('download-tarball-btn'));
|
||||||
await store.getState().loading.models.download;
|
await waitFor(() => {
|
||||||
|
expect(store.getState().loading.models.download).toBe(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should not display show raw button', () => {
|
test('should not display show raw button', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} showRaw={false} />, store);
|
||||||
expect(screen.queryByLabelText('action-bar-action.raw')).toBeFalsy();
|
await waitFor(() => {
|
||||||
|
expect(screen.queryByLabelText('action-bar-action.raw')).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('when there is a button to open an issue', () => {
|
test('when there is a button to open an issue', async () => {
|
||||||
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} />, store);
|
renderWithStore(<ActionBar packageMeta={defaultPackageMeta} />, store);
|
||||||
expect(screen.getByTestId('BugReportIcon')).toBeInTheDocument();
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('BugReportIcon')).toBeInTheDocument();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import { MemoryRouter } from 'react-router';
|
import { MemoryRouter } from 'react-router';
|
||||||
|
|
||||||
import { store } from '../../';
|
import { store } from '../../';
|
||||||
|
import { cleanupDownloadMocks, setupDownloadMocks } from '../../../vitest/vitestHelpers';
|
||||||
import {
|
import {
|
||||||
cleanup,
|
cleanup,
|
||||||
fireEvent,
|
fireEvent,
|
||||||
@@ -34,6 +35,14 @@ const props = {
|
|||||||
keywords: ['verdaccio-core'],
|
keywords: ['verdaccio-core'],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
setupDownloadMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
cleanupDownloadMocks();
|
||||||
|
});
|
||||||
|
|
||||||
describe('<Package /> component', () => {
|
describe('<Package /> component', () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ const Search: React.FC<RouteComponentProps> = ({ history }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderOption = (props, option) => {
|
const renderOption = (props, option) => {
|
||||||
|
const { key, ...otherProps } = props;
|
||||||
|
|
||||||
if (searchRemote) {
|
if (searchRemote) {
|
||||||
const item: SearchResultWeb = option.package;
|
const item: SearchResultWeb = option.package;
|
||||||
const isPrivate = option?.verdaccioPrivate;
|
const isPrivate = option?.verdaccioPrivate;
|
||||||
@@ -125,7 +127,8 @@ const Search: React.FC<RouteComponentProps> = ({ history }) => {
|
|||||||
const isRemote = !isCached && !isPrivate;
|
const isRemote = !isCached && !isPrivate;
|
||||||
return (
|
return (
|
||||||
<SearchItem
|
<SearchItem
|
||||||
{...props}
|
key={key}
|
||||||
|
{...otherProps}
|
||||||
description={item?.description}
|
description={item?.description}
|
||||||
isCached={isCached}
|
isCached={isCached}
|
||||||
isPrivate={isPrivate}
|
isPrivate={isPrivate}
|
||||||
@@ -137,7 +140,8 @@ const Search: React.FC<RouteComponentProps> = ({ history }) => {
|
|||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<SearchItem
|
<SearchItem
|
||||||
{...props}
|
key={key}
|
||||||
|
{...otherProps}
|
||||||
description={option?.description}
|
description={option?.description}
|
||||||
name={option?.name}
|
name={option?.name}
|
||||||
version={option?.version}
|
version={option?.version}
|
||||||
@@ -161,4 +165,4 @@ const Search: React.FC<RouteComponentProps> = ({ history }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withRouter(Search);
|
export default withRouter(Search as any);
|
||||||
|
|||||||
@@ -45,13 +45,29 @@ export function downloadFile(fileStream: Blob, fileName: string): void {
|
|||||||
fileLink.href = objectURL;
|
fileLink.href = objectURL;
|
||||||
fileLink.download = fileName;
|
fileLink.download = fileName;
|
||||||
|
|
||||||
// Without appending to an HTML Element, download dialog does not show up on Firefox
|
// Skip actual download in test environment to avoid JSDOM navigation error
|
||||||
// https://github.com/verdaccio/ui/issues/119
|
// Check if we're in a test environment (JSDOM)
|
||||||
document.documentElement.appendChild(fileLink);
|
const isTestEnvironment =
|
||||||
fileLink.click();
|
(typeof window !== 'undefined' &&
|
||||||
// firefox requires remove the object url
|
window.navigator &&
|
||||||
setTimeout(() => {
|
window.navigator.userAgent &&
|
||||||
URL.revokeObjectURL(objectURL);
|
window.navigator.userAgent.includes('Node.js')) ||
|
||||||
document.documentElement.removeChild(fileLink);
|
window.navigator.userAgent.includes('jsdom');
|
||||||
}, 150);
|
|
||||||
|
if (!isTestEnvironment) {
|
||||||
|
// Without appending to an HTML Element, download dialog does not show up on Firefox
|
||||||
|
// https://github.com/verdaccio/ui/issues/119
|
||||||
|
document.documentElement.appendChild(fileLink);
|
||||||
|
fileLink.click();
|
||||||
|
// firefox requires remove the object url
|
||||||
|
setTimeout(() => {
|
||||||
|
URL.revokeObjectURL(objectURL);
|
||||||
|
document.documentElement.removeChild(fileLink);
|
||||||
|
}, 150);
|
||||||
|
} else {
|
||||||
|
// In test environment, just clean up without triggering navigation
|
||||||
|
setTimeout(() => {
|
||||||
|
URL.revokeObjectURL(objectURL);
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"types": ["node", "jest", "@testing-library/jest-dom"]
|
"types": ["node", "jest", "@testing-library/jest-dom"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*", "vitest/**/*"],
|
"include": ["src/**/*", "vitest/**/*", "src/test/**/*"],
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "../core/types"
|
"path": "../core/types"
|
||||||
|
|||||||
34
packages/ui-components/vitest/vitestHelpers.ts
Normal file
34
packages/ui-components/vitest/vitestHelpers.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { vi } from 'vitest';
|
||||||
|
|
||||||
|
export const mockCreateObjectURL = vi.fn();
|
||||||
|
export const mockRevokeObjectURL = vi.fn();
|
||||||
|
|
||||||
|
let originalUserAgent: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up mocks for URL and navigator.userAgent to handle download functionality in tests
|
||||||
|
*/
|
||||||
|
export function setupDownloadMocks(): void {
|
||||||
|
originalUserAgent = window.navigator.userAgent;
|
||||||
|
|
||||||
|
URL.createObjectURL = mockCreateObjectURL;
|
||||||
|
URL.revokeObjectURL = mockRevokeObjectURL;
|
||||||
|
|
||||||
|
Object.defineProperty(window.navigator, 'userAgent', {
|
||||||
|
value: 'jsdom',
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up mocks for URL and navigator.userAgent
|
||||||
|
*/
|
||||||
|
export function cleanupDownloadMocks(): void {
|
||||||
|
mockCreateObjectURL.mockReset();
|
||||||
|
mockRevokeObjectURL.mockReset();
|
||||||
|
|
||||||
|
Object.defineProperty(window.navigator, 'userAgent', {
|
||||||
|
value: originalUserAgent,
|
||||||
|
configurable: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user