Fix frontend unit tests (#4045)
# What this PR does
- bring back and fix frontend unit tests
## Checklist
- [x] Unit, integration, and e2e (if applicable) tests updated
- [x] Documentation added (or `pr:no public docs` PR label added if not
required)
- [x] Added the relevant release notes label (see labels prefixed w/
`release:`). These labels dictate how your PR will
show up in the autogenerated release notes.
This commit is contained in:
parent
a601ad506c
commit
a14716551c
15 changed files with 146 additions and 257 deletions
4
.github/workflows/linting-and-tests.yml
vendored
4
.github/workflows/linting-and-tests.yml
vendored
|
|
@ -69,9 +69,9 @@ jobs:
|
|||
if: steps.cache-frontend-dependencies.outputs.cache-hit != 'true'
|
||||
working-directory: grafana-plugin
|
||||
run: yarn install --frozen-lockfile --prefer-offline --network-timeout 500000
|
||||
- name: Build frontend (will run linter and tests)
|
||||
- name: Build, lint and test frontend
|
||||
working-directory: grafana-plugin
|
||||
run: yarn build
|
||||
run: yarn lint && yarn test && yarn build
|
||||
|
||||
test-technical-documentation:
|
||||
name: "Test technical documentation"
|
||||
|
|
|
|||
4
grafana-plugin/.gitignore
vendored
4
grafana-plugin/.gitignore
vendored
|
|
@ -18,3 +18,7 @@ grafana-plugin.yml
|
|||
/playwright-report*
|
||||
/playwright/.cache/
|
||||
/e2e-tests/storageState.json
|
||||
|
||||
# Jest test report
|
||||
jest_html_reporters.html
|
||||
jest-html-reporters*
|
||||
|
|
@ -26,6 +26,18 @@ module.exports = {
|
|||
|
||||
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
|
||||
|
||||
reporters: process.env.HTML_REPORT_ENABLED
|
||||
? [
|
||||
'default',
|
||||
[
|
||||
'jest-html-reporters',
|
||||
{
|
||||
openReport: process.env.NODE_ENV !== 'production',
|
||||
},
|
||||
],
|
||||
]
|
||||
: ['default'],
|
||||
|
||||
testTimeout: 10000,
|
||||
testPathIgnorePatterns: ['/node_modules/', '/e2e-tests/'],
|
||||
transform: {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,25 @@ import 'plugin/dayjs';
|
|||
|
||||
import { TextEncoder, TextDecoder } from 'util';
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
__esModule: true,
|
||||
config: {
|
||||
featureToggles: {
|
||||
topNav: false,
|
||||
},
|
||||
bootData: {
|
||||
user: {
|
||||
timezone: 'UTC',
|
||||
},
|
||||
},
|
||||
},
|
||||
getBackendSrv: jest.fn().mockImplementation(() => ({
|
||||
get: jest.fn(),
|
||||
post: jest.fn(),
|
||||
})),
|
||||
getLocationSrv: jest.fn(),
|
||||
}));
|
||||
|
||||
Object.assign(global, { TextDecoder, TextEncoder });
|
||||
|
||||
// https://stackoverflow.com/a/66055672
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
"labels:link": "yarn --cwd ../../gops-labels/frontend link && yarn link \"@grafana/labels\" && yarn --cwd ../../gops-labels/frontend watch",
|
||||
"labels:unlink": "yarn --cwd ../../gops-labels/frontend unlink",
|
||||
"test": "jest --verbose",
|
||||
"test:report": "HTML_REPORT_ENABLED=true jest",
|
||||
"test:silent": "jest --silent",
|
||||
"test:e2e": "yarn playwright test --grep-invert @expensive",
|
||||
"test:e2e-expensive": "yarn playwright test --grep @expensive",
|
||||
|
|
@ -90,6 +91,7 @@
|
|||
"identity-obj-proxy": "3.0.0",
|
||||
"jest": "^29.5.0",
|
||||
"jest-environment-jsdom": "^29.5.0",
|
||||
"jest-html-reporters": "^3.1.7",
|
||||
"knip": "^5.0.3",
|
||||
"lint-staged": "^10.2.11",
|
||||
"lodash-es": "^4.17.21",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { render, fireEvent, screen } from '@testing-library/react';
|
|||
|
||||
import { Collapse, CollapseProps } from 'components/Collapse/Collapse';
|
||||
|
||||
describe.skip('Collapse', () => {
|
||||
describe('Collapse', () => {
|
||||
function getProps(isOpen: boolean, onClick: jest.Mock = jest.fn()) {
|
||||
return {
|
||||
label: 'Toggle',
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ import React from 'react';
|
|||
import { render } from '@testing-library/react';
|
||||
import { Provider } from 'mobx-react';
|
||||
|
||||
import { UserHelper } from 'models/user/user.helpers';
|
||||
|
||||
import { AddRespondersPopup } from './AddRespondersPopup';
|
||||
|
||||
describe('AddRespondersPopup', () => {
|
||||
|
|
@ -30,11 +32,10 @@ describe('AddRespondersPopup', () => {
|
|||
getSearchResult: jest.fn().mockReturnValue(teams),
|
||||
updateItems: jest.fn(),
|
||||
},
|
||||
userStore: {
|
||||
search: jest.fn().mockReturnValue({ results: [] }),
|
||||
},
|
||||
};
|
||||
|
||||
UserHelper.search = jest.fn().mockReturnValue({ results: [] });
|
||||
|
||||
const component = render(
|
||||
<Provider store={mockStoreValue}>
|
||||
<AddRespondersPopup
|
||||
|
|
|
|||
|
|
@ -14,23 +14,6 @@ jest.mock('plugin/GrafanaPluginRootPage.helpers', () => ({
|
|||
isTopNavbar: () => false,
|
||||
}));
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
__esModule: true,
|
||||
|
||||
config: {
|
||||
featureToggles: {
|
||||
topNav: false,
|
||||
},
|
||||
},
|
||||
|
||||
getBackendSrv: jest.fn().mockImplementation(() => ({
|
||||
get: jest.fn(),
|
||||
post: jest.fn(),
|
||||
})),
|
||||
|
||||
getLocationSrv: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('utils/authorization/authorization', () => ({
|
||||
...jest.requireActual('utils/authorization/authorization'),
|
||||
isUserActionAllowed: jest.fn().mockReturnValue(true),
|
||||
|
|
@ -44,7 +27,7 @@ jest.mock('state/rootStore', () => ({
|
|||
|
||||
const mockRootStore = (rest?: any, connected = false, cloud_connected = true) => {
|
||||
rootStore.userStore = {
|
||||
loadUser: loadUserMock,
|
||||
fetchItemById: loadUserMock,
|
||||
currentUser: {
|
||||
messaging_backends: {
|
||||
MOBILE_APP: { connected },
|
||||
|
|
@ -76,13 +59,11 @@ describe('MobileAppConnection', () => {
|
|||
beforeEach(() => {
|
||||
loadUserMock.mockClear();
|
||||
(rootStore as any).mockClear();
|
||||
mockRootStore();
|
||||
UserHelper.fetchBackendConfirmationCode = jest.fn().mockResolvedValueOnce('dfd');
|
||||
});
|
||||
|
||||
test('it shows a loading message if it is currently fetching the QR code', async () => {
|
||||
mockRootStore({
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'),
|
||||
});
|
||||
|
||||
const component = render(<MobileAppConnection userPk={USER_PK} />);
|
||||
expect(component.container).toMatchSnapshot();
|
||||
|
||||
|
|
@ -93,10 +74,7 @@ describe('MobileAppConnection', () => {
|
|||
});
|
||||
|
||||
test('it shows an error message if there was an error fetching the QR code', async () => {
|
||||
mockRootStore({
|
||||
fetchBackendConfirmationCode: jest.fn().mockRejectedValueOnce('dfd'),
|
||||
});
|
||||
|
||||
UserHelper.fetchBackendConfirmationCode = jest.fn().mockRejectedValueOnce('dfd');
|
||||
const component = render(<MobileAppConnection userPk={USER_PK} />);
|
||||
await screen.findByText(/.*error fetching your QR code.*/);
|
||||
|
||||
|
|
@ -109,10 +87,6 @@ describe('MobileAppConnection', () => {
|
|||
});
|
||||
|
||||
test("it shows a QR code if the app isn't already connected", async () => {
|
||||
mockRootStore({
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'),
|
||||
});
|
||||
|
||||
const component = render(<MobileAppConnection userPk={USER_PK} />);
|
||||
expect(component.container).toMatchSnapshot();
|
||||
|
||||
|
|
@ -125,7 +99,6 @@ describe('MobileAppConnection', () => {
|
|||
test('if we disconnect the app, it disconnects and fetches a new QR code', async () => {
|
||||
mockRootStore(
|
||||
{
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'),
|
||||
unlinkBackend: jest.fn().mockResolvedValueOnce('asdfadsfafds'),
|
||||
},
|
||||
true
|
||||
|
|
@ -153,7 +126,6 @@ describe('MobileAppConnection', () => {
|
|||
test('it shows a loading message if it is currently disconnecting', async () => {
|
||||
mockRootStore(
|
||||
{
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'),
|
||||
unlinkBackend: jest.fn().mockResolvedValueOnce(new Promise((resolve) => setTimeout(resolve, 500))),
|
||||
},
|
||||
true
|
||||
|
|
@ -184,7 +156,6 @@ describe('MobileAppConnection', () => {
|
|||
test('it shows an error message if there was an error disconnecting the mobile app', async () => {
|
||||
mockRootStore(
|
||||
{
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'),
|
||||
unlinkBackend: jest.fn().mockRejectedValueOnce('asdfadsfafds'),
|
||||
},
|
||||
true
|
||||
|
|
@ -213,7 +184,6 @@ describe('MobileAppConnection', () => {
|
|||
test('it polls loadUser on first render if not connected', async () => {
|
||||
mockRootStore(
|
||||
{
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dfd'),
|
||||
unlinkBackend: jest.fn().mockRejectedValueOnce('asdfadsfafds'),
|
||||
},
|
||||
false
|
||||
|
|
@ -232,7 +202,6 @@ describe('MobileAppConnection', () => {
|
|||
test('it polls loadUser after disconnect', async () => {
|
||||
mockRootStore(
|
||||
{
|
||||
fetchBackendConfirmationCode: jest.fn().mockResolvedValueOnce('dff'),
|
||||
unlinkBackend: jest.fn().mockRejectedValueOnce('asdff'),
|
||||
},
|
||||
true
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ enum License {
|
|||
CLOUD = 'some-other-license',
|
||||
}
|
||||
|
||||
const SELF_HOSTED_INSTALL_PLUGIN_ERROR_MESSAGE = 'ohhh nooo an error msg from self hosted install plugin';
|
||||
const CHECK_IF_PLUGIN_IS_CONNECTED_ERROR_MESSAGE = 'ohhh nooo a plugin connection error';
|
||||
const UPDATE_PLUGIN_STATUS_ERROR_MESSAGE = 'ohhh noooo a sync issue';
|
||||
const PLUGIN_CONFIGURATION_FORM_DATA_ID = 'plugin-configuration-form';
|
||||
|
|
@ -197,39 +196,6 @@ describe('PluginConfigPage', () => {
|
|||
expect(component.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("If onCallApiUrl is not set in the plugin's meta jsonData, and ONCALL_API_URL is passed in process.env, it calls selfHostedInstallPlugin", async () => {
|
||||
// mocks
|
||||
const processEnvOnCallApiUrl = 'onCallApiUrlFromProcessEnv';
|
||||
process.env.ONCALL_API_URL = processEnvOnCallApiUrl;
|
||||
|
||||
PluginState.selfHostedInstallPlugin = jest.fn();
|
||||
mockCheckTokenAndIfPluginIsConnected();
|
||||
|
||||
// test setup
|
||||
render(<PluginConfigPage {...generateComponentProps()} />);
|
||||
|
||||
// assertions
|
||||
expect(PluginState.selfHostedInstallPlugin).toHaveBeenCalledTimes(1);
|
||||
expect(PluginState.selfHostedInstallPlugin).toHaveBeenCalledWith(processEnvOnCallApiUrl, true);
|
||||
});
|
||||
|
||||
test("If onCallApiUrl is not set in the plugin's meta jsonData, and ONCALL_API_URL is passed in process.env, and there is an error calling selfHostedInstallPlugin, it sets an error message", async () => {
|
||||
// mocks
|
||||
const processEnvOnCallApiUrl = 'onCallApiUrlFromProcessEnv';
|
||||
process.env.ONCALL_API_URL = processEnvOnCallApiUrl;
|
||||
|
||||
PluginState.selfHostedInstallPlugin = jest.fn().mockResolvedValueOnce(SELF_HOSTED_INSTALL_PLUGIN_ERROR_MESSAGE);
|
||||
|
||||
// test setup
|
||||
const component = render(<PluginConfigPage {...generateComponentProps()} />);
|
||||
await screen.findByTestId(STATUS_MESSAGE_BLOCK_DATA_ID);
|
||||
|
||||
// assertions
|
||||
expect(PluginState.selfHostedInstallPlugin).toHaveBeenCalledTimes(1);
|
||||
expect(PluginState.selfHostedInstallPlugin).toHaveBeenCalledWith(processEnvOnCallApiUrl, true);
|
||||
expect(component.container).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('If onCallApiUrl is set, and updatePluginStatus returns an error, it sets an error message', async () => {
|
||||
// mocks
|
||||
const processEnvOnCallApiUrl = 'onCallApiUrlFromProcessEnv';
|
||||
|
|
|
|||
|
|
@ -1,60 +1,5 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`PluginConfigPage If onCallApiUrl is not set in the plugin's meta jsonData, and ONCALL_API_URL is passed in process.env, and there is an error calling selfHostedInstallPlugin, it sets an error message 1`] = `
|
||||
<div>
|
||||
<legend
|
||||
class="css-1w9pvsj"
|
||||
>
|
||||
Configure Grafana OnCall
|
||||
</legend>
|
||||
<p>
|
||||
This page will help you configure the OnCall plugin 👋
|
||||
</p>
|
||||
<pre
|
||||
data-testid="status-message-block"
|
||||
>
|
||||
<span
|
||||
class="root text text--undefined text--medium"
|
||||
>
|
||||
ohhh nooo an error msg from self hosted install plugin
|
||||
</span>
|
||||
</pre>
|
||||
<div
|
||||
class="css-ffyaiw-horizontal-group"
|
||||
style="width: 100%; height: 100%;"
|
||||
>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<button
|
||||
class="css-td06pi-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
>
|
||||
Retry Sync
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<button
|
||||
class="css-ttl745-button"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
>
|
||||
Remove current configuration
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`PluginConfigPage If onCallApiUrl is not set in the plugin's meta jsonData, or in process.env, updatePluginStatus is not called, and the configuration form is shown 1`] = `
|
||||
<div>
|
||||
<legend
|
||||
|
|
@ -229,38 +174,40 @@ exports[`PluginConfigPage It doesn't make any network calls if the plugin config
|
|||
Connected to OnCall (v1.2.3, OpenSource)
|
||||
</span>
|
||||
</pre>
|
||||
<div
|
||||
class="css-ffyaiw-horizontal-group"
|
||||
style="width: 100%; height: 100%;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
class="css-ffyaiw-horizontal-group"
|
||||
style="width: 100%; height: 100%;"
|
||||
>
|
||||
<a
|
||||
class="css-td06pi-button"
|
||||
href="/a/grafana-oncall-app/"
|
||||
tabindex="0"
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
<a
|
||||
class="css-td06pi-button"
|
||||
href="/a/grafana-oncall-app/"
|
||||
tabindex="0"
|
||||
>
|
||||
Open Grafana OnCall
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<button
|
||||
class="css-ttl745-button"
|
||||
type="button"
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
>
|
||||
Open Grafana OnCall
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
<button
|
||||
class="css-ttl745-button"
|
||||
type="button"
|
||||
>
|
||||
Remove current configuration
|
||||
</span>
|
||||
</button>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
>
|
||||
Remove current configuration
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -282,38 +229,40 @@ exports[`PluginConfigPage OnCallApiUrl is set, and checkTokenAndIfPluginIsConnec
|
|||
Connected to OnCall (v1.2.3, OpenSource)
|
||||
</span>
|
||||
</pre>
|
||||
<div
|
||||
class="css-ffyaiw-horizontal-group"
|
||||
style="width: 100%; height: 100%;"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
class="css-ffyaiw-horizontal-group"
|
||||
style="width: 100%; height: 100%;"
|
||||
>
|
||||
<a
|
||||
class="css-td06pi-button"
|
||||
href="/a/grafana-oncall-app/"
|
||||
tabindex="0"
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
<a
|
||||
class="css-td06pi-button"
|
||||
href="/a/grafana-oncall-app/"
|
||||
tabindex="0"
|
||||
>
|
||||
Open Grafana OnCall
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<button
|
||||
class="css-ttl745-button"
|
||||
type="button"
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
>
|
||||
Open Grafana OnCall
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
class="css-18qv8yz-layoutChildrenWrapper"
|
||||
>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
<button
|
||||
class="css-ttl745-button"
|
||||
type="button"
|
||||
>
|
||||
Remove current configuration
|
||||
</span>
|
||||
</button>
|
||||
<span
|
||||
class="css-1riaxdn"
|
||||
>
|
||||
Remove current configuration
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,54 +0,0 @@
|
|||
import { makeRequest as makeRequestOriginal } from 'network/network';
|
||||
import { RootStore } from 'state/rootStore';
|
||||
|
||||
import { UserStore } from './user';
|
||||
import { UserHelper } from './user.helpers';
|
||||
|
||||
const makeRequest = makeRequestOriginal as jest.Mock<ReturnType<typeof makeRequestOriginal>>;
|
||||
|
||||
jest.mock('network/network');
|
||||
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
describe('UserStore.fetchBackendConfirmationCode', () => {
|
||||
const userPk = '5';
|
||||
const backend = 'dfkjfdjkfdkjfdaaa';
|
||||
const mockedQrCode = 'dfkjfdkjfdkjfdjk';
|
||||
|
||||
test('it makes the proper API call and returns the response', async () => {
|
||||
makeRequest.mockResolvedValueOnce(mockedQrCode);
|
||||
|
||||
expect(await UserHelper.fetchBackendConfirmationCode(userPk, backend)).toEqual(mockedQrCode);
|
||||
|
||||
expect(makeRequest).toHaveBeenCalledTimes(1);
|
||||
expect(makeRequest).toHaveBeenCalledWith(`/users/${userPk}/get_backend_verification_code?backend=${backend}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('UserStore.unlinkBackend', () => {
|
||||
const rootStore = new RootStore();
|
||||
const userStore = new UserStore(rootStore);
|
||||
|
||||
const userPk = '5';
|
||||
const backend = 'dfkjfdjkfdkjfdaaa';
|
||||
|
||||
test('it makes the proper API call and returns the response', async () => {
|
||||
makeRequest.mockResolvedValueOnce('hello');
|
||||
|
||||
Object.defineProperty(userStore, 'loadCurrentUser', { value: jest.fn() });
|
||||
|
||||
await userStore.unlinkBackend(userPk, backend);
|
||||
|
||||
expect(makeRequest).toHaveBeenCalledTimes(1);
|
||||
expect(makeRequest).toHaveBeenCalledWith(`/users/${userPk}/unlink_backend/?backend=${backend}`, {
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
expect(userStore.loadCurrentUser).toHaveBeenCalledTimes(1);
|
||||
expect(userStore.loadCurrentUser).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
|
@ -63,12 +63,10 @@ describe('customFetch', () => {
|
|||
|
||||
describe('if there is otel', () => {
|
||||
const spanEndMock = jest.fn();
|
||||
const setStatusMock = jest.fn();
|
||||
const setAttributeMock = jest.fn();
|
||||
const spanStartMock = jest.fn(() => ({
|
||||
setAttribute: setAttributeMock,
|
||||
end: spanEndMock,
|
||||
setStatus: setStatusMock,
|
||||
}));
|
||||
const otel = {
|
||||
trace: {
|
||||
|
|
@ -93,11 +91,9 @@ describe('customFetch', () => {
|
|||
expect(spanStartMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it(`adds 'X-Idempotency-Key' header`, async () => {
|
||||
it(`passes request config`, async () => {
|
||||
await customFetch(URL, REQUEST_CONFIG);
|
||||
expect(fetchMock).toHaveBeenCalledWith(expect.any(String), {
|
||||
headers: { ...REQUEST_CONFIG.headers, 'X-Idempotency-Key': expect.any(String) },
|
||||
});
|
||||
expect(fetchMock).toHaveBeenCalledWith(expect.any(String), REQUEST_CONFIG);
|
||||
});
|
||||
|
||||
describe('if response is successful', () => {
|
||||
|
|
@ -116,7 +112,6 @@ describe('customFetch', () => {
|
|||
await expect(customFetch(URL, REQUEST_CONFIG)).rejects.toEqual(ERROR_MOCK);
|
||||
expect(FaroHelper.faro.api.pushEvent).toHaveBeenCalledWith('Request failed', { url: URL });
|
||||
expect(FaroHelper.faro.api.pushError).toHaveBeenCalledWith(ERROR_MOCK);
|
||||
expect(setStatusMock).toHaveBeenCalledTimes(1);
|
||||
expect(spanEndMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ jest.mock('grafana/app/core/core', () => ({
|
|||
},
|
||||
},
|
||||
}));
|
||||
jest.mock('network/network', () => ({
|
||||
__esModule: true,
|
||||
makeRequest: () => ({ pk: '1' }),
|
||||
}));
|
||||
|
||||
const onCallApiUrl = 'http://oncall-dev-engine:8080';
|
||||
|
||||
|
|
@ -166,7 +170,6 @@ describe('rootBaseStore', () => {
|
|||
{ is_installed: true, token_ok: false },
|
||||
])('signup is allowed, user is an admin, plugin installation is triggered', async (scenario) => {
|
||||
const rootBaseStore = new RootBaseStore();
|
||||
const mockedLoadCurrentUser = jest.fn();
|
||||
|
||||
contextSrv.user.orgRole = OrgRole.Admin;
|
||||
contextSrv.licensedAccessControlEnabled = jest.fn().mockResolvedValueOnce(false);
|
||||
|
|
@ -181,8 +184,6 @@ describe('rootBaseStore', () => {
|
|||
});
|
||||
isUserActionAllowed.mockReturnValueOnce(true);
|
||||
PluginState.installPlugin = jest.fn().mockResolvedValueOnce(null);
|
||||
Object.defineProperty(rootBaseStore.userStore, 'loadCurrentUser', { value: mockedLoadCurrentUser });
|
||||
|
||||
// test
|
||||
await rootBaseStore.setupPlugin(generatePluginData(onCallApiUrl));
|
||||
|
||||
|
|
@ -209,7 +210,6 @@ describe('rootBaseStore', () => {
|
|||
},
|
||||
])('signup is allowed, licensedAccessControlEnabled, various roles and permissions', async (scenario) => {
|
||||
const rootBaseStore = new RootBaseStore();
|
||||
const mockedLoadCurrentUser = jest.fn();
|
||||
|
||||
contextSrv.user.orgRole = scenario.role;
|
||||
contextSrv.licensedAccessControlEnabled = jest.fn().mockReturnValue(true);
|
||||
|
|
@ -224,7 +224,6 @@ describe('rootBaseStore', () => {
|
|||
});
|
||||
isUserActionAllowed.mockReturnValueOnce(true);
|
||||
PluginState.installPlugin = jest.fn().mockResolvedValueOnce(null);
|
||||
Object.defineProperty(rootBaseStore.userStore, 'loadCurrentUser', { value: mockedLoadCurrentUser });
|
||||
|
||||
// test
|
||||
await rootBaseStore.setupPlugin(generatePluginData(onCallApiUrl));
|
||||
|
|
@ -290,7 +289,6 @@ describe('rootBaseStore', () => {
|
|||
|
||||
test('when the plugin is installed, a data sync is triggered', async () => {
|
||||
const rootBaseStore = new RootBaseStore();
|
||||
const mockedLoadCurrentUser = jest.fn();
|
||||
|
||||
PluginState.updatePluginStatus = jest.fn().mockResolvedValueOnce({
|
||||
is_user_anonymous: false,
|
||||
|
|
@ -300,24 +298,17 @@ describe('rootBaseStore', () => {
|
|||
version: 'asdfasdf',
|
||||
license: 'asdfasdf',
|
||||
});
|
||||
Object.defineProperty(rootBaseStore.userStore, 'loadCurrentUser', { value: mockedLoadCurrentUser });
|
||||
|
||||
// test
|
||||
await rootBaseStore.setupPlugin(generatePluginData(onCallApiUrl));
|
||||
|
||||
// assertions
|
||||
expect(PluginState.updatePluginStatus).toHaveBeenCalledTimes(1);
|
||||
expect(PluginState.updatePluginStatus).toHaveBeenCalledWith(onCallApiUrl);
|
||||
|
||||
expect(mockedLoadCurrentUser).toHaveBeenCalledTimes(1);
|
||||
expect(mockedLoadCurrentUser).toHaveBeenCalledWith();
|
||||
|
||||
expect(rootBaseStore.initializationError).toBeNull();
|
||||
});
|
||||
|
||||
test('when the plugin is installed, and the data sync returns an error, it is properly handled', async () => {
|
||||
const rootBaseStore = new RootBaseStore();
|
||||
const mockedLoadCurrentUser = jest.fn();
|
||||
const updatePluginStatusError = 'asdasdfasdfasf';
|
||||
|
||||
PluginState.updatePluginStatus = jest.fn().mockResolvedValueOnce({
|
||||
|
|
@ -329,7 +320,6 @@ describe('rootBaseStore', () => {
|
|||
license: 'asdfasdf',
|
||||
});
|
||||
PluginState.updatePluginStatus = jest.fn().mockResolvedValueOnce(updatePluginStatusError);
|
||||
Object.defineProperty(rootBaseStore.userStore, 'loadCurrentUser', { value: mockedLoadCurrentUser });
|
||||
|
||||
// test
|
||||
await rootBaseStore.setupPlugin(generatePluginData(onCallApiUrl));
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ jest.mock('@grafana/faro-web-sdk', () => ({
|
|||
pushLog: jest.fn(),
|
||||
},
|
||||
}),
|
||||
LogLevel: jest.requireActual('@grafana/faro-web-sdk').LogLevel,
|
||||
InternalLoggerLevel: jest.requireActual('@grafana/faro-web-sdk').InternalLoggerLevel,
|
||||
getWebInstrumentations: () => [],
|
||||
}));
|
||||
|
||||
|
|
|
|||
|
|
@ -5746,6 +5746,11 @@ define-data-property@^1.1.2, define-data-property@^1.1.4:
|
|||
es-errors "^1.3.0"
|
||||
gopd "^1.0.1"
|
||||
|
||||
define-lazy-prop@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
|
||||
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
|
||||
|
||||
define-properties@^1.1.3, define-properties@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
|
||||
|
|
@ -8175,6 +8180,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2:
|
|||
is-data-descriptor "^1.0.0"
|
||||
kind-of "^6.0.2"
|
||||
|
||||
is-docker@^2.0.0, is-docker@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
|
||||
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
|
||||
|
||||
is-extendable@^0.1.0, is-extendable@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
|
||||
|
|
@ -8464,6 +8474,13 @@ is-windows@^1.0.1, is-windows@^1.0.2:
|
|||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
||||
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
|
||||
|
||||
is-wsl@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
|
||||
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
|
||||
dependencies:
|
||||
is-docker "^2.0.0"
|
||||
|
||||
isarray@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
|
||||
|
|
@ -8751,6 +8768,14 @@ jest-haste-map@^29.7.0:
|
|||
optionalDependencies:
|
||||
fsevents "^2.3.2"
|
||||
|
||||
jest-html-reporters@^3.1.7:
|
||||
version "3.1.7"
|
||||
resolved "https://registry.yarnpkg.com/jest-html-reporters/-/jest-html-reporters-3.1.7.tgz#d8cb6f5d15fd518e601841f90165f37765e7ff34"
|
||||
integrity sha512-GTmjqK6muQ0S0Mnksf9QkL9X9z2FGIpNSxC52E0PHDzjPQ1XDu2+XTI3B3FS43ZiUzD1f354/5FfwbNIBzT7ew==
|
||||
dependencies:
|
||||
fs-extra "^10.0.0"
|
||||
open "^8.0.3"
|
||||
|
||||
jest-leak-detector@^29.7.0:
|
||||
version "29.7.0"
|
||||
resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728"
|
||||
|
|
@ -10429,6 +10454,15 @@ onetime@^5.1.0, onetime@^5.1.2:
|
|||
dependencies:
|
||||
mimic-fn "^2.1.0"
|
||||
|
||||
open@^8.0.3:
|
||||
version "8.4.2"
|
||||
resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9"
|
||||
integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==
|
||||
dependencies:
|
||||
define-lazy-prop "^2.0.0"
|
||||
is-docker "^2.1.1"
|
||||
is-wsl "^2.2.0"
|
||||
|
||||
openapi-fetch@^0.8.1:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/openapi-fetch/-/openapi-fetch-0.8.1.tgz#a2bda1f72a8311e92cc789d1c8fec7b2d8ca28b6"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue