mirror of
https://github.com/qlik-oss/nebula.js.git
synced 2025-12-19 17:58:43 -05:00
* fix: fetch and apply csrf to WS call * fix: update tests * fix: update more tests * fix: update more tests
262 lines
9.4 KiB
JavaScript
262 lines
9.4 KiB
JavaScript
import { renderHook, act } from '@testing-library/react';
|
|
import {
|
|
useConnection,
|
|
handleConnectionSuccess,
|
|
handleConnectionFailure,
|
|
handleSessionNotification,
|
|
} from '../useConnection';
|
|
import * as connectModule from '../../connect';
|
|
import { RouterWrapper } from '../../utils';
|
|
import getCsrfToken from '../../utils/getCsrfToken';
|
|
|
|
jest.mock('../../utils/getCsrfToken', () => jest.fn());
|
|
|
|
describe('useConnection Module', () => {
|
|
let connectMock;
|
|
let renderResult;
|
|
let info;
|
|
let glob;
|
|
let getDocList;
|
|
let getConfiguration;
|
|
let cachedConnectionsData;
|
|
let addCachedConnections;
|
|
|
|
beforeEach(() => {
|
|
info = {};
|
|
addCachedConnections = jest.fn();
|
|
cachedConnectionsData = { addCachedConnections };
|
|
|
|
getDocList = jest.fn();
|
|
getConfiguration = jest.fn().mockResolvedValue({ qFeatures: { qIsDesktop: false } });
|
|
glob = { getDocList, getConfiguration };
|
|
connectMock = jest.fn().mockResolvedValue(glob);
|
|
|
|
jest.spyOn(connectModule, 'connect').mockImplementation(connectMock);
|
|
getCsrfToken.mockResolvedValue('A-CSRF-TOKEN');
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
describe('useConnection()', () => {
|
|
test('should return correct expected values from hook', async () => {
|
|
await act(async () => {
|
|
renderResult = renderHook(() => useConnection({ info, cachedConnectionsData }), { wrapper: RouterWrapper });
|
|
});
|
|
|
|
expect(renderResult.result.current).toMatchObject({
|
|
glob: undefined,
|
|
treatAsDesktop: false,
|
|
error: undefined,
|
|
activeStep: 0,
|
|
|
|
setGlobal: expect.any(Function),
|
|
setTreatAsDesktop: expect.any(Function),
|
|
setError: expect.any(Function),
|
|
setActiveStep: expect.any(Function),
|
|
});
|
|
});
|
|
|
|
test('should not proceed in any flow and NOT cache the provided connection if already was in "/" path', async () => {
|
|
info = { engineUrl: 'someEngineUrl#01' };
|
|
|
|
await act(async () => {
|
|
renderResult = renderHook(() => useConnection({ info, cachedConnectionsData }), { wrapper: RouterWrapper });
|
|
});
|
|
|
|
expect(addCachedConnections).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
test('should not proceed in any flow and NOT cache the provided connection if there was no info or engine url', async () => {
|
|
window.location.assign('/some-other-route');
|
|
|
|
await act(async () => {
|
|
renderResult = renderHook(() => useConnection({ info, cachedConnectionsData }), { wrapper: RouterWrapper });
|
|
});
|
|
|
|
expect(addCachedConnections).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
test('should not proceed in any flow and NOT cache the provided connection if info was invalid', async () => {
|
|
window.location.assign('/some-other-route');
|
|
info = { engineUrl: 'someEngineUrl#01', invalid: true };
|
|
|
|
await act(async () => {
|
|
renderResult = renderHook(() => useConnection({ info, cachedConnectionsData }), { wrapper: RouterWrapper });
|
|
});
|
|
|
|
expect(addCachedConnections).toHaveBeenCalledTimes(0);
|
|
expect(renderResult.result.current.error).toEqual({
|
|
message: 'Connection failed',
|
|
hints: ['The WebSocket URL is not valid.'],
|
|
});
|
|
});
|
|
|
|
test('should proceed in success flow and cache the provided connection successfully', async () => {
|
|
window.location.assign('/some-other-route');
|
|
info = { engineUrl: 'someEngineUrl#01' };
|
|
|
|
await act(async () => {
|
|
renderResult = renderHook(() => useConnection({ info, cachedConnectionsData }), { wrapper: RouterWrapper });
|
|
});
|
|
|
|
expect(addCachedConnections).toHaveBeenCalledTimes(1);
|
|
expect(addCachedConnections).toHaveBeenCalledWith({ info });
|
|
});
|
|
|
|
test('should proceed in failure flow and dont cache the provided connection', async () => {
|
|
connectMock.mockRejectedValue({ isRejected: true });
|
|
window.location.assign('/some-other-route');
|
|
info = { engineUrl: 'someEngineUrl#01' };
|
|
|
|
await act(async () => {
|
|
renderResult = renderHook(() => useConnection({ info, cachedConnectionsData }), { wrapper: RouterWrapper });
|
|
});
|
|
|
|
expect(addCachedConnections).toHaveBeenCalledTimes(0);
|
|
});
|
|
});
|
|
|
|
describe('utils()', () => {
|
|
let setGlobal;
|
|
let setTreatAsDesktop;
|
|
let setError;
|
|
|
|
beforeEach(() => {
|
|
setGlobal = jest.fn();
|
|
setTreatAsDesktop = jest.fn();
|
|
setError = jest.fn();
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.resetAllMocks();
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
describe('handleConnectionSuccess()', () => {
|
|
test('should setGlobal', async () => {
|
|
info = { engineUrl: 'someEngineUrl#01' };
|
|
handleConnectionSuccess({ result: info, setGlobal, setError, setTreatAsDesktop });
|
|
|
|
expect(setGlobal).toHaveBeenCalledTimes(1);
|
|
expect(setGlobal).toHaveBeenCalledWith(info);
|
|
});
|
|
|
|
test('should return if there was no `getDocList` in info (result in here) object', async () => {
|
|
getConfiguration.mockResolvedValue({ qFeatures: { qIsDesktop: true } });
|
|
info = { engineUrl: 'someEngineUrl#01', getConfiguration };
|
|
await handleConnectionSuccess({ result: info, setGlobal, setError, setTreatAsDesktop });
|
|
|
|
expect(setGlobal).toHaveBeenCalledTimes(1);
|
|
expect(setGlobal).toHaveBeenCalledWith(info);
|
|
expect(setTreatAsDesktop).toHaveBeenCalledTimes(0);
|
|
});
|
|
|
|
test('should setTreatAsDesktop if `config.qFeatures.qIsDesktop` set to true', async () => {
|
|
getConfiguration.mockResolvedValue({ qFeatures: { qIsDesktop: true } });
|
|
info = {
|
|
engineUrl: 'someEngineUrl#01',
|
|
getConfiguration,
|
|
getDocList: jest.fn(),
|
|
};
|
|
await handleConnectionSuccess({ result: info, setGlobal, setError, setTreatAsDesktop });
|
|
|
|
expect(setTreatAsDesktop).toHaveBeenCalledTimes(1);
|
|
expect(setTreatAsDesktop).toHaveBeenCalledWith(true);
|
|
});
|
|
|
|
test('should not set setTreatAsDesktop if ther ewas error while tring to get configuration', async () => {
|
|
getConfiguration.mockRejectedValue(undefined);
|
|
info = {
|
|
engineUrl: 'someEngineUrl#01',
|
|
getConfiguration,
|
|
getDocList: jest.fn(),
|
|
};
|
|
|
|
try {
|
|
await handleConnectionSuccess({ result: info, setGlobal, setError, setTreatAsDesktop });
|
|
} catch (error) {
|
|
expect(error.message).toBe('Failed to get configuration');
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('handleConnectionFailure()', () => {
|
|
test('should setError', async () => {
|
|
const error = new Error('someError#01');
|
|
handleConnectionFailure({ error, setError });
|
|
|
|
expect(setError).toHaveBeenCalledTimes(1);
|
|
expect(setError).toHaveBeenCalledWith({
|
|
hints: [],
|
|
message: 'Something went wrong, check the devtools console',
|
|
});
|
|
});
|
|
|
|
test('should setError if error was instance of WebSocket', async () => {
|
|
const error = new Error('someError#01');
|
|
error.target = new WebSocket('ws://localhost:1234');
|
|
info = { engineUrl: 'ws://localhost:1234' };
|
|
handleConnectionFailure({ error, info, setError });
|
|
|
|
expect(setError).toHaveBeenCalledTimes(1);
|
|
expect(setError).toHaveBeenCalledWith({
|
|
hints: [],
|
|
message: 'Connection failed to ws://localhost:1234',
|
|
});
|
|
});
|
|
|
|
test('should setError and add hint if url was for a qlik cloud SDE and there was no web integration id', async () => {
|
|
const error = new Error('someError#01');
|
|
error.target = new WebSocket('wss://some.remote.sde.qlikdev.com');
|
|
info = { engineUrl: 'wss://some.remote.sde.qlikdev.com' };
|
|
handleConnectionFailure({ error, info, setError });
|
|
|
|
expect(setError).toHaveBeenCalledTimes(1);
|
|
expect(setError).toHaveBeenCalledWith({
|
|
hints: [
|
|
'- If you are connecting to Qlik Cloud, make sure to provide a web integration id or client id.',
|
|
'- For Qlik Sense on Windows, make sure the proxy setup is correct and that you are authenticated.',
|
|
'- Press the ? in the top right for more information on how to set up the connection correctly.',
|
|
],
|
|
message: 'Connection failed to wss://some.remote.sde.qlikdev.com',
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('handleSessionNotification()', () => {
|
|
const sessionOnMock = jest.fn();
|
|
|
|
beforeEach(() => {
|
|
info = {
|
|
session: {
|
|
on: sessionOnMock,
|
|
},
|
|
};
|
|
});
|
|
|
|
test('should call `session.on` if it was in info object', () => {
|
|
sessionOnMock.mockImplementationOnce((evt, callback) => {
|
|
if (evt === 'notification:OnAuthenticationInformation') {
|
|
callback({ mustAuthenticate: true });
|
|
}
|
|
});
|
|
handleSessionNotification({ result: info, setError, setGlobal });
|
|
expect(sessionOnMock).toHaveBeenCalledTimes(1);
|
|
expect(sessionOnMock).toHaveBeenCalledWith('notification:OnAuthenticationInformation', expect.any(Function));
|
|
expect(setError).toHaveBeenCalledTimes(1);
|
|
expect(setError).toHaveBeenCalledWith({
|
|
message: 'Could not authenticate.',
|
|
hints: [
|
|
`In your virtual proxy advanced settings in the QMC, make sure to whitelist ${window.location.host}, ensure "Has secure attribute" is enabled and that "SameSite attribute" is set to "None".`,
|
|
],
|
|
});
|
|
expect(setGlobal).toHaveBeenCalledTimes(1);
|
|
expect(setGlobal).toHaveBeenCalledWith(null);
|
|
});
|
|
});
|
|
});
|
|
});
|