mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
build(dev-deps): upgrade Jest to major version v30 (#33979)
This commit is contained in:
4
.github/dependabot.yml
vendored
4
.github/dependabot.yml
vendored
@@ -12,6 +12,10 @@ updates:
|
||||
# not until React >= 18.0.0
|
||||
- dependency-name: "storybook"
|
||||
- dependency-name: "@storybook*"
|
||||
# JSDOM v30 doesn't play well with Jest v30
|
||||
# Source: https://jestjs.io/blog#known-issues
|
||||
# GH thread: https://github.com/jsdom/jsdom/issues/3492
|
||||
- dependency-name: "jest-environment-jsdom"
|
||||
directory: "/superset-frontend/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
|
||||
@@ -86,9 +86,7 @@ module.exports = {
|
||||
],
|
||||
parser: '@babel/eslint-parser',
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
experimentalObjectRestSpread: true,
|
||||
},
|
||||
ecmaVersion: 2018,
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
@@ -127,6 +125,11 @@ module.exports = {
|
||||
'react-prefer-function-component',
|
||||
'prettier',
|
||||
],
|
||||
// Add this TS ESlint rule in separate `rules` section to avoid breakages with JS/TS files in /cypress-base.
|
||||
// TODO(hainenber): merge it to below `rules` section.
|
||||
rules: {
|
||||
'@typescript-eslint/prefer-optional-chain': 'error',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
@@ -160,7 +163,7 @@ module.exports = {
|
||||
'@typescript-eslint/no-non-null-assertion': 0, // disabled temporarily
|
||||
'@typescript-eslint/explicit-function-return-type': 0,
|
||||
'@typescript-eslint/explicit-module-boundary-types': 0, // re-enable up for discussion
|
||||
'@typescript-eslint/prefer-optional-chain': 2,
|
||||
'@typescript-eslint/no-unused-vars': 'warn', // downgrade to Warning severity for Jest v30 upgrade
|
||||
camelcase: 0,
|
||||
'class-methods-use-this': 0,
|
||||
'func-names': 0,
|
||||
@@ -395,6 +398,7 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
],
|
||||
// eslint-disable-next-line no-dupe-keys
|
||||
rules: {
|
||||
'theme-colors/no-literal-colors': 'error',
|
||||
'icons/no-fa-icons-usage': 'error',
|
||||
|
||||
@@ -21,30 +21,21 @@ import qs from 'querystring';
|
||||
import {
|
||||
dashboardView,
|
||||
nativeFilters,
|
||||
exploreView,
|
||||
dataTestChartName,
|
||||
} from 'cypress/support/directories';
|
||||
|
||||
import {
|
||||
addCountryNameFilter,
|
||||
addParentFilterWithValue,
|
||||
applyAdvancedTimeRangeFilterOnDashboard,
|
||||
applyNativeFilterValueWithIndex,
|
||||
cancelNativeFilterSettings,
|
||||
checkNativeFilterTooltip,
|
||||
clickOnAddFilterInModal,
|
||||
collapseFilterOnLeftPanel,
|
||||
deleteNativeFilter,
|
||||
enterNativeFilterEditModal,
|
||||
expandFilterOnLeftPanel,
|
||||
fillNativeFilterForm,
|
||||
getNativeFilterPlaceholderWithIndex,
|
||||
inputNativeFilterDefaultValue,
|
||||
saveNativeFilterSettings,
|
||||
nativeFilterTooltips,
|
||||
undoDeleteNativeFilter,
|
||||
validateFilterContentOnDashboard,
|
||||
valueNativeFilterOptions,
|
||||
validateFilterNameOnDashboard,
|
||||
testItems,
|
||||
WORLD_HEALTH_CHARTS,
|
||||
@@ -55,19 +46,19 @@ import {
|
||||
visitDashboard,
|
||||
} from './shared_dashboard_functions';
|
||||
|
||||
function selectFilter(index: number) {
|
||||
cy.get("[data-test='filter-title-container'] [draggable='true']")
|
||||
.eq(index)
|
||||
.click();
|
||||
}
|
||||
// function selectFilter(index: number) {
|
||||
// cy.get("[data-test='filter-title-container'] [draggable='true']")
|
||||
// .eq(index)
|
||||
// .click();
|
||||
// }
|
||||
|
||||
function closeFilterModal() {
|
||||
cy.get('body').then($body => {
|
||||
if ($body.find('[data-test="native-filter-modal-cancel-button"]').length) {
|
||||
cy.getBySel('native-filter-modal-cancel-button').click();
|
||||
}
|
||||
});
|
||||
}
|
||||
// function closeFilterModal() {
|
||||
// cy.get('body').then($body => {
|
||||
// if ($body.find('[data-test="native-filter-modal-cancel-button"]').length) {
|
||||
// cy.getBySel('native-filter-modal-cancel-button').click();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
describe('Native filters', () => {
|
||||
describe('Nativefilters initial state not required', () => {
|
||||
|
||||
@@ -16,37 +16,29 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import qs from 'querystring';
|
||||
import {
|
||||
dashboardView,
|
||||
nativeFilters,
|
||||
exploreView,
|
||||
dataTestChartName,
|
||||
} from 'cypress/support/directories';
|
||||
|
||||
import {
|
||||
addCountryNameFilter,
|
||||
addParentFilterWithValue,
|
||||
applyAdvancedTimeRangeFilterOnDashboard,
|
||||
applyNativeFilterValueWithIndex,
|
||||
cancelNativeFilterSettings,
|
||||
checkNativeFilterTooltip,
|
||||
clickOnAddFilterInModal,
|
||||
collapseFilterOnLeftPanel,
|
||||
deleteNativeFilter,
|
||||
enterNativeFilterEditModal,
|
||||
expandFilterOnLeftPanel,
|
||||
fillNativeFilterForm,
|
||||
getNativeFilterPlaceholderWithIndex,
|
||||
inputNativeFilterDefaultValue,
|
||||
saveNativeFilterSettings,
|
||||
nativeFilterTooltips,
|
||||
undoDeleteNativeFilter,
|
||||
validateFilterContentOnDashboard,
|
||||
valueNativeFilterOptions,
|
||||
validateFilterNameOnDashboard,
|
||||
testItems,
|
||||
WORLD_HEALTH_CHARTS,
|
||||
} from './utils';
|
||||
import {
|
||||
prepareDashboardFilters,
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
*/
|
||||
import '@cypress/code-coverage/support';
|
||||
import '@applitools/eyes-cypress/commands';
|
||||
import failOnConsoleError from 'cypress-fail-on-console-error';
|
||||
import { expect } from 'chai';
|
||||
import rison from 'rison';
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"allowJs": true,
|
||||
"noEmit": true
|
||||
},
|
||||
"files": ["cypress/support/index.d.ts", "./node_modules/@applitools/eyes-cypress/eyes-index.d.ts"],
|
||||
"files": ["cypress/support/index.d.ts", "./node_modules/@applitools/eyes-cypress/types/index.d.ts"],
|
||||
"include": ["cypress/**/*.ts", "./cypress.config.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ module.exports = {
|
||||
setupFilesAfterEnv: ['<rootDir>/spec/helpers/setup.ts'],
|
||||
snapshotSerializers: ['@emotion/jest/serializer'],
|
||||
testEnvironmentOptions: {
|
||||
globalsCleanup: true,
|
||||
url: 'http://localhost',
|
||||
},
|
||||
collectCoverageFrom: [
|
||||
|
||||
5221
superset-frontend/package-lock.json
generated
5221
superset-frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -164,7 +164,6 @@
|
||||
"ol": "^7.5.2",
|
||||
"polished": "^4.3.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"rc-trigger": "^5.3.4",
|
||||
"re-resizable": "^6.10.1",
|
||||
"react": "^17.0.2",
|
||||
"react-checkbox-tree": "^1.8.0",
|
||||
@@ -258,7 +257,6 @@
|
||||
"@types/node": "^22.12.0",
|
||||
"@types/react": "^17.0.83",
|
||||
"@types/react-dom": "^17.0.26",
|
||||
"@types/react-gravatar": "^2.6.14",
|
||||
"@types/react-json-tree": "^0.6.11",
|
||||
"@types/react-loadable": "^5.5.11",
|
||||
"@types/react-redux": "^7.1.10",
|
||||
@@ -275,17 +273,16 @@
|
||||
"@types/sinon": "^17.0.3",
|
||||
"@types/testing-library__jest-dom": "^5.14.9",
|
||||
"@types/tinycolor2": "^1.4.3",
|
||||
"@types/yargs": "12 - 18",
|
||||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.62.0",
|
||||
"babel-jest": "^29.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
||||
"@typescript-eslint/parser": "^7.18.0",
|
||||
"babel-jest": "^30.0.2",
|
||||
"babel-loader": "^10.0.0",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.3",
|
||||
"babel-plugin-jsx-remove-data-test-id": "^3.0.0",
|
||||
"babel-plugin-lodash": "^3.3.4",
|
||||
"babel-plugin-typescript-to-proptypes": "^2.0.0",
|
||||
"cheerio": "1.0.0-rc.10",
|
||||
"copy-webpack-plugin": "^12.0.2",
|
||||
"copy-webpack-plugin": "^13.0.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^7.1.2",
|
||||
"css-minimizer-webpack-plugin": "^7.0.2",
|
||||
@@ -315,9 +312,9 @@
|
||||
"history": "^5.3.0",
|
||||
"html-webpack-plugin": "^5.6.3",
|
||||
"imports-loader": "^5.0.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest": "^30.0.2",
|
||||
"jest-environment-jsdom": "^29.7.0",
|
||||
"jest-html-reporter": "^3.10.2",
|
||||
"jest-html-reporter": "^4.3.0",
|
||||
"jest-websocket-mock": "^2.5.0",
|
||||
"jsdom": "^26.0.0",
|
||||
"lerna": "^8.2.1",
|
||||
@@ -336,11 +333,11 @@
|
||||
"storybook": "8.1.11",
|
||||
"style-loader": "^4.0.0",
|
||||
"thread-loader": "^4.0.4",
|
||||
"ts-jest": "^29.2.5",
|
||||
"ts-jest": "^29.4.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"tscw-config": "^1.1.2",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "5.1.6",
|
||||
"typescript": "5.4.5",
|
||||
"vm-browserify": "^1.1.2",
|
||||
"webpack": "^5.98.0",
|
||||
"webpack-bundle-analyzer": "^4.10.1",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.3",
|
||||
"fs-extra": "^11.2.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest": "^30.0.2",
|
||||
"yeoman-test": "^8.3.0"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -27,10 +27,9 @@ import {
|
||||
import { PostProcessingFactory } from './types';
|
||||
import { extractExtraMetrics } from './utils';
|
||||
|
||||
export const sortOperator: PostProcessingFactory<PostProcessingSort> = (
|
||||
formData,
|
||||
queryObject,
|
||||
) => {
|
||||
export const sortOperator: PostProcessingFactory<
|
||||
PostProcessingSort
|
||||
> = formData => {
|
||||
// the sortOperator only used in the barchart v2
|
||||
const sortableLabels = [
|
||||
getXAxisLabel(formData),
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// /superset/sqllab_viz
|
||||
interface SqlLabPostRequest {
|
||||
data: {
|
||||
schema: string;
|
||||
sql: string;
|
||||
dbId: number;
|
||||
templateParams?: string | undefined;
|
||||
datasourceName: string;
|
||||
metrics?: string[];
|
||||
columns?: string[];
|
||||
};
|
||||
}
|
||||
@@ -27,6 +27,8 @@ import getLabelsColorMap, {
|
||||
import { getAnalogousColors } from './utils';
|
||||
import { FeatureFlag, isFeatureEnabled } from '../utils';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
||||
|
||||
// Use type augmentation to correct the fact that
|
||||
// an instance of CategoricalScale is also a function
|
||||
interface CategoricalColorScale {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* under the License.
|
||||
*/
|
||||
import { StoryObj } from '@storybook/react';
|
||||
import { noop } from 'lodash';
|
||||
import { SelectOptionsType, SelectProps } from './types';
|
||||
import { Select } from '.';
|
||||
|
||||
@@ -93,23 +94,26 @@ export const InteractiveSelect: StoryObj = {
|
||||
options,
|
||||
optionsCount,
|
||||
...args
|
||||
}: SelectProps & { header: string; optionsCount: number }) => (
|
||||
<div
|
||||
style={{
|
||||
width: DEFAULT_WIDTH,
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
{...args}
|
||||
options={
|
||||
Array.isArray(options)
|
||||
? generateOptions(options, optionsCount)
|
||||
: options
|
||||
}
|
||||
mode="multiple"
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
}: SelectProps & { header: string; optionsCount: number }) => {
|
||||
noop(header);
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: DEFAULT_WIDTH,
|
||||
}}
|
||||
>
|
||||
<Select
|
||||
{...args}
|
||||
options={
|
||||
Array.isArray(options)
|
||||
? generateOptions(options, optionsCount)
|
||||
: options
|
||||
}
|
||||
mode="multiple"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
args: {
|
||||
autoFocus: true,
|
||||
allowNewOptions: false,
|
||||
|
||||
@@ -21,6 +21,8 @@ import { ExtensibleFunction } from '../models';
|
||||
import { getNumberFormatter, NumberFormats } from '../number-format';
|
||||
import { Currency } from '../query';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
||||
|
||||
interface CurrencyFormatterConfig {
|
||||
d3Format?: string;
|
||||
currency: Currency;
|
||||
|
||||
@@ -20,6 +20,8 @@ import { ExtensibleFunction } from '../models';
|
||||
import { isRequired } from '../utils';
|
||||
import { NumberFormatFunction } from './types';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
||||
|
||||
export const PREVIEW_VALUE = 12345.432;
|
||||
|
||||
export interface NumberFormatterConfig {
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
CacheProvider as EmotionCacheProvider,
|
||||
} from '@emotion/react';
|
||||
import createCache from '@emotion/cache';
|
||||
import { noop } from 'lodash';
|
||||
import { GlobalStyles } from './GlobalStyles';
|
||||
|
||||
import {
|
||||
@@ -285,6 +286,7 @@ export class Theme {
|
||||
antdConfig: AntdThemeConfig,
|
||||
emotionCache: any,
|
||||
): void {
|
||||
noop(theme, antdConfig, emotionCache);
|
||||
// Overridden at runtime by SupersetThemeProvider using setThemeState
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ import { isRequired } from '../utils';
|
||||
import { TimeFormatFunction } from './types';
|
||||
import stringifyTimeInput from './utils/stringifyTimeInput';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
||||
|
||||
export const PREVIEW_TIME = new Date(Date.UTC(2017, 1, 14, 11, 22, 33));
|
||||
|
||||
// Use type augmentation to indicate that
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
import { ExtensibleFunction } from '../models';
|
||||
import { TimeRangeFormatFunction } from './types';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
||||
|
||||
// Use type augmentation to indicate that
|
||||
// an instance of TimeFormatter is also a function
|
||||
interface TimeRangeFormatter {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
||||
|
||||
import { ExtensibleFunction } from '@superset-ui/core';
|
||||
|
||||
describe('ExtensibleFunction', () => {
|
||||
|
||||
@@ -28,9 +28,7 @@ const colorTypes = [
|
||||
'grayscale',
|
||||
];
|
||||
|
||||
const AntDFunctionalColors = ({ antdTheme }) => {
|
||||
const { antd } = supersetTheme;
|
||||
|
||||
const AntDFunctionalColors = () => {
|
||||
// Define color types and variants dynamically
|
||||
const variants = [
|
||||
'active',
|
||||
@@ -44,7 +42,6 @@ const AntDFunctionalColors = ({ antdTheme }) => {
|
||||
'bg',
|
||||
];
|
||||
|
||||
const { colors } = supersetTheme;
|
||||
return (
|
||||
<table
|
||||
style={{ borderCollapse: 'collapse', width: '100%', textAlign: 'left' }}
|
||||
@@ -63,32 +60,29 @@ const AntDFunctionalColors = ({ antdTheme }) => {
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{colorTypes.map(type => {
|
||||
const typeKey = `color${type}`;
|
||||
return (
|
||||
<tr key={type}>
|
||||
<td style={{ border: '1px solid #ddd', padding: '8px' }}>
|
||||
<strong>{type}</strong>
|
||||
</td>
|
||||
{variants.map(variant => {
|
||||
const color = themeObject.getColorVariants(type)[variant];
|
||||
return (
|
||||
<td
|
||||
key={variant}
|
||||
style={{
|
||||
border: '1px solid #ddd',
|
||||
padding: '8px',
|
||||
backgroundColor: color || 'transparent',
|
||||
color: [`color${type}${variant}`],
|
||||
}}
|
||||
>
|
||||
{color ? <code>{color}</code> : '-'}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
{colorTypes.map(type => (
|
||||
<tr key={type}>
|
||||
<td style={{ border: '1px solid #ddd', padding: '8px' }}>
|
||||
<strong>{type}</strong>
|
||||
</td>
|
||||
{variants.map(variant => {
|
||||
const color = themeObject.getColorVariants(type)[variant];
|
||||
return (
|
||||
<td
|
||||
key={variant}
|
||||
style={{
|
||||
border: '1px solid #ddd',
|
||||
padding: '8px',
|
||||
backgroundColor: color || 'transparent',
|
||||
color: `color${type}${variant}`,
|
||||
}}
|
||||
>
|
||||
{color ? <code>{color}</code> : '-'}
|
||||
</td>
|
||||
);
|
||||
})}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
);
|
||||
@@ -159,7 +153,7 @@ export const ThemeColors = () => {
|
||||
</table>
|
||||
<h2>Ant Design Theme Colors</h2>
|
||||
<h3>Functional Colors</h3>
|
||||
<AntDFunctionalColors antdTheme={supersetTheme.antd} />
|
||||
<AntDFunctionalColors />
|
||||
<h2>The supersetTheme object</h2>
|
||||
<pre>
|
||||
<code>{JSON.stringify(supersetTheme, null, 2)}</code>
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
sharedControls,
|
||||
sections,
|
||||
} from '@superset-ui/chart-controls';
|
||||
import { noop } from 'lodash';
|
||||
import {
|
||||
headerFontSize,
|
||||
subheaderFontSize,
|
||||
@@ -143,6 +144,7 @@ const config: ControlPanelConfig = {
|
||||
return true;
|
||||
},
|
||||
mapStateToProps(explore, _, chart) {
|
||||
noop(explore, _, chart);
|
||||
return {
|
||||
columnsPropsObject: {
|
||||
colnames: ['Previous value', 'Delta', 'Percent change'],
|
||||
|
||||
@@ -36,7 +36,10 @@ jest.mock('@superset-ui/core', () => ({
|
||||
jest.mock('../utils', () => ({
|
||||
getDateFormatter: jest.fn(() => (v: any) => `${v}pm`),
|
||||
parseMetricValue: jest.fn(val => Number(val)),
|
||||
getOriginalLabel: jest.fn((metric, metrics) => metric),
|
||||
getOriginalLabel: jest.fn((metric, metrics) => {
|
||||
console.log(metrics);
|
||||
return metric;
|
||||
}),
|
||||
}));
|
||||
|
||||
describe('BigNumberTotal transformProps', () => {
|
||||
|
||||
@@ -39,7 +39,10 @@ jest.mock('@superset-ui/core', () => ({
|
||||
jest.mock('../utils', () => ({
|
||||
getDateFormatter: jest.fn(() => (v: any) => `${v}pm`),
|
||||
parseMetricValue: jest.fn(val => Number(val)),
|
||||
getOriginalLabel: jest.fn((metric, metrics) => metric),
|
||||
getOriginalLabel: jest.fn((metric, metrics) => {
|
||||
console.log(metrics);
|
||||
return metric;
|
||||
}),
|
||||
}));
|
||||
|
||||
jest.mock('../../utils/tooltip', () => ({
|
||||
|
||||
@@ -44,6 +44,6 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/lodash": "^4.17.16",
|
||||
"jest": "^29.7.0"
|
||||
"jest": "^30.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,6 @@
|
||||
"devDependencies": {
|
||||
"@babel/types": "^7.26.9",
|
||||
"@types/jest": "^29.5.12",
|
||||
"jest": "^29.7.0"
|
||||
"jest": "^30.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
} from 'spec/helpers/testing-library';
|
||||
import ShareSqlLabQuery from 'src/SqlLab/components/ShareSqlLabQuery';
|
||||
import { initialState } from 'src/SqlLab/fixtures';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
const mockStore = configureStore([thunk]);
|
||||
const defaultProps = {
|
||||
@@ -110,7 +111,7 @@ describe('ShareSqlLabQuery', () => {
|
||||
});
|
||||
});
|
||||
const button = screen.getByRole('button');
|
||||
const { id: _id, remoteId: _remoteId, ...expected } = mockQueryEditor;
|
||||
const expected = omit(mockQueryEditor, ['id', 'remoteId']);
|
||||
userEvent.click(button);
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(storeQueryUrl)).toHaveLength(1),
|
||||
@@ -134,7 +135,7 @@ describe('ShareSqlLabQuery', () => {
|
||||
});
|
||||
});
|
||||
const button = screen.getByRole('button');
|
||||
const { id: _id, ...expected } = unsavedQueryEditor;
|
||||
const expected = omit(unsavedQueryEditor, ['id']);
|
||||
userEvent.click(button);
|
||||
await waitFor(() =>
|
||||
expect(fetchMock.calls(storeQueryUrl)).toHaveLength(1),
|
||||
|
||||
@@ -42,6 +42,7 @@ import {
|
||||
LocalStorageKeys,
|
||||
setItem,
|
||||
} from 'src/utils/localStorageHelpers';
|
||||
import { noop } from 'lodash';
|
||||
import TableElement from '../TableElement';
|
||||
|
||||
export interface SqlEditorLeftBarProps {
|
||||
@@ -98,6 +99,8 @@ const SqlEditorLeftBar = ({
|
||||
[allSelectedTables, dbId, schema],
|
||||
);
|
||||
|
||||
noop(_emptyResultsWithSearch); // This is to avoid unused variable warning, can be removed if not needed
|
||||
|
||||
useEffect(() => {
|
||||
const bool = new URLSearchParams(window.location.search).get('db');
|
||||
const userSelected = getItem(
|
||||
|
||||
@@ -35,7 +35,6 @@ interface DatabaseErrorExtra {
|
||||
export function DatabaseErrorMessage({
|
||||
error,
|
||||
source,
|
||||
subtitle,
|
||||
}: ErrorMessageComponentProps<DatabaseErrorExtra | null>) {
|
||||
const { extra, level, message } = error;
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ interface SupersetParseErrorExtra {
|
||||
*/
|
||||
export function InvalidSQLErrorMessage({
|
||||
error,
|
||||
source,
|
||||
subtitle,
|
||||
}: ErrorMessageComponentProps<SupersetParseErrorExtra>) {
|
||||
const { extra, level, message } = error;
|
||||
|
||||
@@ -54,7 +54,6 @@ const findMatches = (undefinedParameters: string[], templateKeys: string[]) => {
|
||||
|
||||
export function ParameterErrorMessage({
|
||||
error,
|
||||
source = 'sqllab',
|
||||
subtitle,
|
||||
}: ErrorMessageComponentProps<ParameterErrorExtra>) {
|
||||
const { extra = { issue_codes: [] }, level, message } = error;
|
||||
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
export const useNativeFilters = () => {
|
||||
const [isInitialized, setIsInitialized] = useState(false);
|
||||
const showNativeFilters = useSelector<RootState, boolean>(
|
||||
state => getUrlParam(URL_PARAMS.showFilters) ?? true,
|
||||
() => getUrlParam(URL_PARAMS.showFilters) ?? true,
|
||||
);
|
||||
const canEdit = useSelector<RootState, boolean>(
|
||||
({ dashboardInfo }) => dashboardInfo.dash_edit_perm,
|
||||
|
||||
@@ -31,7 +31,7 @@ const mockAddDangerToast = jest.fn();
|
||||
|
||||
jest.mock('src/utils/downloadAsImage', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => (_e: SyntheticEvent) => {}),
|
||||
default: jest.fn(() => (_e: SyntheticEvent) => console.log(_e)),
|
||||
}));
|
||||
|
||||
jest.mock('src/components/MessageToasts/withToasts', () => ({
|
||||
|
||||
@@ -31,7 +31,7 @@ const mockAddDangerToast = jest.fn();
|
||||
|
||||
jest.mock('src/utils/downloadAsPdf', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => (_e: SyntheticEvent) => {}),
|
||||
default: jest.fn(() => (_e: SyntheticEvent) => console.log(_e)),
|
||||
}));
|
||||
|
||||
jest.mock('src/components/MessageToasts/withToasts', () => ({
|
||||
|
||||
@@ -181,7 +181,7 @@ const HorizontalFormItem = styled(StyledFormItem)<{
|
||||
}
|
||||
|
||||
.select-container {
|
||||
${({ inverseSelection, theme }) =>
|
||||
${({ inverseSelection }) =>
|
||||
inverseSelection &&
|
||||
`
|
||||
width: 164px;
|
||||
|
||||
@@ -232,7 +232,7 @@ export const DashboardPage: FC<PageProps> = ({ idOrSlug }: PageProps) => {
|
||||
|
||||
const globalStyles = useMemo(
|
||||
() => [
|
||||
filterCardPopoverStyle(theme),
|
||||
filterCardPopoverStyle(),
|
||||
headerStyles(theme),
|
||||
chartContextMenuStyles(theme),
|
||||
focusStyle(theme),
|
||||
|
||||
@@ -65,7 +65,7 @@ export const chartHeaderStyles = (theme: SupersetTheme) => css`
|
||||
}
|
||||
`;
|
||||
|
||||
export const filterCardPopoverStyle = (theme: SupersetTheme) => css`
|
||||
export const filterCardPopoverStyle = () => css`
|
||||
.filter-card-tooltip {
|
||||
&.ant-tooltip-placement-bottom {
|
||||
padding-top: 0;
|
||||
|
||||
@@ -75,51 +75,50 @@ const expectedDisplayValues = {
|
||||
|
||||
test('useTableColumns with no options', () => {
|
||||
const hook = renderHook(() => useTableColumns(colnames, coltypes, data));
|
||||
expect(hook.result.current).toEqual([
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: 'col01',
|
||||
accessor: expect.any(Function),
|
||||
id: 'col01',
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: 'col02',
|
||||
accessor: expect.any(Function),
|
||||
id: 'col02',
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: ASCII_KEY,
|
||||
accessor: expect.any(Function),
|
||||
id: ASCII_KEY,
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: UNICODE_KEY,
|
||||
accessor: expect.any(Function),
|
||||
id: UNICODE_KEY,
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: expect.objectContaining({
|
||||
type: expect.objectContaining({
|
||||
name: 'DataTableTemporalHeaderCell',
|
||||
}),
|
||||
props: expect.objectContaining({
|
||||
onTimeColumnChange: expect.any(Function),
|
||||
}),
|
||||
}),
|
||||
accessor: expect.any(Function),
|
||||
id: NUMTIME_KEY,
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: STRTIME_KEY,
|
||||
accessor: expect.any(Function),
|
||||
id: STRTIME_KEY,
|
||||
},
|
||||
]);
|
||||
expect(hook.result.current).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "col01",
|
||||
"accessor": [Function],
|
||||
"id": "col01",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "col02",
|
||||
"accessor": [Function],
|
||||
"id": "col02",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~",
|
||||
"accessor": [Function],
|
||||
"id": " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "你好. 吃了吗?",
|
||||
"accessor": [Function],
|
||||
"id": "你好. 吃了吗?",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": <DataTableTemporalHeaderCell
|
||||
columnName="numtime"
|
||||
isOriginalTimeColumn={false}
|
||||
onTimeColumnChange={[Function]}
|
||||
/>,
|
||||
"accessor": [Function],
|
||||
"id": "numtime",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "strtime",
|
||||
"accessor": [Function],
|
||||
"id": "strtime",
|
||||
},
|
||||
]
|
||||
`);
|
||||
hook.result.current.forEach((col: JsonObject) => {
|
||||
expect(col.accessor(data[0])).toBe(data[0][col.id]);
|
||||
});
|
||||
@@ -139,51 +138,50 @@ test('useTableColumns with options', () => {
|
||||
col01: { Header: 'Header' },
|
||||
}),
|
||||
);
|
||||
expect(hook.result.current).toEqual([
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: 'Header',
|
||||
accessor: expect.any(Function),
|
||||
id: 'col01',
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: 'col02',
|
||||
accessor: expect.any(Function),
|
||||
id: 'col02',
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: ASCII_KEY,
|
||||
accessor: expect.any(Function),
|
||||
id: ASCII_KEY,
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: UNICODE_KEY,
|
||||
accessor: expect.any(Function),
|
||||
id: UNICODE_KEY,
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: expect.objectContaining({
|
||||
type: expect.objectContaining({
|
||||
name: 'DataTableTemporalHeaderCell',
|
||||
}),
|
||||
props: expect.objectContaining({
|
||||
onTimeColumnChange: expect.any(Function),
|
||||
}),
|
||||
}),
|
||||
accessor: expect.any(Function),
|
||||
id: NUMTIME_KEY,
|
||||
},
|
||||
{
|
||||
Cell: expect.any(Function),
|
||||
Header: STRTIME_KEY,
|
||||
accessor: expect.any(Function),
|
||||
id: STRTIME_KEY,
|
||||
},
|
||||
]);
|
||||
expect(hook.result.current).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "Header",
|
||||
"accessor": [Function],
|
||||
"id": "col01",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "col02",
|
||||
"accessor": [Function],
|
||||
"id": "col02",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~",
|
||||
"accessor": [Function],
|
||||
"id": " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_\`abcdefghijklmnopqrstuvwxyz{|}~",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "你好. 吃了吗?",
|
||||
"accessor": [Function],
|
||||
"id": "你好. 吃了吗?",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": <DataTableTemporalHeaderCell
|
||||
columnName="numtime"
|
||||
isOriginalTimeColumn={false}
|
||||
onTimeColumnChange={[Function]}
|
||||
/>,
|
||||
"accessor": [Function],
|
||||
"id": "numtime",
|
||||
},
|
||||
{
|
||||
"Cell": [Function],
|
||||
"Header": "strtime",
|
||||
"accessor": [Function],
|
||||
"id": "strtime",
|
||||
},
|
||||
]
|
||||
`);
|
||||
hook.result.current.forEach((col: JsonObject) => {
|
||||
expect(col.accessor(data[0])).toBe(data[0][col.id]);
|
||||
});
|
||||
|
||||
@@ -39,7 +39,7 @@ import {
|
||||
import { DataTablesPaneProps, ResultTypes } from './types';
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
${({ theme }) => `
|
||||
${() => `
|
||||
display: flex;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { isEmpty, isEqual } from 'lodash';
|
||||
import { isEmpty, isEqual, noop } from 'lodash';
|
||||
import {
|
||||
BinaryAdhocFilter,
|
||||
css,
|
||||
@@ -61,6 +61,8 @@ const oldChoices = {
|
||||
export const ComparisonRangeLabel = ({
|
||||
multi = true,
|
||||
}: ComparisonRangeLabelProps) => {
|
||||
noop(multi); // This is to avoid unused variable warning, can be removed if not needed
|
||||
|
||||
const [labels, setLabels] = useState<string[]>([]);
|
||||
const currentTimeRangeFilters = useSelector<RootState, BinaryAdhocFilter[]>(
|
||||
state =>
|
||||
|
||||
@@ -38,7 +38,9 @@ const defaultProps = {
|
||||
multi: true,
|
||||
needAsyncVerification: true,
|
||||
actions: { setControlValue: mockSetControlValue },
|
||||
onChange: (p0: string[]) => {},
|
||||
onChange: (p0: string[]) => {
|
||||
console.log('onChange called with:', p0);
|
||||
},
|
||||
columns: [
|
||||
{ type: 'VARCHAR(255)', column_name: 'source' },
|
||||
{ type: 'VARCHAR(255)', column_name: 'target' },
|
||||
|
||||
@@ -59,11 +59,7 @@ export interface EmptyStateProps {
|
||||
otherTabTitle?: string;
|
||||
}
|
||||
|
||||
export default function EmptyState({
|
||||
tableName,
|
||||
tab,
|
||||
otherTabTitle,
|
||||
}: EmptyStateProps) {
|
||||
export default function EmptyState({ tableName, tab }: EmptyStateProps) {
|
||||
const getActionButton = () => {
|
||||
if (tableName === WelcomeTable.Recents) {
|
||||
return null;
|
||||
|
||||
@@ -47,10 +47,7 @@ interface TagCardProps {
|
||||
function TagCard({
|
||||
tag,
|
||||
hasPerm,
|
||||
bulkSelectEnabled,
|
||||
tagFilter,
|
||||
refreshData,
|
||||
userId,
|
||||
addDangerToast,
|
||||
addSuccessToast,
|
||||
showThumbnails,
|
||||
|
||||
@@ -234,7 +234,7 @@ const TagModal: FC<TagModalProps> = ({
|
||||
objects_to_tag: [...dashboards, ...charts, ...savedQueries],
|
||||
},
|
||||
})
|
||||
.then(({ json = {} }) => {
|
||||
.then(() => {
|
||||
refreshData();
|
||||
clearTagForm();
|
||||
addSuccessToast(t('Tag updated'));
|
||||
@@ -252,7 +252,7 @@ const TagModal: FC<TagModalProps> = ({
|
||||
objects_to_tag: [...dashboards, ...charts, ...savedQueries],
|
||||
},
|
||||
})
|
||||
.then(({ json = {} }) => {
|
||||
.then(() => {
|
||||
refreshData();
|
||||
clearTagForm();
|
||||
addSuccessToast(t('Tag created'));
|
||||
|
||||
@@ -74,11 +74,10 @@ export function fetchTags(
|
||||
{
|
||||
objectType,
|
||||
objectId,
|
||||
includeTypes = false,
|
||||
}: {
|
||||
objectType: string;
|
||||
objectId: number;
|
||||
includeTypes: boolean;
|
||||
includeTypes?: boolean;
|
||||
},
|
||||
callback: (json: JsonObject) => void,
|
||||
error: (response: Response) => void,
|
||||
@@ -151,11 +150,10 @@ export function addTag(
|
||||
{
|
||||
objectType,
|
||||
objectId,
|
||||
includeTypes = false,
|
||||
}: {
|
||||
objectType: string;
|
||||
objectId: number;
|
||||
includeTypes: boolean;
|
||||
includeTypes?: boolean;
|
||||
},
|
||||
tag: string,
|
||||
callback: (text: string) => void,
|
||||
|
||||
@@ -109,7 +109,7 @@ function AllEntities() {
|
||||
const editableTitleProps = {
|
||||
title: tag?.name || '',
|
||||
placeholder: 'testing',
|
||||
onSave: (newDatasetName: string) => {},
|
||||
onSave: () => {},
|
||||
canEdit: false,
|
||||
label: t('dataset name'),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user