mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 17:58:43 -05:00
test: Migration to jest (#935)
* jest initialised * refactor: `connect()` and `openApp()` * test: integrate to jest * chore: renaming jests test commands * chore: adding override rule for non `commands/serve` directories to skip jest rules
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true
|
||||
"browser": true,
|
||||
"jest/globals": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
},
|
||||
"extends": ["airbnb", "prettier"],
|
||||
"plugins": ["prettier"],
|
||||
"plugins": ["prettier", "jest"],
|
||||
"rules": {
|
||||
"max-len": 0,
|
||||
"no-plusplus": 0,
|
||||
@@ -18,12 +19,24 @@
|
||||
"react/prop-types": 0,
|
||||
"react/no-deprecated": 0,
|
||||
"import/no-extraneous-dependencies": [2, { "devDependencies": true }],
|
||||
"import/no-dynamic-require": 0
|
||||
"import/no-dynamic-require": 0,
|
||||
"jest/no-disabled-tests": "warn",
|
||||
"jest/no-focused-tests": "error",
|
||||
"jest/no-identical-title": "error",
|
||||
"jest/prefer-to-have-length": "warn",
|
||||
"jest/valid-expect": "error"
|
||||
},
|
||||
"globals": {
|
||||
"__NEBULA_DEV__": false
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["apis/**/*", "packages/**/*", "commands/create/**/*", "commands/sense/src/**/*"],
|
||||
"rules": {
|
||||
"jest/valid-expect": 0,
|
||||
"jest/no-identical-title": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["scripts/**/*", "**/apis/*/scripts/**/*"],
|
||||
"rules": {
|
||||
|
||||
@@ -2,15 +2,7 @@ module.exports = {
|
||||
env: {
|
||||
test: {
|
||||
presets: [['@babel/preset-env', { targets: { node: 'current' } }]],
|
||||
plugins: [
|
||||
['@babel/plugin-transform-react-jsx'],
|
||||
[
|
||||
'istanbul',
|
||||
{
|
||||
exclude: ['**/test/**', '**/__test__/**', '**/dist/**'],
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: ['@babel/plugin-transform-react-jsx'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ import Step from '@mui/material/Step';
|
||||
import StepLabel from '@mui/material/StepLabel';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
|
||||
import { info as connectionInfo, connect } from '../connect';
|
||||
import { getConnectionInfo, connect } from '../connect';
|
||||
import storageFn from '../storage';
|
||||
|
||||
const storage = storageFn({});
|
||||
@@ -268,7 +268,7 @@ export default function Hub() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
connectionInfo.then((i) => {
|
||||
getConnectionInfo().then((i) => {
|
||||
if (i.enigma.appId) {
|
||||
window.location.href = `/dev/${window.location.search}`;
|
||||
return;
|
||||
|
||||
@@ -61,51 +61,37 @@ const parseEngineURL = (url) => {
|
||||
};
|
||||
};
|
||||
|
||||
const connectionInfo = fetch('/info')
|
||||
.then((response) => response.json())
|
||||
.then(async (n) => {
|
||||
let info = n;
|
||||
if (params.engine_url) {
|
||||
info = {
|
||||
const getConnectionInfo = () =>
|
||||
fetch('/info')
|
||||
.then((response) => response.json())
|
||||
.then(async (n) => {
|
||||
let info = n;
|
||||
if (params.engine_url) {
|
||||
info = {
|
||||
...info,
|
||||
...parseEngineURL(params.engine_url),
|
||||
};
|
||||
} else if (params.app) {
|
||||
info = {
|
||||
...info,
|
||||
enigma: {
|
||||
...info.enigma,
|
||||
appId: params.app,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (params['qlik-web-integration-id']) {
|
||||
info.webIntegrationId = params['qlik-web-integration-id'];
|
||||
}
|
||||
if (info.invalid) {
|
||||
return info;
|
||||
}
|
||||
const rootPath = `${info.enigma.secure ? 'https' : 'http'}://${info.enigma.host}`;
|
||||
return {
|
||||
...info,
|
||||
...parseEngineURL(params.engine_url),
|
||||
rootPath,
|
||||
};
|
||||
} else if (params.app) {
|
||||
info = {
|
||||
...info,
|
||||
enigma: {
|
||||
...info.enigma,
|
||||
appId: params.app,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (params['qlik-web-integration-id']) {
|
||||
info.webIntegrationId = params['qlik-web-integration-id'];
|
||||
}
|
||||
if (info.invalid) {
|
||||
return info;
|
||||
}
|
||||
const rootPath = `${info.enigma.secure ? 'https' : 'http'}://${info.enigma.host}`;
|
||||
return {
|
||||
...info,
|
||||
rootPath,
|
||||
};
|
||||
});
|
||||
|
||||
let headers;
|
||||
|
||||
const getHeaders = (authInstance) => {
|
||||
if (!authInstance) return 401;
|
||||
headers = {
|
||||
'qlik-web-integration-id': authInstance.config.webIntegrationId,
|
||||
'qlik-csrf-token': authInstance.config.csrfToken,
|
||||
};
|
||||
return headers;
|
||||
};
|
||||
|
||||
const defaultConfig = {
|
||||
secure: false,
|
||||
};
|
||||
});
|
||||
|
||||
const getAuthInstance = ({ webIntegrationId, host }) => {
|
||||
const authInstance = new Auth({
|
||||
@@ -118,69 +104,73 @@ const getAuthInstance = ({ webIntegrationId, host }) => {
|
||||
return authInstance;
|
||||
};
|
||||
|
||||
let connection;
|
||||
const connect = () => {
|
||||
if (!connection) {
|
||||
connection = connectionInfo.then(({ webIntegrationId, enigma: enigmaInfo, enigma: { host } }) => {
|
||||
if (webIntegrationId) {
|
||||
const authInstance = getAuthInstance({ webIntegrationId, host });
|
||||
if (!headers) headers = getHeaders(authInstance);
|
||||
if (headers === 401) return { status: 401 };
|
||||
const connect = async () => {
|
||||
try {
|
||||
const {
|
||||
webIntegrationId,
|
||||
enigma: enigmaInfo,
|
||||
enigma: { host },
|
||||
} = await getConnectionInfo();
|
||||
|
||||
return {
|
||||
getDocList: async () => {
|
||||
const url = `/items?resourceType=app&limit=30&sort=-updatedAt`;
|
||||
const { data = [] } = await (await authInstance.rest(url)).json();
|
||||
return data.map((d) => ({
|
||||
qDocId: d.resourceId,
|
||||
qTitle: d.name,
|
||||
}));
|
||||
},
|
||||
getConfiguration: async () => ({}),
|
||||
};
|
||||
}
|
||||
|
||||
const url = SenseUtilities.buildUrl({
|
||||
...defaultConfig,
|
||||
...enigmaInfo,
|
||||
});
|
||||
|
||||
return enigma
|
||||
.create({
|
||||
schema: qixSchema,
|
||||
url,
|
||||
})
|
||||
.open();
|
||||
});
|
||||
}
|
||||
|
||||
return connection;
|
||||
};
|
||||
|
||||
const openApp = (id) =>
|
||||
connectionInfo.then(async ({ webIntegrationId, enigma: enigmaInfo, enigma: { host } }) => {
|
||||
let urlParams = {};
|
||||
if (webIntegrationId) {
|
||||
const authInstance = getAuthInstance({ webIntegrationId, host });
|
||||
|
||||
if (!headers) headers = getHeaders(authInstance);
|
||||
urlParams = { ...headers };
|
||||
return {
|
||||
getDocList: async () => {
|
||||
const url = `/items?resourceType=app&limit=30&sort=-updatedAt`;
|
||||
const { data = [] } = await (await authInstance.rest(url)).json();
|
||||
return data.map((d) => ({
|
||||
qDocId: d.resourceId,
|
||||
qTitle: d.name,
|
||||
}));
|
||||
},
|
||||
getConfiguration: async () => ({}),
|
||||
};
|
||||
}
|
||||
const url = SenseUtilities.buildUrl({
|
||||
secure: false,
|
||||
...enigmaInfo,
|
||||
});
|
||||
|
||||
return enigma
|
||||
.create({
|
||||
schema: qixSchema,
|
||||
url,
|
||||
})
|
||||
.open();
|
||||
} catch (error) {
|
||||
throw new Error('Failed to return enigma instance');
|
||||
}
|
||||
};
|
||||
|
||||
const openApp = async (id) => {
|
||||
try {
|
||||
const {
|
||||
webIntegrationId,
|
||||
enigma: enigmaInfo,
|
||||
enigma: { host },
|
||||
} = await getConnectionInfo();
|
||||
|
||||
if (webIntegrationId) {
|
||||
const authInstance = getAuthInstance({ webIntegrationId, host });
|
||||
const url = await authInstance.generateWebsocketUrl(id);
|
||||
const enigmaGlobal = await enigma.create({ schema: qixSchema, url }).open();
|
||||
return enigmaGlobal.openDoc(id);
|
||||
}
|
||||
|
||||
const url = SenseUtilities.buildUrl({
|
||||
...defaultConfig,
|
||||
secure: false,
|
||||
...enigmaInfo,
|
||||
urlParams,
|
||||
urlParams: {},
|
||||
appId: id,
|
||||
});
|
||||
return enigma
|
||||
.create({ schema: qixSchema, url })
|
||||
.open()
|
||||
.then((global) => global.openDoc(id));
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error('Failed to open app!');
|
||||
}
|
||||
};
|
||||
|
||||
export { connect, openApp, params, connectionInfo as info };
|
||||
export { connect, openApp, params, getConnectionInfo, getAuthInstance };
|
||||
|
||||
@@ -3,10 +3,10 @@ import ReactDOM from 'react-dom';
|
||||
|
||||
import App from './components/App';
|
||||
|
||||
import { openApp, info } from './connect';
|
||||
import { openApp, getConnectionInfo } from './connect';
|
||||
import initiateWatch from './hot';
|
||||
|
||||
info.then(($) => {
|
||||
getConnectionInfo().then(($) => {
|
||||
if (!$.enigma.appId) {
|
||||
window.location.href = `/${window.location.search}`;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { embed } from '@nebula.js/stardust';
|
||||
import snapshooter from '@nebula.js/snapshooter/client';
|
||||
|
||||
import { openApp, params, info as serverInfo } from './connect';
|
||||
import { openApp, params, getConnectionInfo } from './connect';
|
||||
import initiateWatch from './hot';
|
||||
import renderFixture from './render-fixture';
|
||||
|
||||
@@ -31,7 +31,7 @@ const nuke = async ({ app, supernova: { name }, themes, theme, language }) => {
|
||||
};
|
||||
|
||||
async function renderWithEngine() {
|
||||
const info = await serverInfo;
|
||||
const info = await getConnectionInfo();
|
||||
initiateWatch(info);
|
||||
if (!info.enigma.appId) {
|
||||
location.href = location.origin; //eslint-disable-line
|
||||
@@ -79,7 +79,7 @@ async function renderWithEngine() {
|
||||
}
|
||||
|
||||
async function renderSnapshot() {
|
||||
const info = await serverInfo;
|
||||
const info = await getConnectionInfo();
|
||||
const { themes, supernova } = info;
|
||||
initiateWatch(info);
|
||||
const element = document.querySelector('#chart-container');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { embed } from '@nebula.js/stardust';
|
||||
import EnigmaMocker from '@nebula.js/enigma-mocker';
|
||||
import extend from 'extend';
|
||||
import { info as getServerInfo } from './connect';
|
||||
import { getConnectionInfo } from './connect';
|
||||
import { getModule } from './hot';
|
||||
|
||||
const getDefaultGenericObject = ({ type }) => ({
|
||||
@@ -101,7 +101,7 @@ function getQId(genericObjects = []) {
|
||||
|
||||
const renderFixture = async (params) => {
|
||||
const element = document.querySelector('#chart-container');
|
||||
const serverInfo = await getServerInfo;
|
||||
const serverInfo = await getConnectionInfo();
|
||||
const fixture = await getFixture(params.fixture);
|
||||
const { type, load, genericObjects, instanceConfig, snConfig } = await getOptions({ fixture, params, serverInfo });
|
||||
const mockedApp = await EnigmaMocker.fromGenericObjects(genericObjects);
|
||||
|
||||
16
jest.config.js
Normal file
16
jest.config.js
Normal file
@@ -0,0 +1,16 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
testEnvironment: 'jest-environment-jsdom',
|
||||
testRegex: ['commands/serve/web/.+\\.(test|spec)\\.[jt]sx?$'],
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
|
||||
collectCoverageFrom: [
|
||||
'commands/serve/web/**/*.{js,jsx}',
|
||||
'!commands/serve/web/**/*.spec.{js,jsx}',
|
||||
'!commands/serve/web/**/*.test.{js,jsx}',
|
||||
'!commands/serve/web/**/__tests__/**/*',
|
||||
|
||||
'!**/dist/**',
|
||||
'!**/node_modules/**',
|
||||
],
|
||||
coverageReporters: ['json', 'lcov', 'text-summary', 'clover'],
|
||||
};
|
||||
2
jest.setup.js
Normal file
2
jest.setup.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import '@testing-library/jest-dom';
|
||||
import 'whatwg-fetch';
|
||||
14
package.json
14
package.json
@@ -15,6 +15,9 @@
|
||||
"build-storybook": "build-storybook",
|
||||
"spec": "lerna run spec --stream --concurrency 99 && lerna run ts --stream --concurrency 99 ",
|
||||
"test": "yarn run test:unit",
|
||||
"test:jest": "jest",
|
||||
"test:jest:watch": "jest --watch",
|
||||
"test:jest:coverage": "jest --coverage",
|
||||
"mashup": "node scripts/start-mashup.js",
|
||||
"test:mashup": "aw puppet -c aw.config.js --testExt '*.int.js' --glob 'test/mashup/**/*.int.js'",
|
||||
"test:integration": "aw puppet -c aw.config.js --testExt '*.int.js' --glob 'test/integration/**/*.int.js'",
|
||||
@@ -36,8 +39,8 @@
|
||||
"@babel/cli": "7.18.10",
|
||||
"@babel/core": "7.18.13",
|
||||
"@babel/helper-plugin-utils": "7.18.9",
|
||||
"@babel/plugin-transform-react-jsx": "7.18.10",
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.18.9",
|
||||
"@babel/plugin-transform-react-jsx": "7.18.10",
|
||||
"@babel/preset-env": "7.18.10",
|
||||
"@babel/preset-react": "7.18.6",
|
||||
"@commitlint/cli": "17.1.2",
|
||||
@@ -46,9 +49,9 @@
|
||||
"@rollup/plugin-json": "4.1.0",
|
||||
"@rollup/plugin-node-resolve": "13.3.0",
|
||||
"@rollup/plugin-replace": "4.0.0",
|
||||
"@storybook/addon-docs": "6.5.10",
|
||||
"@storybook/addon-controls": "6.5.10",
|
||||
"@storybook/addon-actions": "6.5.10",
|
||||
"@storybook/addon-controls": "6.5.10",
|
||||
"@storybook/addon-docs": "6.5.10",
|
||||
"@storybook/addon-essentials": "6.5.10",
|
||||
"@storybook/addon-interactions": "6.5.10",
|
||||
"@storybook/addon-links": "6.5.10",
|
||||
@@ -56,6 +59,7 @@
|
||||
"@storybook/manager-webpack5": "6.5.10",
|
||||
"@storybook/react": "6.5.10",
|
||||
"@storybook/testing-library": "0.0.13",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"babel-loader": "8.2.5",
|
||||
"babel-plugin-istanbul": "6.1.1",
|
||||
"body-parser": "1.20.0",
|
||||
@@ -65,6 +69,7 @@
|
||||
"eslint-config-airbnb": "19.0.4",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-import": "2.26.0",
|
||||
"eslint-plugin-jest": "^27.0.4",
|
||||
"eslint-plugin-jsx-a11y": "6.6.1",
|
||||
"eslint-plugin-mocha": "10.1.0",
|
||||
"eslint-plugin-prettier": "4.2.1",
|
||||
@@ -72,6 +77,8 @@
|
||||
"eslint-plugin-storybook": "0.6.4",
|
||||
"express": "4.18.1",
|
||||
"husky": "8.0.1",
|
||||
"jest": "^29.0.3",
|
||||
"jest-environment-jsdom": "^29.0.3",
|
||||
"jimp": "0.16.1",
|
||||
"lerna": "5.5.0",
|
||||
"lint-staged": "13.0.3",
|
||||
@@ -86,6 +93,7 @@
|
||||
"rollup-plugin-dependency-flow": "0.3.0",
|
||||
"rollup-plugin-sass": "1.2.13",
|
||||
"rollup-plugin-terser": "7.0.2",
|
||||
"whatwg-fetch": "^3.6.2",
|
||||
"yargs": "17.5.1"
|
||||
},
|
||||
"resolutions": {
|
||||
|
||||
Reference in New Issue
Block a user