import { render, screen } from 'test/test-utils'; import { PluginSignatureStatus, PluginSignatureType, PluginType } from '@grafana/data'; import { config } from '@grafana/runtime'; import { CatalogPlugin } from '../types'; import { PluginDetailsPage } from './PluginDetailsPage'; const plugin: 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', details: { readme: 'Test readme', versions: [ { version: '1.0.0', createdAt: '2023-01-01', isCompatible: true, grafanaDependency: '>=9.0.0', angularDetected: false, }, ], links: [ { name: 'Website', url: 'https://test-plugin.com', }, ], grafanaDependency: '>=9.0.0', statusContext: 'stable', changelog: 'Test changelog', }, angularDetected: false, isFullyInstalled: true, accessControl: {}, }; jest.mock('../state/hooks', () => ({ useGetSingle: jest.fn(), useFetchStatus: jest.fn().mockReturnValue({ isLoading: false }), useFetchDetailsStatus: () => ({ isLoading: false }), useIsRemotePluginsAvailable: () => false, useInstallStatus: () => ({ error: null, isInstalling: false }), useUninstallStatus: () => ({ error: null, isUninstalling: false }), useInstall: () => jest.fn(), useUninstall: () => jest.fn(), useUnsetInstall: () => jest.fn(), useFetchDetailsLazy: () => jest.fn(), })); jest.mock('../hooks/usePluginConfig', () => ({ usePluginConfig: jest.fn().mockReturnValue({ value: {}, loading: false }), })); const mockUseGetSingle = jest.requireMock('../state/hooks').useGetSingle; const mockUsePluginConfig = jest.requireMock('../hooks/usePluginConfig').usePluginConfig; describe('PluginDetailsPage', () => { beforeEach(() => { jest.spyOn(console, 'error').mockImplementation(); mockUseGetSingle.mockReturnValue(plugin); }); afterEach(() => { jest.clearAllMocks(); }); it('should show loader when fetching plugin details', () => { jest.requireMock('../state/hooks').useFetchStatus.mockReturnValueOnce({ isLoading: true }); render(); expect(screen.getByText('Loading...')).toBeInTheDocument(); }); it('should show not found component when plugin doesnt exist', () => { mockUseGetSingle.mockReturnValue(undefined); render(); expect(screen.getByText('Plugin not found')).toBeInTheDocument(); }); it('should show right panel when screen is wide', () => { window.matchMedia = jest.fn().mockImplementation((query) => ({ matches: query !== '(max-width: 600px)', media: query, onchange: null, addEventListener: jest.fn(), removeEventListener: jest.fn(), dispatchEvent: jest.fn(), })); render(); expect(screen.getByTestId('plugin-details-panel')).toBeInTheDocument(); }); it('should show "Plugin details" tab when screen is narrow', () => { window.matchMedia = jest.fn().mockImplementation((query) => ({ matches: query === '(max-width: 600px)', media: query, onchange: null, addEventListener: jest.fn(), removeEventListener: jest.fn(), dispatchEvent: jest.fn(), })); render(); expect(screen.getByRole('tab', { name: 'Plugin details' })).toBeInTheDocument(); }); it('should show "Datasource connections" tab when plugin is type of datasource', () => { config.featureToggles.datasourceConnectionsTab = true; mockUseGetSingle.mockReturnValue({ ...plugin, type: PluginType.datasource }); mockUsePluginConfig.mockReturnValue({ value: {}, loading: false }); render(); expect(screen.getByRole('tab', { name: 'Data source connections' })).toBeVisible(); }); it('should not show version and changelog tabs when plugin is core', () => { mockUseGetSingle.mockReturnValue({ ...plugin, isCore: true }); render(); expect(screen.queryByRole('tab', { name: 'Version history' })).not.toBeInTheDocument(); expect(screen.queryByRole('tab', { name: 'Changelog' })).not.toBeInTheDocument(); }); it('should not show last version in plugin details panel when plugin is core', () => { window.matchMedia = jest.fn().mockImplementation((query) => ({ matches: query !== '(max-width: 600px)', media: query, onchange: null, addEventListener: jest.fn(), removeEventListener: jest.fn(), dispatchEvent: jest.fn(), })); mockUseGetSingle.mockReturnValue({ ...plugin, isCore: true, latestVersion: '1.2.0' }); render(); expect(screen.queryByText('Latest Version:')).not.toBeInTheDocument(); }); });