Plugins: All plugins are up to date message if now new updates available (#109175)
* add message for no updates abailable * add tests to PluginList
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { PluginSignatureStatus, PluginSignatureType, PluginType } from '@grafana/data';
|
||||
import { config } from '@grafana/runtime';
|
||||
|
||||
import { CatalogPlugin } from '../types';
|
||||
|
||||
import { PluginList } from './PluginList';
|
||||
|
||||
jest.mock('react-router-dom-v5-compat', () => ({ useLocation: jest.fn(), useSearchParams: jest.fn() }));
|
||||
|
||||
const mockUseLocation = jest.requireMock('react-router-dom-v5-compat').useLocation;
|
||||
const mockUseSearchParams = jest.requireMock('react-router-dom-v5-compat').useSearchParams;
|
||||
|
||||
const mockPlugin: CatalogPlugin = {
|
||||
description: 'Test plugin description',
|
||||
downloads: 1000,
|
||||
hasUpdate: false,
|
||||
id: 'test-plugin',
|
||||
info: { logos: { small: 'small-logo-url', large: 'large-logo-url' }, keywords: ['test', 'plugin'] },
|
||||
isDev: false,
|
||||
isCore: false,
|
||||
isEnterprise: false,
|
||||
isInstalled: true,
|
||||
isDisabled: false,
|
||||
isDeprecated: false,
|
||||
isManaged: false,
|
||||
isPreinstalled: { found: false, withVersion: false },
|
||||
isPublished: true,
|
||||
name: 'Test Plugin',
|
||||
orgName: 'Test Org',
|
||||
signature: PluginSignatureStatus.valid,
|
||||
signatureType: PluginSignatureType.grafana,
|
||||
signatureOrg: 'Test Signature Org',
|
||||
popularity: 4,
|
||||
publishedAt: '2023-01-01',
|
||||
type: PluginType.app,
|
||||
updatedAt: '2023-12-01',
|
||||
installedVersion: '1.0.0',
|
||||
angularDetected: false,
|
||||
isFullyInstalled: true,
|
||||
accessControl: {},
|
||||
};
|
||||
|
||||
const mockPlugin2: CatalogPlugin = {
|
||||
...mockPlugin,
|
||||
id: 'test-plugin-2',
|
||||
name: 'Test Plugin 2',
|
||||
type: PluginType.datasource,
|
||||
};
|
||||
|
||||
describe('PluginList', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockUseLocation.mockReturnValue({ pathname: '/plugins' });
|
||||
mockUseSearchParams.mockReturnValue([new URLSearchParams(), jest.fn()]);
|
||||
config.appSubUrl = '';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should render plugins when not loading and plugins exist', () => {
|
||||
const plugins = [mockPlugin, mockPlugin2];
|
||||
render(<PluginList plugins={plugins} isLoading={false} />);
|
||||
|
||||
expect(screen.getByTestId('plugin-list')).toBeInTheDocument();
|
||||
expect(screen.getByText('Test Plugin')).toBeInTheDocument();
|
||||
expect(screen.getByText('Test Plugin 2')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show "All plugins are up to date" message when filterBy=has-update and no plugins', () => {
|
||||
mockUseSearchParams.mockReturnValue([new URLSearchParams('filterBy=has-update'), jest.fn()]);
|
||||
|
||||
render(<PluginList plugins={[]} isLoading={false} />);
|
||||
|
||||
expect(screen.getByText('All plugins are up to date')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show "No plugins found" message when filterBy=all and not loading', () => {
|
||||
mockUseSearchParams.mockReturnValue([new URLSearchParams('filterBy=all'), jest.fn()]);
|
||||
|
||||
render(<PluginList plugins={[]} isLoading={false} />);
|
||||
|
||||
expect(screen.getByText('No plugins found')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should not show empty state when filterBy=has-update but plugins exist', () => {
|
||||
mockUseSearchParams.mockReturnValue([new URLSearchParams('filterBy=has-update'), jest.fn()]);
|
||||
|
||||
render(<PluginList plugins={[mockPlugin]} isLoading={false} />);
|
||||
|
||||
expect(screen.queryByText('All plugins are up to date')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Test Plugin')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useLocation } from 'react-router-dom-v5-compat';
|
||||
import { useLocation, useSearchParams } from 'react-router-dom-v5-compat';
|
||||
|
||||
import { t } from '@grafana/i18n';
|
||||
import { config } from '@grafana/runtime';
|
||||
@@ -15,9 +15,18 @@ interface Props {
|
||||
|
||||
export const PluginList = ({ plugins, isLoading }: Props) => {
|
||||
const { pathname } = useLocation();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const pathName = config.appSubUrl + (pathname.endsWith('/') ? pathname.slice(0, -1) : pathname);
|
||||
|
||||
if (searchParams.get('filterBy') === 'has-update' && !isLoading && plugins.length === 0) {
|
||||
return (
|
||||
<EmptyState
|
||||
variant="not-found"
|
||||
message={t('plugins.no-updates-available.message', 'All plugins are up to date')}
|
||||
/>
|
||||
);
|
||||
}
|
||||
if (!isLoading && plugins.length === 0) {
|
||||
return <EmptyState variant="not-found" message={t('plugins.empty-state.message', 'No plugins found')} />;
|
||||
}
|
||||
|
||||
@@ -10941,6 +10941,9 @@
|
||||
"label-plugin-id": "Plugin Id",
|
||||
"label-severity": "Severity"
|
||||
},
|
||||
"no-updates-available": {
|
||||
"message": "All plugins are up to date"
|
||||
},
|
||||
"not-found-plugin": {
|
||||
"body-plugin-not-found": "That plugin cannot be found. Please check the url is correct or <1></1>go to the <3>plugin catalog</3>.",
|
||||
"title-plugin-not-found": "Plugin not found"
|
||||
|
||||
Reference in New Issue
Block a user