import { render, screen, waitFor } from '@testing-library/react'; import { DataSourceInstanceSettings, QueryEditorProps } from '@grafana/data'; import { DataQuery, DataSourceJsonData } from '@grafana/schema'; import { config } from '../config'; import { BackendSrv, BackendSrvRequest } from '../services'; import { DataSourceWithBackend } from '../utils/DataSourceWithBackend'; import { MigrationHandler } from '../utils/migrationHandler'; import { QueryEditorWithMigration } from './QueryEditorWithMigration'; const backendSrv = { post(url: string, data?: unknown, options?: Partial): Promise { return mockDatasourcePost({ url, data, ...options }); }, } as unknown as BackendSrv; jest.mock('../services', () => ({ ...jest.requireActual('../services'), getBackendSrv: () => backendSrv, })); let mockDatasourcePost = jest.fn(); interface MyQuery extends DataQuery {} class MyDataSource extends DataSourceWithBackend implements MigrationHandler { hasBackendMigration: boolean; constructor(instanceSettings: DataSourceInstanceSettings) { super(instanceSettings); this.hasBackendMigration = true; } shouldMigrate(query: DataQuery): boolean { return true; } } type Props = QueryEditorProps; function QueryEditor(props: Props) { return
{JSON.stringify(props.query)}
; } function createMockDatasource(otherSettings?: Partial>) { const settings = { name: 'test', id: 1234, uid: 'abc', type: 'dummy', jsonData: {}, ...otherSettings, } as DataSourceInstanceSettings; return new MyDataSource(settings); } describe('QueryEditorWithMigration', () => { const originalFeatureToggles = config.featureToggles; beforeEach(() => { config.featureToggles = { ...originalFeatureToggles, grafanaAPIServerWithExperimentalAPIs: true }; }); afterEach(() => { config.featureToggles = originalFeatureToggles; }); it('should migrate a query', async () => { const WithMigration = QueryEditorWithMigration(QueryEditor); const ds = createMockDatasource(); const originalQuery = { refId: 'A', datasource: { type: 'dummy' }, foo: 'bar' }; const migratedQuery = { refId: 'A', datasource: { type: 'dummy' }, foobar: 'barfoo' }; mockDatasourcePost = jest.fn().mockImplementation((args: { url: string; data: unknown }) => { expect(args.url).toBe('/apis/dummy.datasource.grafana.app/v0alpha1/namespaces/default/queryconvert'); expect(args.data).toMatchObject({ queries: [originalQuery] }); return Promise.resolve({ queries: [{ JSON: migratedQuery }] }); }); render(); await waitFor(() => { // Check that migratedQuery is rendered expect(screen.getByText(JSON.stringify(migratedQuery))).toBeInTheDocument(); }); }); it('should render a Skeleton while migrating', async () => { const WithMigration = QueryEditorWithMigration(QueryEditor); const ds = createMockDatasource(); const originalQuery = { refId: 'A', datasource: { type: 'dummy' }, foo: 'bar' }; mockDatasourcePost = jest.fn().mockImplementation(async (args: { url: string; data: unknown }) => { await waitFor(() => {}, { timeout: 5000 }); return Promise.resolve({ queries: [{ JSON: originalQuery }] }); }); render(); expect(screen.getByTestId('react-loading-skeleton-testid')).toBeInTheDocument(); }); });