Handle enterprise data source tab refreshes (#37567)

This commit is contained in:
Todd Treece 2021-09-14 09:24:18 -04:00 committed by GitHub
parent f5ecf5c2d9
commit 9b20a24989
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 93 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import {
InitDataSourceSettingDependencies,
testDataSource,
TestDataSourceDependencies,
getDataSourceUsingUidOrId,
} from './actions';
import { getMockPlugin, getMockPlugins } from '../../plugins/__mocks__/pluginMocks';
import { thunkTester } from 'test/core/thunk/thunkTester';
@ -17,6 +18,15 @@ import {
import { initDataSourceSettings } from '../state/actions';
import { ThunkResult, ThunkDispatch } from 'app/types';
import { GenericDataSourcePlugin } from '../settings/PluginSettings';
import { getBackendSrv } from 'app/core/services/backend_srv';
import { BackendSrvRequest, FetchResponse } from '@grafana/runtime';
import { of } from 'rxjs';
jest.mock('app/core/services/backend_srv');
jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as object),
getBackendSrv: jest.fn(),
}));
const getBackendSrvMock = () =>
({
@ -54,6 +64,79 @@ const failDataSourceTest = async (error: object) => {
return dispatchedActions;
};
describe('getDataSourceUsingUidOrId', () => {
const uidResponse = {
ok: true,
data: {
id: 111,
uid: 'abcdefg',
},
};
const idResponse = {
ok: true,
data: {
id: 222,
uid: 'xyz',
},
};
it('should return UID response data', async () => {
(getBackendSrv as jest.Mock).mockReturnValueOnce({
fetch: (options: BackendSrvRequest) => {
return of(uidResponse as FetchResponse);
},
});
expect(await getDataSourceUsingUidOrId('abcdefg')).toBe(uidResponse.data);
});
it('should return ID response data', async () => {
const uidResponse = {
ok: false,
};
(getBackendSrv as jest.Mock)
.mockReturnValueOnce({
fetch: (options: BackendSrvRequest) => {
return of(uidResponse as FetchResponse);
},
})
.mockReturnValueOnce({
fetch: (options: BackendSrvRequest) => {
return of(idResponse as FetchResponse);
},
});
expect(await getDataSourceUsingUidOrId(222)).toBe(idResponse.data);
});
it('should return empty response data', async () => {
// @ts-ignore
delete window.location;
window.location = {} as any;
const uidResponse = {
ok: false,
};
(getBackendSrv as jest.Mock)
.mockReturnValueOnce({
fetch: (options: BackendSrvRequest) => {
return of(uidResponse as FetchResponse);
},
})
.mockReturnValueOnce({
fetch: (options: BackendSrvRequest) => {
return of(idResponse as FetchResponse);
},
});
expect(await getDataSourceUsingUidOrId('222')).toStrictEqual({});
expect(window.location.href).toBe('/datasources/edit/xyz');
});
});
describe('Name exists', () => {
const plugins = getMockPlugins(5);

View File

@ -138,7 +138,7 @@ export function loadDataSource(uid: string): ThunkResult<void> {
/**
* Get data source by uid or id, if old id detected handles redirect
*/
async function getDataSourceUsingUidOrId(uid: string): Promise<DataSourceSettings> {
export async function getDataSourceUsingUidOrId(uid: string | number): Promise<DataSourceSettings> {
// Try first with uid api
try {
const byUid = await lastValueFrom(
@ -157,7 +157,7 @@ async function getDataSourceUsingUidOrId(uid: string): Promise<DataSourceSetting
}
// try lookup by old db id
const id = parseInt(uid, 10);
const id = typeof uid === 'string' ? parseInt(uid, 10) : uid;
if (!Number.isNaN(id)) {
const response = await lastValueFrom(
getBackendSrv().fetch<DataSourceSettings>({
@ -167,6 +167,12 @@ async function getDataSourceUsingUidOrId(uid: string): Promise<DataSourceSetting
})
);
// If the uid is a number, then this is a refresh on one of the settings tabs
// and we can return the response data
if (response.ok && typeof uid === 'number' && response.data.id === uid) {
return response.data;
}
// Not ideal to do a full page reload here but so tricky to handle this
// otherwise We can update the location using react router, but need to
// fully reload the route as the nav model page index is not matching with

View File

@ -69,9 +69,9 @@ export function buildNavModel(dataSource: DataSourceSettings, plugin: GenericDat
navModel.children!.push({
active: false,
icon: 'database',
id: `datasource-cache-${dataSource.id}`,
id: `datasource-cache-${dataSource.uid}`,
text: 'Cache',
url: `datasources/edit/${dataSource.id}/cache`,
url: `datasources/edit/${dataSource.uid}/cache`,
hideFromTabs: !pluginMeta.isBackend || !config.caching.enabled,
});
}