superset/superset-frontend/packages/superset-ui-core/test/chart/clients/ChartClient.test.ts

314 lines
8.7 KiB
TypeScript
Raw Normal View History

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import fetchMock from 'fetch-mock';
import {
SupersetClientClass,
SupersetClient,
buildQueryContext,
QueryFormData,
configure as configureTranslation,
ChartClient,
getChartBuildQueryRegistry,
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
getChartMetadataRegistry,
ChartMetadata,
} from '@superset-ui/core';
import { LOGIN_GLOB } from '../fixtures/constants';
import { sankeyFormData } from '../fixtures/formData';
import { SliceIdAndOrFormData } from '../../../src/chart/clients/ChartClient';
configureTranslation();
describe('ChartClient', () => {
let chartClient: ChartClient;
beforeAll(() => {
fetchMock.get(LOGIN_GLOB, { result: '1234' });
SupersetClient.reset();
SupersetClient.configure().init();
});
beforeEach(() => {
chartClient = new ChartClient();
});
afterEach(fetchMock.restore);
describe('new ChartClient(config)', () => {
it('creates a client without argument', () => {
expect(chartClient).toBeInstanceOf(ChartClient);
});
it('creates a client with specified config.client', () => {
const customClient = new SupersetClientClass();
chartClient = new ChartClient({ client: customClient });
expect(chartClient).toBeInstanceOf(ChartClient);
expect(chartClient.client).toBe(customClient);
});
});
describe('.loadFormData({ sliceId, formData }, options)', () => {
const sliceId = 123;
it('fetches formData if given only sliceId', () => {
fetchMock.get(
`glob:*/api/v1/form_data/?slice_id=${sliceId}`,
sankeyFormData,
);
return expect(chartClient.loadFormData({ sliceId })).resolves.toEqual(
sankeyFormData,
);
});
it('fetches formData from sliceId and merges with specify formData if both fields are specified', () => {
fetchMock.get(
`glob:*/api/v1/form_data/?slice_id=${sliceId}`,
sankeyFormData,
);
return expect(
chartClient.loadFormData({
sliceId,
formData: {
granularity: 'second',
viz_type: 'bar',
},
}),
).resolves.toEqual({
...sankeyFormData,
granularity: 'second',
viz_type: 'bar',
});
});
it('returns promise of formData if only formData was given', () =>
expect(
chartClient.loadFormData({
formData: {
datasource: '1__table',
granularity: 'minute',
viz_type: 'line',
},
}),
).resolves.toEqual({
datasource: '1__table',
granularity: 'minute',
viz_type: 'line',
}));
it('rejects if none of sliceId or formData is specified', () =>
expect(
chartClient.loadFormData({} as SliceIdAndOrFormData),
).rejects.toEqual(
new Error('At least one of sliceId or formData must be specified'),
));
});
describe('.loadQueryData(formData, options)', () => {
it('returns a promise of query data for known chart type', () => {
getChartMetadataRegistry().registerValue(
'word_cloud',
new ChartMetadata({ name: 'Word Cloud', thumbnail: '' }),
);
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
getChartBuildQueryRegistry().registerValue(
'word_cloud',
(formData: QueryFormData) => buildQueryContext(formData),
);
fetchMock.post('glob:*/api/v1/chart/data', [
{
field1: 'abc',
field2: 'def',
},
]);
return expect(
chartClient.loadQueryData({
granularity: 'minute',
viz_type: 'word_cloud',
datasource: '1__table',
}),
).resolves.toEqual([
{
field1: 'abc',
field2: 'def',
},
]);
});
it('returns a promise that rejects for unknown chart type', () =>
expect(
chartClient.loadQueryData({
granularity: 'minute',
viz_type: 'rainbow_3d_pie',
datasource: '1__table',
}),
).rejects.toEqual(new Error('Unknown chart type: rainbow_3d_pie')));
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
it('fetches data from the legacy API if ChartMetadata has useLegacyApi=true,', () => {
// note legacy charts do not register a buildQuery function in the registry
getChartMetadataRegistry().registerValue(
'word_cloud_legacy',
new ChartMetadata({
name: 'Legacy Word Cloud',
thumbnail: '.png',
useLegacyApi: true,
}),
);
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
fetchMock.post('glob:*/api/v1/chart/data', () =>
Promise.reject(new Error('Unexpected all to v1 API')),
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
);
fetchMock.post('glob:*/superset/explore_json/', {
field1: 'abc',
field2: 'def',
});
return expect(
chartClient.loadQueryData({
granularity: 'minute',
viz_type: 'word_cloud_legacy',
datasource: '1__table',
}),
).resolves.toEqual([
{
field1: 'abc',
field2: 'def',
},
]);
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
});
});
describe('.loadDatasource(datasourceKey, options)', () => {
it('fetches datasource', () => {
fetchMock.get(
'glob:*/superset/fetch_datasource_metadata?datasourceKey=1__table',
{
field1: 'abc',
field2: 'def',
},
);
2019-07-27 19:21:57 -04:00
return expect(chartClient.loadDatasource('1__table')).resolves.toEqual({
field1: 'abc',
field2: 'def',
});
});
});
describe('.loadAnnotation(annotationLayer)', () => {
it('returns an empty object if the annotation layer does not require query', () =>
expect(
chartClient.loadAnnotation({
name: 'my-annotation',
}),
).resolves.toEqual({}));
it('otherwise returns a rejected promise because it is not implemented yet', () =>
expect(
chartClient.loadAnnotation({
name: 'my-annotation',
sourceType: 'abc',
}),
).rejects.toEqual(new Error('This feature is not implemented yet.')));
});
describe('.loadAnnotations(annotationLayers)', () => {
it('loads multiple annotation layers and combine results', () =>
expect(
chartClient.loadAnnotations([
{
name: 'anno1',
},
{
name: 'anno2',
},
{
name: 'anno3',
},
]),
).resolves.toEqual({
anno1: {},
anno2: {},
anno3: {},
}));
it('returns an empty object if input is not an array', () =>
expect(chartClient.loadAnnotations()).resolves.toEqual({}));
it('returns an empty object if input is an empty array', () =>
expect(chartClient.loadAnnotations()).resolves.toEqual({}));
});
describe('.loadChartData({ sliceId, formData })', () => {
const sliceId = 10120;
it('loadAllDataNecessaryForAChart', () => {
fetchMock.get(`glob:*/api/v1/form_data/?slice_id=${sliceId}`, {
granularity: 'minute',
viz_type: 'line',
datasource: '1__table',
color: 'living-coral',
});
fetchMock.get(
'glob:*/superset/fetch_datasource_metadata?datasourceKey=1__table',
{
name: 'transactions',
schema: 'staging',
},
);
fetchMock.post('glob:*/api/v1/chart/data', {
lorem: 'ipsum',
dolor: 'sit',
amet: true,
});
getChartMetadataRegistry().registerValue(
'line',
new ChartMetadata({ name: 'Line', thumbnail: '.gif' }),
);
feat(chart): Add `<ChartDataProvider />` (#120) * docs: [demo][connection] add ConfigureCORS story for testing CORS * docs: [demo][ConfigureCORS] better instructions * feat: [chart] add mvp DataProvider component * docs: better CORS story, update webpack for @babel/polyfill * docs: [chart] add DataProvider story with WordCloudPlugin * docs: [chart] add DataProvider deets to Readme * test(chart): move SuperChart.test.jsx => .tsx and instead use @ts-ignore * fix(connection): point interface.request to client.request * feat(chart): re-write DataProvider as ChartDataProvider * docs(demo): re-write LegacyWordCloudStories => ChartDataProviderStories * refactor(chart): use IDENTITY as ChartPlugin buildQuery default * feat(chart): support legacy + v1 loadQueryData endpoints in ChartClient * docs(demo): add sankey + sunburst plugins to ChartDataProvider story * style(chart): run prettier on SuperChart * feat(chart): export QueryData type from models/ChartProps * feat(chart): export Metrics and BaseFormData from types/ChartFormData * feat(chart): add request option overrides in ChartDataProvider * fix(chart): use Partial<> for ChartClient request option overrides * test(chart): add ChartDataProvider tests * build: include demo pkg in type script * build: move storybook/mocks to test/fixtures * build: move json-bigint TS declaration to root * test(chart): clean up ChartDataProvider test TS * chore(chart): lint fix SuperChart * fix(chart): set ChartPlugin.buildQuery default back to undefined * test(connection): fix expected Client.get call count * test(chart): fix ChartClient tests and add test for legacy API * fix(chart): uninitialized typo, change fetching => loading * docs(chart): update README to final ChartDataProvider API * docs(chart): fix typo * test(chart): get ChartDataProvider to one hundo * feat(chart): add and export more meaningful Datasource type * feat(chart): use Datasource type in ChartClient
2019-03-19 17:58:20 -04:00
getChartBuildQueryRegistry().registerValue(
'line',
(formData: QueryFormData) => buildQueryContext(formData),
);
return expect(
chartClient.loadChartData({
sliceId,
}),
).resolves.toEqual({
annotationData: {},
datasource: {
name: 'transactions',
schema: 'staging',
},
formData: {
granularity: 'minute',
viz_type: 'line',
datasource: '1__table',
color: 'living-coral',
},
queriesData: [
{
lorem: 'ipsum',
dolor: 'sit',
amet: true,
},
],
});
});
});
});