diff --git a/superset-frontend/package-lock.json b/superset-frontend/package-lock.json
index 6307c40d57c..b10c58bf80e 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -194,7 +194,6 @@
"@testing-library/user-event": "^12.8.3",
"@types/classnames": "^2.2.10",
"@types/dom-to-image": "^2.6.7",
- "@types/enzyme": "^3.10.18",
"@types/fetch-mock": "^7.3.2",
"@types/jest": "^29.5.12",
"@types/jquery": "^3.5.8",
@@ -224,7 +223,6 @@
"@types/yargs": "12 - 18",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
- "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"babel-jest": "^29.7.0",
"babel-loader": "^10.0.0",
"babel-plugin-dynamic-import-node": "^2.3.3",
@@ -236,8 +234,6 @@
"cross-env": "^7.0.3",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.2",
- "enzyme": "^3.11.0",
- "enzyme-matchers": "^7.1.2",
"eslint": "^8.56.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^7.2.0",
@@ -14053,55 +14049,6 @@
}
}
},
- "node_modules/@wojtekmaj/enzyme-adapter-react-17": {
- "version": "0.8.0",
- "resolved": "https://registry.npmjs.org/@wojtekmaj/enzyme-adapter-react-17/-/enzyme-adapter-react-17-0.8.0.tgz",
- "integrity": "sha512-zeUGfQRziXW7R7skzNuJyi01ZwuKCH8WiBNnTgUJwdS/CURrJwAhWsfW7nG7E30ak8Pu3ZwD9PlK9skBfAoOBw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@wojtekmaj/enzyme-adapter-utils": "^0.2.0",
- "enzyme-shallow-equal": "^1.0.0",
- "has": "^1.0.0",
- "prop-types": "^15.7.0",
- "react-is": "^17.0.0",
- "react-test-renderer": "^17.0.0"
- },
- "funding": {
- "url": "https://github.com/wojtekmaj/enzyme-adapter-react-17?sponsor=1"
- },
- "peerDependencies": {
- "enzyme": "^3.0.0",
- "react": "^17.0.0-0",
- "react-dom": "^17.0.0-0"
- }
- },
- "node_modules/@wojtekmaj/enzyme-adapter-react-17/node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@wojtekmaj/enzyme-adapter-utils": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@wojtekmaj/enzyme-adapter-utils/-/enzyme-adapter-utils-0.2.0.tgz",
- "integrity": "sha512-ZvZm9kZxZEKAbw+M1/Q3iDuqQndVoN8uLnxZ8bzxm7KgGTBejrGRoJAp8f1EN8eoO3iAjBNEQnTDW/H4Ekb0FQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "function.prototype.name": "^1.1.0",
- "has": "^1.0.0",
- "object.fromentries": "^2.0.0",
- "prop-types": "^15.7.0"
- },
- "funding": {
- "url": "https://github.com/wojtekmaj/enzyme-adapter-utils?sponsor=1"
- },
- "peerDependencies": {
- "react": "^17.0.0-0"
- }
- },
"node_modules/@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
@@ -15647,6 +15594,8 @@
"integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
@@ -17792,13 +17741,6 @@
"node": ">=8"
}
},
- "node_modules/circular-json-es6": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/circular-json-es6/-/circular-json-es6-2.0.2.tgz",
- "integrity": "sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/citty": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz",
@@ -20098,28 +20040,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/deep-equal-ident": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/deep-equal-ident/-/deep-equal-ident-1.1.1.tgz",
- "integrity": "sha512-aWv7VhTl/Lju1zenOD3E1w8PpUVrTDbwXCHtbSNr+p/uadr49Y1P1ld0W3Pl6gbvIbiRjoCVsqw70UupCNGh6g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash.isequal": "^3.0"
- }
- },
- "node_modules/deep-equal-ident/node_modules/lodash.isequal": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz",
- "integrity": "sha512-Bsu5fP9Omd+HBk2Dz8qp4BHbC+83DBykZ87Lz1JmPKTVNy4Q0XQVtUrbfXVAK/udQrWNcGStcKSA9yj/Zkm3TQ==",
- "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash._baseisequal": "^3.0.0",
- "lodash._bindcallback": "^3.0.0"
- }
- },
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -20516,7 +20436,9 @@
"resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
"integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "optional": true,
+ "peer": true
},
"node_modules/distributions": {
"version": "2.2.0",
@@ -21204,6 +21126,8 @@
"integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"array.prototype.flat": "^1.2.3",
"cheerio": "^1.0.0-rc.3",
@@ -21232,26 +21156,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/enzyme-matchers": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/enzyme-matchers/-/enzyme-matchers-7.1.2.tgz",
- "integrity": "sha512-03WqAg2XDl7id9rARIO97HQ1JIw9F2heJ3R4meGu/13hx0ULTDEgl0E67MGl2Uq1jq1DyRnJfto1/VSzskdV5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "circular-json-es6": "^2.0.1",
- "deep-equal-ident": "^1.1.1"
- },
- "peerDependencies": {
- "enzyme": ">=3.4.0"
- }
- },
"node_modules/enzyme-shallow-equal": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz",
"integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"hasown": "^2.0.0",
"object-is": "^1.1.5"
@@ -26262,6 +26174,8 @@
"integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"array.prototype.filter": "^1.0.0",
"call-bind": "^1.0.2"
@@ -31531,32 +31445,6 @@
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
- "node_modules/lodash._baseisequal": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz",
- "integrity": "sha512-U+3GsNEZj9ebI03ncLC2pLmYVjgtYZEwdkAPO7UGgtGvAz36JVFPAQUufpSaVL93Cz5arc6JGRKZRhaOhyVJYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash.isarray": "^3.0.0",
- "lodash.istypedarray": "^3.0.0",
- "lodash.keys": "^3.0.0"
- }
- },
- "node_modules/lodash._bindcallback": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
- "integrity": "sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash._getnative": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
- "integrity": "sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/lodash.curry": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.curry/-/lodash.curry-4.1.1.tgz",
@@ -31575,14 +31463,17 @@
"resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
"integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "optional": true,
+ "peer": true
},
"node_modules/lodash.flattendeep": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
"integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/lodash.get": {
"version": "4.4.2",
@@ -31590,20 +31481,6 @@
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
"license": "MIT"
},
- "node_modules/lodash.isarguments": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
- "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.isarray": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
- "integrity": "sha512-JwObCrNJuT0Nnbuecmqr5DgtuBppuCvGD9lxjFpAzwnVtdGoDQ1zig+5W8k5/6Gcn0gZ3936HDAlGd28i7sOGQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/lodash.isequal": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
@@ -31624,25 +31501,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lodash.istypedarray": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz",
- "integrity": "sha512-lGWJ6N8AA3KSv+ZZxlTdn4f6A7kMfpJboeyvbFdE7IU9YAgweODqmOgdUHOA+c6lVWeVLysdaxciFXi+foVsWw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.keys": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
- "integrity": "sha512-CuBsapFjcubOGMn3VD+24HOAPxM79tH+V6ivJL3CHYjtrawauDJHUk//Yew9Hvc6e9rbCrURGk8z6PC+8WJBfQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash._getnative": "^3.0.0",
- "lodash.isarguments": "^3.0.0",
- "lodash.isarray": "^3.0.0"
- }
- },
"node_modules/lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
@@ -33911,7 +33769,9 @@
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "BSD-3-Clause",
+ "optional": true,
+ "peer": true
},
"node_modules/mousetrap": {
"version": "1.6.5",
@@ -34059,6 +33919,8 @@
"integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"commander": "^2.19.0",
"moo": "^0.5.0",
@@ -34081,7 +33943,9 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "optional": true,
+ "peer": true
},
"node_modules/needle": {
"version": "3.3.1",
@@ -38276,8 +38140,8 @@
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
"integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
"dependencies": {
"performance-now": "^2.1.0"
}
@@ -38287,7 +38151,9 @@
"resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
"integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==",
"dev": true,
- "license": "CC0-1.0"
+ "license": "CC0-1.0",
+ "optional": true,
+ "peer": true
},
"node_modules/ramda": {
"version": "0.29.0",
@@ -38305,6 +38171,8 @@
"integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"discontinuous-range": "1.0.0",
"ret": "~0.1.10"
@@ -39736,8 +39604,9 @@
"version": "16.15.0",
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
"integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"object-assign": "^4.1.1",
"react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
@@ -39831,8 +39700,9 @@
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
"integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==",
- "devOptional": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"dependencies": {
"object-assign": "^4.1.1",
"react-is": "^17.0.2",
@@ -39847,8 +39717,9 @@
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
- "devOptional": true,
- "license": "MIT"
+ "license": "MIT",
+ "optional": true,
+ "peer": true
},
"node_modules/react-transition-group": {
"version": "4.4.5",
@@ -41985,6 +41856,8 @@
"integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
"dev": true,
"license": "MIT",
+ "optional": true,
+ "peer": true,
"engines": {
"node": ">=0.12"
}
@@ -42157,6 +42030,8 @@
"integrity": "sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==",
"dev": true,
"license": "BSD-3-Clause",
+ "optional": true,
+ "peer": true,
"dependencies": {
"lodash.flattendeep": "^4.4.0",
"nearley": "^2.7.10"
diff --git a/superset-frontend/package.json b/superset-frontend/package.json
index 9c9422e7946..ad8a68d444d 100644
--- a/superset-frontend/package.json
+++ b/superset-frontend/package.json
@@ -261,7 +261,6 @@
"@testing-library/user-event": "^12.8.3",
"@types/classnames": "^2.2.10",
"@types/dom-to-image": "^2.6.7",
- "@types/enzyme": "^3.10.18",
"@types/fetch-mock": "^7.3.2",
"@types/jest": "^29.5.12",
"@types/jquery": "^3.5.8",
@@ -291,7 +290,6 @@
"@types/yargs": "12 - 18",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
- "@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"babel-jest": "^29.7.0",
"babel-loader": "^10.0.0",
"babel-plugin-dynamic-import-node": "^2.3.3",
@@ -303,8 +301,6 @@
"cross-env": "^7.0.3",
"css-loader": "^7.1.2",
"css-minimizer-webpack-plugin": "^7.0.2",
- "enzyme": "^3.11.0",
- "enzyme-matchers": "^7.1.2",
"eslint": "^8.56.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^7.2.0",
diff --git a/superset-frontend/packages/superset-ui-chart-controls/package.json b/superset-frontend/packages/superset-ui-chart-controls/package.json
index 76a1169a3d2..c487d3449d4 100644
--- a/superset-frontend/packages/superset-ui-chart-controls/package.json
+++ b/superset-frontend/packages/superset-ui-chart-controls/package.json
@@ -25,7 +25,6 @@
],
"dependencies": {
"@react-icons/all-files": "^4.1.0",
- "@types/enzyme": "^3.10.18",
"@types/react": "*",
"lodash": "^4.17.21",
"prop-types": "^15.8.1"
diff --git a/superset-frontend/packages/superset-ui-core/package.json b/superset-frontend/packages/superset-ui-core/package.json
index 158aaa15d35..a6393c22e8b 100644
--- a/superset-frontend/packages/superset-ui-core/package.json
+++ b/superset-frontend/packages/superset-ui-core/package.json
@@ -56,7 +56,6 @@
"@types/d3-scale": "^2.1.1",
"@types/d3-time": "^3.0.4",
"@types/d3-time-format": "^4.0.3",
- "@types/enzyme": "^3.10.18",
"@types/fetch-mock": "^7.3.8",
"@types/lodash": "^4.17.16",
"@types/math-expression-evaluator": "^1.3.3",
diff --git a/superset-frontend/scripts/eslint-metrics-uploader.js b/superset-frontend/scripts/eslint-metrics-uploader.js
index 6c6d4a9de92..0b38e590bac 100644
--- a/superset-frontend/scripts/eslint-metrics-uploader.js
+++ b/superset-frontend/scripts/eslint-metrics-uploader.js
@@ -58,7 +58,7 @@ module.exports = async results => {
// Ignore thie rule here - the messages in eslintrc_metrics.js are sufficient descriptions, broken down by file type.
'no-restricted-imports': {
description:
- "This rule catches several things that shouldn't be used anymore. LESS, antD, enzyme, etc. See individual occurrence messages for details",
+ "This rule catches several things that shouldn't be used anymore. LESS, antD, etc. See individual occurrence messages for details",
},
'no-console': {
description:
diff --git a/superset-frontend/spec/helpers/shim.tsx b/superset-frontend/spec/helpers/shim.tsx
index af5ea846815..c8c19a56613 100644
--- a/superset-frontend/spec/helpers/shim.tsx
+++ b/superset-frontend/spec/helpers/shim.tsx
@@ -20,10 +20,7 @@ import { AriaAttributes } from 'react';
import 'core-js/stable';
import 'regenerator-runtime/runtime';
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
-import 'enzyme-matchers';
import jQuery from 'jquery';
-import Enzyme from 'enzyme';
-import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
// https://jestjs.io/docs/jest-object#jestmockmodulename-factory-options
// in order to mock modules in test case, so avoid absolute import module
import { configure as configureTranslation } from '../../packages/superset-ui-core/src/translation';
@@ -33,8 +30,6 @@ import { ResizeObserver } from './ResizeObserver';
import setupSupersetClient from './setupSupersetClient';
import CacheStorage from './CacheStorage';
-Enzyme.configure({ adapter: new Adapter() });
-
const exposedProperties = ['window', 'navigator', 'document'];
const { defaultView } = document;
diff --git a/superset-frontend/spec/helpers/theming.ts b/superset-frontend/spec/helpers/theming.ts
deleted file mode 100644
index d24126b8d16..00000000000
--- a/superset-frontend/spec/helpers/theming.ts
+++ /dev/null
@@ -1,44 +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.
- */
-import { mount as enzymeMount } from 'enzyme';
-// eslint-disable-next-line no-restricted-imports
-import { supersetTheme } from '@superset-ui/core';
-import { ReactElement } from 'react';
-import { ProviderWrapper } from './ProviderWrapper';
-
-type optionsType = {
- wrappingComponentProps?: any;
- wrappingComponent?: ReactElement;
- context?: any;
- newOption?: string;
-};
-
-export function styledMount(
- component: ReactElement,
- options: optionsType = {},
-): any {
- return enzymeMount(component, {
- ...options,
- wrappingComponent: ProviderWrapper,
- wrappingComponentProps: {
- theme: supersetTheme,
- ...options?.wrappingComponentProps,
- },
- });
-}
diff --git a/superset-frontend/spec/helpers/waitForComponentToPaint.ts b/superset-frontend/spec/helpers/waitForComponentToPaint.ts
deleted file mode 100644
index 2e57a80b413..00000000000
--- a/superset-frontend/spec/helpers/waitForComponentToPaint.ts
+++ /dev/null
@@ -1,34 +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.
- */
-import { ReactWrapper } from 'enzyme';
-import { act } from 'react-dom/test-utils';
-
-// taken from: https://github.com/enzymejs/enzyme/issues/2073
-// There is currently and issue with enzyme and react-16's hooks
-// that results in a race condition between tests and react hook updates.
-// This function ensures tests run after all react updates are done.
-export default async function waitForComponentToPaint
(
- wrapper: ReactWrapper
,
- amount = 0,
-) {
- await act(async () => {
- await new Promise(resolve => setTimeout(resolve, amount));
- wrapper.update();
- });
-}
diff --git a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
index ef931af8735..837f892ff69 100644
--- a/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
+++ b/superset-frontend/src/SqlLab/components/TabbedSqlEditors/index.tsx
@@ -230,7 +230,6 @@ class TabbedSqlEditors extends PureComponent {
}
- // for tests - key prop isn't handled by enzyme well bcs it's a react keyword
data-key={qe.id}
>
{},
-};
-
-const setup = overrideProps =>
- mount(
-
-
- ,
- {
- wrappingComponent: ThemeProvider,
- wrappingComponentProps: { theme: supersetTheme },
- },
- );
-
-// all these tests need to be moved to dashboard/components/PropertiesModal/PropertiesModal.test.tsx
-describe.skip('PropertiesModal', () => {
- afterEach(() => {
- jest.restoreAllMocks();
- jest.resetAllMocks();
- });
-
- describe('onColorSchemeChange', () => {
- it('sets up a default state', () => {
- const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
- expect(
- wrapper.find('PropertiesModal').instance().state.values.colorScheme,
- ).toEqual('SUPERSET_DEFAULT');
- });
- describe('with a valid color scheme as an arg', () => {
- describe('without metadata', () => {
- const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('updates the color scheme in the metadata', () => {
- const spy = jest.spyOn(modalInstance, 'onMetadataChange');
- modalInstance.onColorSchemeChange('SUPERSET_DEFAULT');
- expect(spy).toHaveBeenCalledWith(
- '{"something": "foo", "color_scheme": "SUPERSET_DEFAULT", "label_colors": {}}',
- );
- });
- });
- describe('with metadata', () => {
- describe('with color_scheme in the metadata', () => {
- it('will update the metadata', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- modalInstance.setState({
- values: {
- json_metadata: '{"color_scheme": "foo"}',
- },
- });
- const spy = jest.spyOn(modalInstance, 'onMetadataChange');
- modalInstance.onColorSchemeChange('SUPERSET_DEFAULT');
- expect(spy).toHaveBeenCalledWith(
- '{"color_scheme": "SUPERSET_DEFAULT", "label_colors": {}}',
- );
- });
- });
- it('without color_scheme in the metadata', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- modalInstance.setState({
- values: {
- json_metadata: '{"timed_refresh_immune_slices": []}',
- },
- });
- it('will update the metadata', () => {
- const spy = jest.spyOn(modalInstance, 'onMetadataChange');
- modalInstance.onColorSchemeChange('SUPERSET_DEFAULT');
- expect(spy).toHaveBeenCalledWith(
- '{"something": "foo", "color_scheme": "SUPERSET_DEFAULT", "label_colors": {}}',
- );
- });
- });
- });
- });
- describe('with an invalid color scheme as an arg', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('will raise an error', () => {
- const spy = jest.spyOn(Modal, 'error');
- expect(() =>
- modalInstance.onColorSchemeChange('THIS_WILL_NOT_WORK'),
- ).toThrow('A valid color scheme is required');
- expect(spy).toHaveBeenCalled();
- });
- });
- describe('with an empty color scheme as an arg', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('will not raise an error', () => {
- const spy = jest.spyOn(Modal, 'error');
- modalInstance.onColorSchemeChange('');
- expect(spy).not.toHaveBeenCalled();
- });
- });
- });
- describe('onOwnersChange', () => {
- it('should update the state with the value passed', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- const spy = jest.spyOn(modalInstance, 'updateFormState');
- const newOwners = [{ value: 1, label: 'foo' }];
- modalInstance.onOwnersChange(newOwners);
- expect(spy).toHaveBeenCalledWith('owners', newOwners);
- });
- });
- describe('onMetadataChange', () => {
- it('should update the state with the value passed', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- const spy = jest.spyOn(modalInstance, 'updateFormState');
- modalInstance.onMetadataChange('foo');
- expect(spy).toHaveBeenCalledWith('json_metadata', 'foo');
- });
- });
- describe('onChange', () => {
- it('should update the state with the value passed', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- const spy = jest.spyOn(modalInstance, 'updateFormState');
- modalInstance.onChange({ target: { name: 'test', value: 'foo' } });
- expect(spy).toHaveBeenCalledWith('test', 'foo');
- });
- });
- describe('fetchDashboardDetails', () => {
- it('should make an api call', () => {
- const spy = jest.spyOn(SupersetClient, 'get');
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- modalInstance.fetchDashboardDetails();
- expect(spy).toHaveBeenCalledWith({
- endpoint: '/api/v1/dashboard/1',
- });
- });
-
- it('should update state', async () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- const fetchSpy = jest
- .spyOn(SupersetClient, 'get')
- .mockResolvedValue(dashboardResult);
- modalInstance.fetchDashboardDetails();
- await fetchSpy();
- expect(modalInstance.state.values.colorScheme).toBeUndefined();
- expect(modalInstance.state.values.dashboard_title).toEqual('New Title');
- expect(modalInstance.state.values.slug).toEqual('/new');
- expect(modalInstance.state.values.json_metadata).toEqual(
- '{"something": "foo"}',
- );
- });
-
- it('should call onOwnersChange', async () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
- json: {
- result: {
- dashboard_title: 'New Title',
- slug: '/new',
- json_metadata: '{"something":"foo"}',
- owners: [{ id: 1, first_name: 'Al', last_name: 'Pacino' }],
- roles: [],
- },
- },
- });
- const onOwnersSpy = jest.spyOn(modalInstance, 'onOwnersChange');
- modalInstance.fetchDashboardDetails();
- await fetchSpy();
- expect(modalInstance.state.values.colorScheme).toBeUndefined();
- expect(onOwnersSpy).toHaveBeenCalledWith([
- { value: 1, label: 'Al Pacino' },
- ]);
- });
-
- it('should call onRolesChange', async () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
- json: {
- result: {
- dashboard_title: 'New Title',
- slug: '/new',
- json_metadata: '{"something":"foo"}',
- owners: [],
- roles: [{ id: 1, name: 'Alpha' }],
- },
- },
- });
- const onRolwesSpy = jest.spyOn(modalInstance, 'onRolesChange');
- modalInstance.fetchDashboardDetails();
- await fetchSpy();
- expect(modalInstance.state.values.colorScheme).toBeUndefined();
- expect(onRolwesSpy).toHaveBeenCalledWith([{ value: 1, label: 'Alpha' }]);
- });
-
- describe('when colorScheme is undefined as a prop', () => {
- describe('when color_scheme is defined in json_metadata', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('should use the color_scheme from json_metadata in the api response', async () => {
- const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
- json: {
- result: {
- dashboard_title: 'New Title',
- slug: '/new',
- json_metadata: '{"color_scheme":"SUPERSET_DEFAULT"}',
- owners: [],
- roles: [],
- },
- },
- });
- modalInstance.fetchDashboardDetails();
-
- // this below triggers the callback of the api call
- await fetchSpy();
-
- expect(modalInstance.state.values.colorScheme).toEqual(
- 'SUPERSET_DEFAULT',
- );
- });
- describe('when color_scheme is not defined in json_metadata', () => {
- const wrapper = setup();
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('should be undefined', async () => {
- const fetchSpy = jest
- .spyOn(SupersetClient, 'get')
- .mockResolvedValue(dashboardResult);
- modalInstance.fetchDashboardDetails();
- await fetchSpy();
- expect(modalInstance.state.values.colorScheme).toBeUndefined();
- });
- });
- });
- });
- describe('when colorScheme is defined as a prop', () => {
- describe('when color_scheme is defined in json_metadata', () => {
- const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('should use the color_scheme from json_metadata in the api response', async () => {
- const fetchSpy = jest.spyOn(SupersetClient, 'get').mockResolvedValue({
- json: {
- result: {
- dashboard_title: 'New Title',
- slug: '/new',
- json_metadata: '{"color_scheme":"SUPERSET_DEFAULT"}',
- owners: [],
- roles: [],
- },
- },
- });
- modalInstance.fetchDashboardDetails();
- await fetchSpy();
- expect(modalInstance.state.values.colorScheme).toEqual(
- 'SUPERSET_DEFAULT',
- );
- });
- });
- describe('when color_scheme is not defined in json_metadata', () => {
- const wrapper = setup({ colorScheme: 'SUPERSET_DEFAULT' });
- const modalInstance = wrapper.find('PropertiesModal').instance();
- it('should use the colorScheme from the prop', async () => {
- const fetchSpy = jest
- .spyOn(SupersetClient, 'get')
- .mockResolvedValue(dashboardResult);
- modalInstance.fetchDashboardDetails();
- await fetchSpy();
- expect(modalInstance.state.values.colorScheme).toBeUndefined();
- });
- });
- });
- });
-});
diff --git a/superset-frontend/src/features/annotationLayers/AnnotationLayerModal.test.jsx b/superset-frontend/src/features/annotationLayers/AnnotationLayerModal.test.jsx
deleted file mode 100644
index f1ccfdacc29..00000000000
--- a/superset-frontend/src/features/annotationLayers/AnnotationLayerModal.test.jsx
+++ /dev/null
@@ -1,91 +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.
- */
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import { Provider } from 'react-redux';
-import fetchMock from 'fetch-mock';
-import Modal from 'src/components/Modal';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { styledMount as mount } from 'spec/helpers/theming';
-import AnnotationLayerModal from './AnnotationLayerModal';
-
-const mockData = { id: 1, name: 'test', descr: 'test description' };
-const FETCH_ANNOTATION_LAYER_ENDPOINT = 'glob:*/api/v1/annotation_layer/*';
-const ANNOTATION_LAYER_PAYLOAD = { result: mockData };
-
-fetchMock.get(FETCH_ANNOTATION_LAYER_ENDPOINT, ANNOTATION_LAYER_PAYLOAD);
-
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const mockedProps = {
- addDangerToast: () => {},
- onLayerAdd: jest.fn(() => []),
- onHide: () => {},
- show: true,
- layer: mockData,
-};
-
-async function mountAndWait(props = mockedProps) {
- const mounted = mount(
-
-
- ,
- );
- await waitForComponentToPaint(mounted);
-
- return mounted;
-}
-
-describe('AnnotationLayerModal', () => {
- let wrapper;
-
- beforeAll(async () => {
- wrapper = await mountAndWait();
- });
-
- it('renders', () => {
- expect(wrapper.find(AnnotationLayerModal)).toBeTruthy();
- });
-
- it('renders a Modal', () => {
- expect(wrapper.find(Modal)).toBeTruthy();
- });
-
- it('renders add header when no layer is included', async () => {
- const addWrapper = await mountAndWait({});
- expect(
- addWrapper.find('[data-test="annotation-layer-modal-title"]').text(),
- ).toEqual('Add annotation layer');
- });
-
- it('renders edit header when layer prop is included', () => {
- expect(
- wrapper.find('[data-test="annotation-layer-modal-title"]').text(),
- ).toEqual('Edit annotation layer properties');
- });
-
- it('renders input element for name', () => {
- expect(wrapper.find('input[name="name"]')).toBeTruthy();
- });
-
- it('renders textarea element for description', () => {
- expect(wrapper.find('textarea[name="descr"]')).toBeTruthy();
- });
-});
diff --git a/superset-frontend/src/features/annotations/AnnotationModal.test.jsx b/superset-frontend/src/features/annotations/AnnotationModal.test.jsx
deleted file mode 100644
index 53da727d60c..00000000000
--- a/superset-frontend/src/features/annotations/AnnotationModal.test.jsx
+++ /dev/null
@@ -1,99 +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.
- */
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import { Provider } from 'react-redux';
-import fetchMock from 'fetch-mock';
-import Modal from 'src/components/Modal';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { JsonEditor } from 'src/components/AsyncAceEditor';
-import { styledMount as mount } from 'spec/helpers/theming';
-import AnnotationModal from './AnnotationModal';
-
-const mockData = {
- id: 1,
- short_descr: 'annotation 1',
- start_dttm: '2019-07-01T10:25:00',
- end_dttm: '2019-06-11T10:25:00',
-};
-
-const FETCH_ANNOTATION_ENDPOINT =
- 'glob:*/api/v1/annotation_layer/*/annotation/*';
-const ANNOTATION_PAYLOAD = { result: mockData };
-
-fetchMock.get(FETCH_ANNOTATION_ENDPOINT, ANNOTATION_PAYLOAD);
-
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const mockedProps = {
- addDangerToast: () => {},
- addSuccessToast: () => {},
- annotation: mockData,
- onAnnotationAdd: jest.fn(() => []),
- onHide: () => {},
- show: true,
-};
-
-async function mountAndWait(props = mockedProps) {
- const mounted = mount(
-
-
- ,
- );
- await waitForComponentToPaint(mounted);
- return mounted;
-}
-
-describe('AnnotationModal', () => {
- let wrapper;
-
- beforeAll(async () => {
- wrapper = await mountAndWait();
- });
-
- it('renders', () => {
- expect(wrapper.find(AnnotationModal)).toBeTruthy();
- });
-
- it('renders a Modal', () => {
- expect(wrapper.find(Modal)).toBeTruthy();
- });
-
- it('renders add header when no annotation prop is included', async () => {
- const addWrapper = await mountAndWait({});
- expect(
- addWrapper.find('[data-test="annotation-modal-title"]').text(),
- ).toEqual('Add annotation');
- });
-
- it('renders edit header when annotation prop is included', () => {
- expect(wrapper.find('[data-test="annotation-modal-title"]').text()).toEqual(
- 'Edit annotation',
- );
- });
-
- it('renders input elements for annotation name', () => {
- expect(wrapper.find('input[name="short_descr"]')).toBeTruthy();
- });
-
- it('renders json editor for json metadata', () => {
- expect(wrapper.find(JsonEditor)).toBeTruthy();
- });
-});
diff --git a/superset-frontend/src/features/cssTemplates/CssTemplateModal.test.jsx b/superset-frontend/src/features/cssTemplates/CssTemplateModal.test.jsx
deleted file mode 100644
index d636835d006..00000000000
--- a/superset-frontend/src/features/cssTemplates/CssTemplateModal.test.jsx
+++ /dev/null
@@ -1,92 +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.
- */
-import thunk from 'redux-thunk';
-import { Provider } from 'react-redux';
-import configureStore from 'redux-mock-store';
-import fetchMock from 'fetch-mock';
-import Modal from 'src/components/Modal';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { CssEditor } from 'src/components/AsyncAceEditor';
-import { styledMount as mount } from 'spec/helpers/theming';
-import CssTemplateModal from './CssTemplateModal';
-
-const mockData = { id: 1, template_name: 'test' };
-const FETCH_CSS_TEMPLATE_ENDPOINT = 'glob:*/api/v1/css_template/*';
-const CSS_TEMPLATE_PAYLOAD = { result: mockData };
-
-fetchMock.get(FETCH_CSS_TEMPLATE_ENDPOINT, CSS_TEMPLATE_PAYLOAD);
-
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const mockedProps = {
- addDangerToast: () => {},
- onCssTemplateAdd: jest.fn(() => []),
- onHide: () => {},
- show: true,
- cssTemplate: mockData,
-};
-
-async function mountAndWait(props = mockedProps) {
- const mounted = mount(
-
-
- ,
- );
- await waitForComponentToPaint(mounted);
-
- return mounted;
-}
-
-describe('CssTemplateModal', () => {
- let wrapper;
-
- beforeAll(async () => {
- wrapper = await mountAndWait();
- });
-
- it('renders', () => {
- expect(wrapper.find(CssTemplateModal)).toBeTruthy();
- });
-
- it('renders a Modal', () => {
- expect(wrapper.find(Modal)).toBeTruthy();
- });
-
- it('renders add header when no css template is included', async () => {
- const addWrapper = await mountAndWait({});
- expect(
- addWrapper.find('[data-test="css-template-modal-title"]').text(),
- ).toEqual('Add CSS template');
- });
-
- it('renders edit header when css template prop is included', () => {
- expect(
- wrapper.find('[data-test="css-template-modal-title"]').text(),
- ).toEqual('Edit CSS template properties');
- });
-
- it('renders input elements for template name', () => {
- expect(wrapper.find('input[name="template_name"]')).toBeTruthy();
- });
-
- it('renders css editor for css', () => {
- expect(wrapper.find(CssEditor)).toBeTruthy();
- });
-});
diff --git a/superset-frontend/src/features/home/SavedQueries.test.tsx b/superset-frontend/src/features/home/SavedQueries.test.tsx
deleted file mode 100644
index 10530c45750..00000000000
--- a/superset-frontend/src/features/home/SavedQueries.test.tsx
+++ /dev/null
@@ -1,112 +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.
- */
-import thunk from 'redux-thunk';
-import { styledMount as mount } from 'spec/helpers/theming';
-import fetchMock from 'fetch-mock';
-import configureStore from 'redux-mock-store';
-import { act } from 'spec/helpers/testing-library';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import SubMenu from './SubMenu';
-import SavedQueries from './SavedQueries';
-
-// store needed for withToasts(DashboardTable)
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const queriesEndpoint = 'glob:*/api/v1/saved_query/?*';
-const savedQueriesInfo = 'glob:*/api/v1/saved_query/_info*';
-
-const mockqueries = [...new Array(3)].map((_, i) => ({
- created_by: {
- id: i,
- first_name: `user`,
- last_name: `${i}`,
- },
- created_on: `${i}-2020`,
- database: {
- database_name: `db ${i}`,
- id: i,
- },
- changed_on_delta_humanized: '1 day ago',
- db_id: i,
- description: `SQL for ${i}`,
- id: i,
- label: `query ${i}`,
- schema: 'public',
- sql: `SELECT ${i} FROM table`,
- sql_tables: [
- {
- catalog: null,
- schema: null,
- table: `${i}`,
- },
- ],
-}));
-
-fetchMock.get(queriesEndpoint, {
- result: mockqueries,
-});
-
-fetchMock.get(savedQueriesInfo, {
- permissions: ['can_list', 'can_edit', 'can_delete'],
-});
-
-describe('SavedQueries', () => {
- const savedQueryProps = {
- user: {
- userId: '1',
- },
- mine: mockqueries,
- };
-
- const wrapper = mount();
-
- const clickTab = (idx: number) => {
- act(() => {
- const handler = wrapper.find('[role="tab"] a').at(idx).prop('onClick');
- if (handler) {
- handler({} as any);
- }
- });
- };
-
- beforeAll(async () => {
- await waitForComponentToPaint(wrapper);
- });
-
- it('is valid', () => {
- expect(wrapper.find(SavedQueries)).toBeTruthy();
- });
-
- it('fetches queries mine and renders listviewcard cards', async () => {
- clickTab(0);
- await waitForComponentToPaint(wrapper);
- expect(fetchMock.calls(/saved_query\/\?q/)).toHaveLength(1);
- expect(wrapper.find('ListViewCard')).toBeTruthy();
- });
-
- it('renders a submenu with clickable tables and buttons', async () => {
- expect(wrapper.find(SubMenu)).toBeTruthy();
- expect(wrapper.find('[role="tab"]')).toHaveLength(1);
- expect(wrapper.find('button')).toHaveLength(5);
- clickTab(0);
- await waitForComponentToPaint(wrapper);
- expect(fetchMock.calls(/saved_query\/\?q/)).toHaveLength(2);
- });
-});
diff --git a/superset-frontend/src/features/queries/QueryPreviewModal.test.tsx b/superset-frontend/src/features/queries/QueryPreviewModal.test.tsx
deleted file mode 100644
index 5a9df74f52e..00000000000
--- a/superset-frontend/src/features/queries/QueryPreviewModal.test.tsx
+++ /dev/null
@@ -1,182 +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.
- */
-import { MouseEvent } from 'react';
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { styledMount as mount } from 'spec/helpers/theming';
-
-import { QueryObject } from 'src/views/CRUD/types';
-import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
-import { act } from 'spec/helpers/testing-library';
-import { QueryState } from '@superset-ui/core';
-import QueryPreviewModal from './QueryPreviewModal';
-
-// store needed for withToasts
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const mockQueries: QueryObject[] = [...new Array(3)].map((_, i) => ({
- changed_on: new Date().toISOString(),
- id: i,
- slice_name: `cool chart ${i}`,
- database: {
- database_name: 'main db',
- },
- schema: 'public',
- sql: `SELECT ${i} FROM table`,
- executed_sql: `SELECT ${i} FROM table LIMIT 1000`,
- sql_tables: [
- { schema: 'foo', table: 'table' },
- { schema: 'bar', table: 'table_2' },
- ],
- status: QueryState.Success,
- tab_name: 'Main Tab',
- user: {
- first_name: 'cool',
- last_name: 'dude',
- id: 2,
- username: 'cooldude',
- },
- start_time: new Date().valueOf(),
- end_time: new Date().valueOf(),
- rows: 200,
- tmp_table_name: '',
- tracking_url: '',
-}));
-
-describe('QueryPreviewModal', () => {
- let currentIndex = 0;
- let currentQuery = mockQueries[currentIndex];
- const mockedProps = {
- onHide: jest.fn(),
- openInSqlLab: jest.fn(),
- queries: mockQueries,
- query: currentQuery,
- fetchData: jest.fn(() => {
- currentIndex += 1;
- currentQuery = mockQueries[currentIndex];
- }),
- show: true,
- };
- const wrapper = mount();
-
- beforeAll(async () => {
- await waitForComponentToPaint(wrapper);
- });
-
- it('renders a SyntaxHighlighter', () => {
- expect(wrapper.find(SyntaxHighlighter)).toBeTruthy();
- });
-
- it('toggles between user sql and executed sql', () => {
- expect(
- wrapper.find(SyntaxHighlighter).props().children,
- ).toMatchInlineSnapshot(`"SELECT 0 FROM table"`);
-
- act(() => {
- const props = wrapper
- .find('[data-test="toggle-executed-sql"]')
- .first()
- .props();
-
- if (typeof props.onClick === 'function') {
- props.onClick({} as MouseEvent);
- }
- });
-
- wrapper.update();
-
- expect(
- wrapper.find(SyntaxHighlighter).props().children,
- ).toMatchInlineSnapshot(`"SELECT 0 FROM table LIMIT 1000"`);
- });
-
- describe('Previous button', () => {
- it('disabled when query is the first in list', () => {
- expect(
- wrapper.find('[data-test="previous-query"]').first().props().disabled,
- ).toBe(true);
- });
-
- it('falls fetchData with previous index', () => {
- const mockedProps2 = {
- ...mockedProps,
- query: mockQueries[1],
- };
- const wrapper2 = mount(
- ,
- );
- act(() => {
- const props = wrapper2
- .find('[data-test="previous-query"]')
- .first()
- .props();
- if (typeof props.onClick === 'function') {
- props.onClick({} as MouseEvent);
- }
- });
-
- expect(mockedProps2.fetchData).toHaveBeenCalledWith(0);
- });
- });
-
- describe('Next button', () => {
- it('calls fetchData with next index', () => {
- act(() => {
- const props = wrapper.find('[data-test="next-query"]').first().props();
- if (typeof props.onClick === 'function') {
- props.onClick({} as MouseEvent);
- }
- });
-
- expect(mockedProps.fetchData).toHaveBeenCalledWith(1);
- });
-
- it('disabled when query is last in list', () => {
- const mockedProps2 = {
- ...mockedProps,
- query: mockQueries[2],
- };
- const wrapper2 = mount(
- ,
- );
-
- expect(
- wrapper2.find('[data-test="next-query"]').first().props().disabled,
- ).toBe(true);
- });
- });
-
- describe('Open in SQL Lab button', () => {
- it('calls openInSqlLab prop', () => {
- const props = wrapper
- .find('[data-test="open-in-sql-lab"]')
- .first()
- .props();
-
- if (typeof props.onClick === 'function') {
- props.onClick({} as MouseEvent);
- }
-
- expect(mockedProps.openInSqlLab).toHaveBeenCalled();
- });
- });
-});
diff --git a/superset-frontend/src/features/queries/SavedQueryPreviewModal.test.jsx b/superset-frontend/src/features/queries/SavedQueryPreviewModal.test.jsx
deleted file mode 100644
index 3adac7f9f81..00000000000
--- a/superset-frontend/src/features/queries/SavedQueryPreviewModal.test.jsx
+++ /dev/null
@@ -1,136 +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.
- */
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import fetchMock from 'fetch-mock';
-import { styledMount as mount } from 'spec/helpers/theming';
-import Button from 'src/components/Button';
-import Modal from 'src/components/Modal';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { act } from 'spec/helpers/testing-library';
-import SavedQueryPreviewModal from './SavedQueryPreviewModal';
-
-// store needed for withToasts(DatabaseList)
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const mockqueries = [...new Array(3)].map((_, i) => ({
- created_by: {
- id: i,
- first_name: `user`,
- last_name: `${i}`,
- },
- created_on: `${i}-2020`,
- database: {
- database_name: `db ${i}`,
- id: i,
- },
- changed_on_delta_humanized: '1 day ago',
- db_id: i,
- description: `SQL for ${i}`,
- id: i,
- label: `query ${i}`,
- schema: 'public',
- sql: `SELECT ${i} FROM table`,
- sql_tables: [
- {
- catalog: null,
- schema: null,
- table: `${i}`,
- },
- ],
-}));
-
-const mockedProps = {
- fetchData: jest.fn(() => {}),
- openInSqlLab: jest.fn(() => {}),
- onHide: () => {},
- queries: mockqueries,
- savedQuery: mockqueries[1],
- show: true,
-};
-
-const FETCH_SAVED_QUERY_ENDPOINT = 'glob:*/api/v1/saved_query/*';
-const SAVED_QUERY_PAYLOAD = { result: mockqueries[1] };
-
-fetchMock.get(FETCH_SAVED_QUERY_ENDPOINT, SAVED_QUERY_PAYLOAD);
-
-async function mountAndWait(props = mockedProps) {
- const mounted = mount();
- await waitForComponentToPaint(mounted);
-
- return mounted;
-}
-
-describe('SavedQueryPreviewModal', () => {
- let wrapper;
-
- beforeAll(async () => {
- wrapper = await mountAndWait();
- });
-
- it('renders', () => {
- expect(wrapper.find(SavedQueryPreviewModal)).toBeTruthy();
- });
-
- it('renders a Modal', () => {
- expect(wrapper.find(Modal)).toBeTruthy();
- });
-
- it('renders sql from saved query', () => {
- expect(wrapper.find('pre').text()).toEqual('SELECT 1 FROM table');
- });
-
- it('renders buttons with correct text', () => {
- expect(wrapper.find(Button).contains('Previous')).toBe(true);
- expect(wrapper.find(Button).contains('Next')).toBe(true);
- expect(wrapper.find(Button).contains('Open in SQL Lab')).toBe(true);
- });
-
- it('handle next save query', () => {
- const button = wrapper.find('button[data-test="next-saved-query"]');
- expect(button.props().disabled).toBe(false);
- act(() => {
- button.props().onClick(false);
- });
- expect(mockedProps.fetchData).toHaveBeenCalled();
- expect(mockedProps.fetchData.mock.calls[0][0]).toEqual(2);
- });
-
- it('handle previous save query', () => {
- const button = wrapper
- .find('[data-test="previous-saved-query"]')
- .find(Button);
- expect(button.props().disabled).toBe(false);
- act(() => {
- button.props().onClick(true);
- });
- wrapper.update();
- expect(mockedProps.fetchData).toHaveBeenCalled();
- expect(mockedProps.fetchData.mock.calls[0][0]).toEqual(2);
- });
-
- it('handle open in sql lab', async () => {
- act(() => {
- wrapper.find('[data-test="open-in-sql-lab"]').first().props().onClick({});
- });
- expect(mockedProps.openInSqlLab).toHaveBeenCalled();
- expect(mockedProps.openInSqlLab.mock.calls[0][0]).toEqual(1);
- });
-});
diff --git a/superset-frontend/src/pages/AnnotationList/AnnotationList.test.jsx b/superset-frontend/src/pages/AnnotationList/AnnotationList.test.jsx
deleted file mode 100644
index 487f4484bfa..00000000000
--- a/superset-frontend/src/pages/AnnotationList/AnnotationList.test.jsx
+++ /dev/null
@@ -1,162 +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.
- */
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import fetchMock from 'fetch-mock';
-import { Provider } from 'react-redux';
-import { styledMount as mount } from 'spec/helpers/theming';
-
-import AnnotationList from 'src/pages/AnnotationList';
-import DeleteModal from 'src/components/DeleteModal';
-import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox';
-import ListView from 'src/components/ListView';
-import SubMenu from 'src/features/home/SubMenu';
-
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { act } from 'spec/helpers/testing-library';
-
-// store needed for withToasts(AnnotationList)
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const annotationsEndpoint = 'glob:*/api/v1/annotation_layer/*/annotation*';
-const annotationLayerEndpoint = 'glob:*/api/v1/annotation_layer/*';
-
-fetchMock.delete(annotationsEndpoint, {});
-
-const mockannotations = [...new Array(3)].map((_, i) => ({
- changed_on_delta_humanized: `${i} day(s) ago`,
- created_by: {
- first_name: `user`,
- id: i,
- },
- changed_by: {
- first_name: `user`,
- id: i,
- },
- end_dttm: new Date().toISOString,
- id: i,
- long_descr: `annotation ${i} description`,
- short_descr: `annotation ${i} label`,
- start_dttm: new Date().toISOString,
-}));
-
-fetchMock.get(annotationsEndpoint, {
- ids: [2, 0, 1],
- result: mockannotations,
- count: 3,
-});
-
-fetchMock.get(annotationLayerEndpoint, {
- id: 1,
- result: { descr: 'annotations test 0', name: 'Test 0' },
-});
-
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'), // use actual for all non-hook parts
- useParams: () => ({ annotationLayerId: '1' }),
-}));
-
-async function mountAndWait(props) {
- const mounted = mount(
-
-
- ,
- );
- await waitForComponentToPaint(mounted);
-
- return mounted;
-}
-
-describe('AnnotationList', () => {
- let wrapper;
-
- beforeAll(async () => {
- wrapper = await mountAndWait();
- });
-
- it('renders', () => {
- expect(wrapper.find(AnnotationList)).toBeTruthy();
- });
-
- it('renders a SubMenu', () => {
- expect(wrapper.find(SubMenu)).toBeTruthy();
- });
-
- it('renders a ListView', () => {
- expect(wrapper.find(ListView)).toBeTruthy();
- });
-
- it('fetches annotation layer', () => {
- const callsQ = fetchMock.calls(/annotation_layer\/1/);
- expect(callsQ).toHaveLength(2);
- expect(callsQ[1][0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/annotation_layer/1"`,
- );
- });
-
- it('fetches annotations', () => {
- const callsQ = fetchMock.calls(/annotation_layer\/1\/annotation/);
- expect(callsQ).toHaveLength(1);
- expect(callsQ[0][0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/annotation_layer/1/annotation/?q=(order_column:short_descr,order_direction:desc,page:0,page_size:25)"`,
- );
- });
-
- it('renders a DeleteModal', () => {
- expect(wrapper.find(DeleteModal)).toBeTruthy();
- });
-
- it('deletes', async () => {
- act(() => {
- wrapper.find('[data-test="delete-action"]').first().props().onClick();
- });
- await waitForComponentToPaint(wrapper);
-
- expect(
- wrapper.find(DeleteModal).first().props().description,
- ).toMatchInlineSnapshot(
- `"Are you sure you want to delete annotation 0 label?"`,
- );
-
- act(() => {
- wrapper
- .find('#delete')
- .first()
- .props()
- .onChange({ target: { value: 'DELETE' } });
- });
- await waitForComponentToPaint(wrapper);
- act(() => {
- wrapper.find('button').last().props().onClick();
- });
- await waitForComponentToPaint(wrapper);
- });
-
- it('shows/hides bulk actions when bulk actions is clicked', async () => {
- const button = wrapper.find('[data-test="annotation-bulk-select"]').first();
- act(() => {
- button.props().onClick();
- });
- await waitForComponentToPaint(wrapper);
- expect(wrapper.find(IndeterminateCheckbox)).toHaveLength(
- mockannotations.length + 1, // 1 for each row and 1 for select all
- );
- });
-});
diff --git a/superset-frontend/src/pages/DatabaseList/DatabaseList.test.jsx b/superset-frontend/src/pages/DatabaseList/DatabaseList.test.jsx
deleted file mode 100644
index e81020e3986..00000000000
--- a/superset-frontend/src/pages/DatabaseList/DatabaseList.test.jsx
+++ /dev/null
@@ -1,248 +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.src/pages/DatabaseList/DatabaseList.test.jsx
- */
-import thunk from 'redux-thunk';
-import * as reactRedux from 'react-redux';
-import configureStore from 'redux-mock-store';
-import fetchMock from 'fetch-mock';
-import { Provider } from 'react-redux';
-import { styledMount as mount } from 'spec/helpers/theming';
-
-import DatabaseList from 'src/pages/DatabaseList';
-import DatabaseModal from 'src/features/databases/DatabaseModal';
-import DeleteModal from 'src/components/DeleteModal';
-import SubMenu from 'src/features/home/SubMenu';
-import ListView from 'src/components/ListView';
-import Filters from 'src/components/ListView/Filters';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { act } from 'spec/helpers/testing-library';
-
-// store needed for withToasts(DatabaseList)
-
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const databasesInfoEndpoint = 'glob:*/api/v1/database/_info*';
-const databasesEndpoint = 'glob:*/api/v1/database/?*';
-const databaseEndpoint = 'glob:*/api/v1/database/*';
-const databaseRelatedEndpoint = 'glob:*/api/v1/database/*/related_objects*';
-
-const mockdatabases = [...new Array(3)].map((_, i) => ({
- changed_by: {
- first_name: `user`,
- last_name: `${i}`,
- },
- database_name: `db ${i}`,
- backend: 'postgresql',
- allow_run_async: true,
- allow_dml: false,
- allow_file_upload: true,
- expose_in_sqllab: false,
- changed_on_delta_humanized: `${i} day(s) ago`,
- changed_on: new Date().toISOString,
- id: i,
-}));
-
-jest.mock('react-redux', () => ({
- ...jest.requireActual('react-redux'),
- useSelector: jest.fn(),
-}));
-
-fetchMock.get(databasesInfoEndpoint, {
- permissions: ['can_write'],
-});
-fetchMock.get(databasesEndpoint, {
- result: mockdatabases,
- database_count: 3,
-});
-
-fetchMock.delete(databaseEndpoint, {});
-fetchMock.get(databaseRelatedEndpoint, {
- charts: {
- count: 0,
- result: [],
- },
- dashboards: {
- count: 0,
- result: [],
- },
- sqllab_tab_states: {
- count: 0,
- result: [],
- },
-});
-
-fetchMock.get(
- 'glob:*api/v1/database/?q=(filters:!((col:allow_file_upload,opr:upload_is_enabled,value:!t)))',
- {},
-);
-
-const useSelectorMock = jest.spyOn(reactRedux, 'useSelector');
-const userSelectorMock = jest.spyOn(reactRedux, 'useSelector');
-
-describe('Admin DatabaseList', () => {
- useSelectorMock.mockReturnValue({
- CSV_EXTENSIONS: ['csv'],
- EXCEL_EXTENSIONS: ['xls', 'xlsx'],
- COLUMNAR_EXTENSIONS: ['parquet', 'zip'],
- ALLOWED_EXTENSIONS: ['parquet', 'zip', 'xls', 'xlsx', 'csv'],
- });
- userSelectorMock.mockReturnValue({
- createdOn: '2021-04-27T18:12:38.952304',
- email: 'admin',
- firstName: 'admin',
- isActive: true,
- lastName: 'admin',
- permissions: {},
- roles: {
- Admin: [
- ['can_sqllab', 'Superset'],
- ['can_write', 'Dashboard'],
- ['can_write', 'Chart'],
- ],
- },
- userId: 1,
- username: 'admin',
- });
-
- const wrapper = mount(
-
-
- ,
- );
-
- beforeAll(async () => {
- await waitForComponentToPaint(wrapper);
- });
-
- test('renders', () => {
- expect(wrapper.find(DatabaseList)).toBeTruthy();
- });
-
- test('renders a SubMenu', () => {
- expect(wrapper.find(SubMenu)).toBeTruthy();
- });
-
- test('renders a SubMenu with no tabs', () => {
- expect(wrapper.find(SubMenu).props().tabs).toBeUndefined();
- });
-
- test('renders a DatabaseModal', () => {
- expect(wrapper.find(DatabaseModal)).toBeTruthy();
- });
-
- test('renders a ListView', () => {
- expect(wrapper.find(ListView)).toBeTruthy();
- });
-
- test('fetches Databases', () => {
- const callsD = fetchMock.calls(/database\/\?q/);
- expect(callsD).toHaveLength(2);
- expect(callsD[0][0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/database/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25)"`,
- );
- });
-
- test('deletes', async () => {
- act(() => {
- wrapper.find('[data-test="database-delete"]').first().props().onClick();
- });
- await waitForComponentToPaint(wrapper);
-
- expect(wrapper.find(DeleteModal).props().description).toMatchSnapshot();
-
- act(() => {
- wrapper
- .find('#delete')
- .first()
- .props()
- .onChange({ target: { value: 'DELETE' } });
- });
- await waitForComponentToPaint(wrapper);
- act(() => {
- wrapper
- .find({ 'data-test': 'modal-confirm-button' })
- .last()
- .props()
- .onClick();
- });
-
- await waitForComponentToPaint(wrapper);
-
- expect(fetchMock.calls(/database\/0\/related_objects/, 'GET')).toHaveLength(
- 1,
- );
- expect(fetchMock.calls(/database\/0/, 'DELETE')).toHaveLength(1);
- });
-
- test('filters', async () => {
- const filtersWrapper = wrapper.find(Filters);
- act(() => {
- filtersWrapper
- .find('[name="expose_in_sqllab"]')
- .first()
- .props()
- .onSelect({ label: 'Yes', value: true });
-
- filtersWrapper
- .find('[name="allow_run_async"]')
- .first()
- .props()
- .onSelect({ label: 'Yes', value: false });
-
- filtersWrapper
- .find('[name="database_name"]')
- .first()
- .props()
- .onSubmit('fooo');
- });
- await waitForComponentToPaint(wrapper);
-
- expect(fetchMock.lastCall()[0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/database/?q=(filters:!((col:database_name,opr:ct,value:fooo),(col:expose_in_sqllab,opr:eq,value:!t),(col:allow_run_async,opr:eq,value:!f)),order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25)"`,
- );
- });
-
- test('should not render dropdown menu button if user is not admin', async () => {
- userSelectorMock.mockReturnValue({
- createdOn: '2021-05-27T18:12:38.952304',
- email: 'alpha@gmail.com',
- firstName: 'alpha',
- isActive: true,
- lastName: 'alpha',
- permissions: {},
- roles: {
- Alpha: [
- ['can_sqllab', 'Superset'],
- ['can_write', 'Dashboard'],
- ['can_write', 'Chart'],
- ],
- },
- userId: 2,
- username: 'alpha',
- });
- const newWrapper = mount(
-
-
- ,
- );
- await waitForComponentToPaint(newWrapper);
-
- expect(newWrapper.find('.dropdown-menu-links').length).toBe(0);
- });
-});
diff --git a/superset-frontend/src/pages/DatabaseList/__snapshots__/DatabaseList.test.jsx.snap b/superset-frontend/src/pages/DatabaseList/__snapshots__/DatabaseList.test.jsx.snap
deleted file mode 100644
index c4f6ebc9659..00000000000
--- a/superset-frontend/src/pages/DatabaseList/__snapshots__/DatabaseList.test.jsx.snap
+++ /dev/null
@@ -1,15 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Admin DatabaseList deletes 1`] = `
-
-
- The database
-
-
- db 0
-
-
- is linked to 0 charts that appear on 0 dashboards and users have 0 SQL Lab tabs using this database open. Are you sure you want to continue? Deleting the database will break those objects.
-
-
-`;
diff --git a/superset-frontend/src/pages/DatasetList/DatasetList.test.tsx b/superset-frontend/src/pages/DatasetList/DatasetList.test.tsx
deleted file mode 100644
index 0253f6074b6..00000000000
--- a/superset-frontend/src/pages/DatasetList/DatasetList.test.tsx
+++ /dev/null
@@ -1,331 +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.
- */
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import fetchMock from 'fetch-mock';
-import { Provider } from 'react-redux';
-import { styledMount as mount } from 'spec/helpers/theming';
-import {
- act,
- cleanup,
- render,
- screen,
- userEvent,
-} from 'spec/helpers/testing-library';
-import { isFeatureEnabled } from '@superset-ui/core';
-import { QueryParamProvider } from 'use-query-params';
-
-import DatasetList from 'src/pages/DatasetList';
-import ListView from 'src/components/ListView';
-import Button from 'src/components/Button';
-import IndeterminateCheckbox from 'src/components/IndeterminateCheckbox';
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import SubMenu from 'src/features/home/SubMenu';
-import * as reactRedux from 'react-redux';
-
-jest.mock('@superset-ui/core', () => ({
- ...jest.requireActual('@superset-ui/core'),
- isFeatureEnabled: jest.fn(),
-}));
-
-const mockedIsFeatureEnabled = isFeatureEnabled as jest.Mock;
-
-// store needed for withToasts(DatasetList)
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const datasetsInfoEndpoint = 'glob:*/api/v1/dataset/_info*';
-const datasetsOwnersEndpoint = 'glob:*/api/v1/dataset/related/owners*';
-const datasetsSchemaEndpoint = 'glob:*/api/v1/dataset/distinct/schema*';
-const datasetsDuplicateEndpoint = 'glob:*/api/v1/dataset/duplicate*';
-const databaseEndpoint = 'glob:*/api/v1/dataset/related/database*';
-const datasetsEndpoint = 'glob:*/api/v1/dataset/?*';
-
-const useSelectorMock = jest.spyOn(reactRedux, 'useSelector');
-
-const mockdatasets = [...new Array(3)].map((_, i) => ({
- changed_by_name: 'user',
- kind: i === 0 ? 'virtual' : 'physical', // ensure there is 1 virtual
- changed_by: 'user',
- changed_on: new Date().toISOString(),
- database_name: `db ${i}`,
- explore_url: `https://www.google.com?${i}`,
- id: i,
- schema: `schema ${i}`,
- table_name: `coolest table ${i}`,
- owners: [{ username: 'admin', userId: 1 }],
-}));
-
-const mockUser = {
- userId: 1,
-};
-
-fetchMock.get(datasetsInfoEndpoint, {
- permissions: ['can_read', 'can_write', 'can_duplicate'],
-});
-fetchMock.get(datasetsOwnersEndpoint, {
- result: [],
-});
-fetchMock.get(datasetsSchemaEndpoint, {
- result: [],
-});
-fetchMock.post(datasetsDuplicateEndpoint, {
- result: [],
-});
-fetchMock.get(datasetsEndpoint, {
- result: mockdatasets,
- dataset_count: 3,
-});
-fetchMock.get(databaseEndpoint, {
- result: [],
-});
-
-async function mountAndWait(props: {}) {
- const mounted = mount(
-
-
- ,
- );
- await waitForComponentToPaint(mounted);
-
- return mounted;
-}
-
-describe('DatasetList', () => {
- const mockedProps = {};
- let wrapper: any;
-
- beforeAll(async () => {
- wrapper = await mountAndWait(mockedProps);
- });
-
- it('renders', () => {
- expect(wrapper.find(DatasetList)).toBeTruthy();
- });
-
- it('renders a ListView', () => {
- expect(wrapper.find(ListView)).toBeTruthy();
- });
-
- it('fetches info', () => {
- const callsI = fetchMock.calls(/dataset\/_info/);
- expect(callsI).toHaveLength(1);
- });
-
- it('fetches data', () => {
- const callsD = fetchMock.calls(/dataset\/\?q/);
- expect(callsD).toHaveLength(1);
- expect(callsD[0][0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/dataset/?q=(order_column:changed_on_delta_humanized,order_direction:desc,page:0,page_size:25)"`,
- );
- });
-
- it('does not fetch owner filter values on mount', async () => {
- await waitForComponentToPaint(wrapper);
- expect(fetchMock.calls(/dataset\/related\/owners/)).toHaveLength(0);
- });
-
- it('does not fetch schema filter values on mount', async () => {
- await waitForComponentToPaint(wrapper);
- expect(fetchMock.calls(/dataset\/distinct\/schema/)).toHaveLength(0);
- });
-
- it('shows/hides bulk actions when bulk actions is clicked', async () => {
- await waitForComponentToPaint(wrapper);
- const button = wrapper.find(Button).at(0);
- act(() => {
- button.props().onClick();
- });
- await waitForComponentToPaint(wrapper);
- expect(wrapper.find(IndeterminateCheckbox)).toHaveLength(
- mockdatasets.length + 1, // 1 for each row and 1 for select all
- );
- });
-
- it('renders different bulk selected copy depending on type of row selected', async () => {
- // None selected
- const checkedEvent = { target: { checked: true } };
- const uncheckedEvent = { target: { checked: false } };
- expect(
- wrapper.find('[data-test="bulk-select-copy"]').text(),
- ).toMatchInlineSnapshot(`"0 Selected"`);
-
- // Virtual Selected
- act(() => {
- wrapper.find(IndeterminateCheckbox).at(1).props().onChange(checkedEvent);
- });
- await waitForComponentToPaint(wrapper);
- expect(
- wrapper.find('[data-test="bulk-select-copy"]').text(),
- ).toMatchInlineSnapshot(`"1 Selected (Virtual)"`);
-
- // Physical Selected
- act(() => {
- wrapper
- .find(IndeterminateCheckbox)
- .at(1)
- .props()
- .onChange(uncheckedEvent);
- wrapper.find(IndeterminateCheckbox).at(2).props().onChange(checkedEvent);
- });
- await waitForComponentToPaint(wrapper);
- expect(
- wrapper.find('[data-test="bulk-select-copy"]').text(),
- ).toMatchInlineSnapshot(`"1 Selected (Physical)"`);
-
- // All Selected
- act(() => {
- wrapper.find(IndeterminateCheckbox).at(0).props().onChange(checkedEvent);
- });
- await waitForComponentToPaint(wrapper);
- expect(
- wrapper.find('[data-test="bulk-select-copy"]').text(),
- ).toMatchInlineSnapshot(`"3 Selected (2 Physical, 1 Virtual)"`);
- });
-
- it('shows duplicate modal when duplicate action is clicked', async () => {
- await waitForComponentToPaint(wrapper);
- expect(
- wrapper.find('[data-test="duplicate-modal-input"]').exists(),
- ).toBeFalsy();
- act(() => {
- wrapper
- .find('#duplicate-action-tooltip')
- .at(0)
- .find('.action-button')
- .props()
- .onClick();
- });
- await waitForComponentToPaint(wrapper);
- expect(
- wrapper.find('[data-test="duplicate-modal-input"]').exists(),
- ).toBeTruthy();
- });
-
- it('calls the duplicate endpoint', async () => {
- await waitForComponentToPaint(wrapper);
- await act(async () => {
- wrapper
- .find('#duplicate-action-tooltip')
- .at(0)
- .find('.action-button')
- .props()
- .onClick();
- await waitForComponentToPaint(wrapper);
- wrapper
- .find('[data-test="duplicate-modal-input"]')
- .at(0)
- .props()
- .onPressEnter();
- });
- expect(fetchMock.calls(/dataset\/duplicate/)).toHaveLength(1);
- });
-
- it('renders a SubMenu', () => {
- expect(wrapper.find(SubMenu)).toBeTruthy();
- });
-
- it('renders a SubMenu with no tabs', () => {
- expect(wrapper.find(SubMenu).props().tabs).toBeUndefined();
- });
-});
-
-jest.mock('react-router-dom', () => ({
- ...jest.requireActual('react-router-dom'),
- useLocation: () => ({}),
- useHistory: () => ({}),
-}));
-
-describe('RTL', () => {
- async function renderAndWait() {
- const mounted = act(async () => {
- const mockedProps = {};
- render(
-
-
- ,
- { useRedux: true, useRouter: true },
- );
- });
-
- return mounted;
- }
-
- beforeEach(async () => {
- mockedIsFeatureEnabled.mockReturnValue(true);
- await renderAndWait();
- });
-
- afterEach(() => {
- cleanup();
- mockedIsFeatureEnabled.mockRestore();
- });
-
- it('renders an "Import Dataset" tooltip under import button', async () => {
- const importButton = await screen.findByTestId('import-button');
- userEvent.hover(importButton);
-
- await screen.findByRole('tooltip');
- const importTooltip = screen.getByRole('tooltip', {
- name: 'Import datasets',
- });
-
- expect(importTooltip).toBeInTheDocument();
- });
-});
-
-describe('Prevent unsafe URLs', () => {
- const columnCount = 8;
- const exploreUrlIndex = 1;
- const getTdIndex = (rowNumber: number): number =>
- rowNumber * columnCount + exploreUrlIndex;
-
- const mockedProps = {};
- let wrapper: any;
-
- it('Check prevent unsafe is on renders relative links', async () => {
- useSelectorMock.mockReturnValue(true);
- wrapper = await mountAndWait(mockedProps);
- const tdElements = wrapper.find(ListView).find('td');
- expect(tdElements.at(getTdIndex(0)).find('a').prop('href')).toBe(
- '/https://www.google.com?0',
- );
- expect(tdElements.at(getTdIndex(1)).find('a').prop('href')).toBe(
- '/https://www.google.com?1',
- );
- expect(tdElements.at(getTdIndex(2)).find('a').prop('href')).toBe(
- '/https://www.google.com?2',
- );
- });
-
- it('Check prevent unsafe is off renders absolute links', async () => {
- useSelectorMock.mockReturnValue(false);
- wrapper = await mountAndWait(mockedProps);
- const tdElements = wrapper.find(ListView).find('td');
- expect(tdElements.at(getTdIndex(0)).find('a').prop('href')).toBe(
- 'https://www.google.com?0',
- );
- expect(tdElements.at(getTdIndex(1)).find('a').prop('href')).toBe(
- 'https://www.google.com?1',
- );
- expect(tdElements.at(getTdIndex(2)).find('a').prop('href')).toBe(
- 'https://www.google.com?2',
- );
- });
-});
diff --git a/superset-frontend/src/pages/QueryHistoryList/QueryHistoryList.test.tsx b/superset-frontend/src/pages/QueryHistoryList/QueryHistoryList.test.tsx
deleted file mode 100644
index 0afe5ad1ced..00000000000
--- a/superset-frontend/src/pages/QueryHistoryList/QueryHistoryList.test.tsx
+++ /dev/null
@@ -1,174 +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.
- */
-import { MouseEvent } from 'react';
-import thunk from 'redux-thunk';
-import configureStore from 'redux-mock-store';
-import { Provider } from 'react-redux';
-import fetchMock from 'fetch-mock';
-import { act } from 'spec/helpers/testing-library';
-
-import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
-import { styledMount as mount } from 'spec/helpers/theming';
-
-import QueryList from 'src/pages/QueryHistoryList';
-import QueryPreviewModal from 'src/features/queries/QueryPreviewModal';
-import { QueryObject } from 'src/views/CRUD/types';
-import ListView from 'src/components/ListView';
-import Filters from 'src/components/ListView/Filters';
-import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
-import SubMenu from 'src/features/home/SubMenu';
-import { QueryState } from '@superset-ui/core';
-
-// store needed for withToasts
-const mockStore = configureStore([thunk]);
-const store = mockStore({});
-
-const queriesEndpoint = 'glob:*/api/v1/query/?*';
-
-const mockQueries: QueryObject[] = [...new Array(3)].map((_, i) => ({
- changed_on: new Date().toISOString(),
- id: i,
- slice_name: `cool chart ${i}`,
- database: {
- database_name: 'main db',
- },
- schema: 'public',
- sql: `SELECT ${i} FROM table`,
- executed_sql: `SELECT ${i} FROM table`,
- sql_tables: [
- { schema: 'foo', table: 'table' },
- { schema: 'bar', table: 'table_2' },
- ],
- status: QueryState.Success,
- tab_name: 'Main Tab',
- user: {
- first_name: 'cool',
- last_name: 'dude',
- id: 2,
- username: 'cooldude',
- },
- start_time: new Date().valueOf(),
- end_time: new Date().valueOf(),
- rows: 200,
- tmp_table_name: '',
- tracking_url: '',
-}));
-
-fetchMock.get(queriesEndpoint, {
- result: mockQueries,
- chart_count: 3,
-});
-
-fetchMock.get('glob:*/api/v1/query/related/user*', {
- result: [],
- count: 0,
-});
-fetchMock.get('glob:*/api/v1/query/related/database*', {
- result: [],
- count: 0,
-});
-fetchMock.get('glob:*/api/v1/query/disting/status*', {
- result: [],
- count: 0,
-});
-
-describe('QueryList', () => {
- const mockedProps = {};
- const wrapper = mount(
-
-
- ,
- {
- context: { store },
- },
- );
-
- beforeAll(async () => {
- await waitForComponentToPaint(wrapper);
- });
-
- it('renders', () => {
- expect(wrapper.find(QueryList)).toBeTruthy();
- });
-
- it('renders a ListView', () => {
- expect(wrapper.find(ListView)).toBeTruthy();
- });
-
- it('fetches data', () => {
- wrapper.update();
- const callsD = fetchMock.calls(/query\/\?q/);
- expect(callsD).toHaveLength(1);
- expect(callsD[0][0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/query/?q=(order_column:start_time,order_direction:desc,page:0,page_size:25)"`,
- );
- });
-
- it('renders a SyntaxHighlight', () => {
- expect(wrapper.find(SyntaxHighlighter)).toBeTruthy();
- });
-
- it('opens a query preview', () => {
- act(() => {
- const props = wrapper
- .find('[data-test="open-sql-preview-0"]')
- .first()
- .props();
- if (props.onClick) props.onClick({} as MouseEvent);
- });
- wrapper.update();
-
- expect(wrapper.find(QueryPreviewModal)).toBeTruthy();
- });
-
- it('searches', async () => {
- const filtersWrapper = wrapper.find(Filters);
- act(() => {
- const props = filtersWrapper.find('[name="sql"]').first().props();
- // @ts-ignore
- if (props.onSubmit) props.onSubmit('fooo');
- });
- await waitForComponentToPaint(wrapper);
- expect((fetchMock.lastCall() ?? [])[0]).toMatchInlineSnapshot(
- `"http://localhost/api/v1/query/?q=(filters:!((col:sql,opr:ct,value:fooo)),order_column:start_time,order_direction:desc,page:0,page_size:25)"`,
- );
- });
-
- it('renders a SubMenu', () => {
- expect(wrapper.find(SubMenu)).toBeTruthy();
- });
-
- it('renders a SubMenu with Saved queries and Query History links', () => {
- expect(wrapper.find(SubMenu).props().tabs).toEqual(
- expect.arrayContaining([
- expect.objectContaining({ label: 'Saved queries' }),
- expect.objectContaining({ label: 'Query history' }),
- ]),
- );
- });
-
- it('renders a SubMenu without Databases and Datasets links', () => {
- expect(wrapper.find(SubMenu).props().tabs).not.toEqual(
- expect.arrayContaining([
- expect.objectContaining({ label: 'Databases' }),
- expect.objectContaining({ label: 'Datasets' }),
- ]),
- );
- });
-});