diff --git a/package.json b/package.json
index ccac6bcdd89..42fab464612 100644
--- a/package.json
+++ b/package.json
@@ -183,7 +183,7 @@
"jest-matcher-utils": "29.7.0",
"lerna": "7.4.1",
"mini-css-extract-plugin": "2.8.0",
- "msw": "1.3.2",
+ "msw": "2.2.0",
"mutationobserver-shim": "0.3.7",
"ngtemplate-loader": "2.1.0",
"node-notifier": "10.0.1",
diff --git a/public/app/core/components/NestedFolderPicker/NestedFolderPicker.test.tsx b/public/app/core/components/NestedFolderPicker/NestedFolderPicker.test.tsx
index f5ed2595d83..73368d51752 100644
--- a/public/app/core/components/NestedFolderPicker/NestedFolderPicker.test.tsx
+++ b/public/app/core/components/NestedFolderPicker/NestedFolderPicker.test.tsx
@@ -1,7 +1,7 @@
import 'whatwg-fetch'; // fetch polyfill
import { fireEvent, render as rtlRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
@@ -47,14 +47,11 @@ describe('NestedFolderPicker', () => {
beforeAll(() => {
window.HTMLElement.prototype.scrollIntoView = function () {};
server = setupServer(
- rest.get('/api/folders/:uid', (_, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- title: folderA.item.title,
- uid: folderA.item.uid,
- })
- );
+ http.get('/api/folders/:uid', () => {
+ return HttpResponse.json({
+ title: folderA.item.title,
+ uid: folderA.item.uid,
+ });
})
);
server.listen();
diff --git a/public/app/features/alerting/unified/CloneRuleEditor.test.tsx b/public/app/features/alerting/unified/CloneRuleEditor.test.tsx
index b14798e4f35..747f66b4eb1 100644
--- a/public/app/features/alerting/unified/CloneRuleEditor.test.tsx
+++ b/public/app/features/alerting/unified/CloneRuleEditor.test.tsx
@@ -1,3 +1,4 @@
+import 'whatwg-fetch';
import { render, waitFor, waitForElementToBeRemoved, within } from '@testing-library/react';
import { setupServer } from 'msw/node';
import React from 'react';
@@ -11,7 +12,6 @@ import { backendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchItem, DashboardSearchItemType } from 'app/features/search/types';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
import { RuleWithLocation } from 'app/types/unified-alerting';
-import 'whatwg-fetch';
import {
RulerAlertingRuleDTO,
diff --git a/public/app/features/alerting/unified/components/GrafanaAlertmanagerDeliveryWarning.test.tsx b/public/app/features/alerting/unified/components/GrafanaAlertmanagerDeliveryWarning.test.tsx
index 31fe270eaff..92583016959 100644
--- a/public/app/features/alerting/unified/components/GrafanaAlertmanagerDeliveryWarning.test.tsx
+++ b/public/app/features/alerting/unified/components/GrafanaAlertmanagerDeliveryWarning.test.tsx
@@ -1,10 +1,9 @@
-import { render, screen } from '@testing-library/react';
+import 'whatwg-fetch';
+import { render, screen, waitFor } from '@testing-library/react';
import { setupServer } from 'msw/node';
import React from 'react';
import { Provider } from 'react-redux';
-import 'whatwg-fetch';
-
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { configureStore } from 'app/store/configureStore';
@@ -76,7 +75,9 @@ describe('GrafanaAlertmanagerDeliveryWarning', () => {
);
- expect(container).toBeEmptyDOMElement();
+ await waitFor(() => {
+ expect(container).toBeEmptyDOMElement();
+ });
});
it('Should render no warning when choice is All but no active AM instances', async () => {
@@ -89,7 +90,9 @@ describe('GrafanaAlertmanagerDeliveryWarning', () => {
);
- expect(container).toBeEmptyDOMElement();
+ await waitFor(() => {
+ expect(container).toBeEmptyDOMElement();
+ });
});
});
diff --git a/public/app/features/alerting/unified/components/PluginBridge.mock.ts b/public/app/features/alerting/unified/components/PluginBridge.mock.ts
index 3644ce5779a..d71d70c313d 100644
--- a/public/app/features/alerting/unified/components/PluginBridge.mock.ts
+++ b/public/app/features/alerting/unified/components/PluginBridge.mock.ts
@@ -1,20 +1,25 @@
-import { rest } from 'msw';
-import { setupServer } from 'msw/node';
-
// bit of setup to mock HTTP request responses
import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
+import { setupServer } from 'msw/node';
+
import { SupportedPlugin } from '../types/pluginBridges';
export const NON_EXISTING_PLUGIN = '__does_not_exist__';
const server = setupServer(
- rest.get(`/api/plugins/${NON_EXISTING_PLUGIN}/settings`, async (_req, res, ctx) => res(ctx.status(404))),
- rest.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async (_req, res, ctx) => {
- return res(
- ctx.json({
- enabled: true,
- })
- );
+ http.get(`/api/plugins/${NON_EXISTING_PLUGIN}/settings`, async () =>
+ HttpResponse.json(
+ {},
+ {
+ status: 404,
+ }
+ )
+ ),
+ http.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async () => {
+ return HttpResponse.json({
+ enabled: true,
+ });
})
);
diff --git a/public/app/features/alerting/unified/components/contact-points/__mocks__/grafanaManagedServer.ts b/public/app/features/alerting/unified/components/contact-points/__mocks__/grafanaManagedServer.ts
index a93b7b046c0..54666de1aa5 100644
--- a/public/app/features/alerting/unified/components/contact-points/__mocks__/grafanaManagedServer.ts
+++ b/public/app/features/alerting/unified/components/contact-points/__mocks__/grafanaManagedServer.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { AlertmanagerChoice, AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -14,15 +15,15 @@ import receiversMock from './receivers.mock.json';
export default (server: SetupServer) => {
server.use(
// this endpoint is a grafana built-in alertmanager
- rest.get('/api/alertmanager/grafana/config/api/v1/alerts', (_req, res, ctx) =>
- res(ctx.json(alertmanagerMock))
+ http.get('/api/alertmanager/grafana/config/api/v1/alerts', () =>
+ HttpResponse.json(alertmanagerMock)
),
// this endpoint is only available for the built-in alertmanager
- rest.get('/api/alertmanager/grafana/config/api/v1/receivers', (_req, res, ctx) =>
- res(ctx.json(receiversMock))
+ http.get('/api/alertmanager/grafana/config/api/v1/receivers', () =>
+ HttpResponse.json(receiversMock)
),
// this endpoint will respond if the OnCall plugin is installed
- rest.get('/api/plugins/grafana-oncall-app/settings', (_req, res, ctx) => res(ctx.status(404)))
+ http.get('/api/plugins/grafana-oncall-app/settings', () => HttpResponse.json({}, { status: 404 }))
);
// this endpoint is for rendering the "additional AMs to configure" warning
@@ -41,12 +42,18 @@ export const setupTestEndpointMock = (server: SetupServer) => {
const mock = jest.fn();
server.use(
- rest.post('/api/alertmanager/grafana/config/api/v1/receivers/test', async (req, res, ctx) => {
- const requestBody = await req.json();
- mock(requestBody);
+ http.post(
+ '/api/alertmanager/grafana/config/api/v1/receivers/test',
+ async ({ request }) => {
+ const requestBody = await request.json();
+ mock(requestBody);
- return res.once(ctx.status(200));
- })
+ return HttpResponse.json({});
+ },
+ {
+ once: true,
+ }
+ )
);
return mock;
@@ -56,12 +63,18 @@ export const setupSaveEndpointMock = (server: SetupServer) => {
const mock = jest.fn();
server.use(
- rest.post('/api/alertmanager/grafana/config/api/v1/alerts', async (req, res, ctx) => {
- const requestBody = await req.json();
- mock(requestBody);
+ http.post(
+ '/api/alertmanager/grafana/config/api/v1/alerts',
+ async ({ request }) => {
+ const requestBody = await request.json();
+ mock(requestBody);
- return res.once(ctx.status(200));
- })
+ return HttpResponse.json({});
+ },
+ {
+ once: true,
+ }
+ )
);
return mock;
diff --git a/public/app/features/alerting/unified/components/contact-points/__mocks__/mimirFlavoredServer.ts b/public/app/features/alerting/unified/components/contact-points/__mocks__/mimirFlavoredServer.ts
index 88ef97018e9..adbed73cb48 100644
--- a/public/app/features/alerting/unified/components/contact-points/__mocks__/mimirFlavoredServer.ts
+++ b/public/app/features/alerting/unified/components/contact-points/__mocks__/mimirFlavoredServer.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -10,14 +11,20 @@ export const MIMIR_DATASOURCE_UID = 'mimir';
export default (server: SetupServer) => {
server.use(
- rest.get(`/api/alertmanager/${MIMIR_DATASOURCE_UID}/config/api/v1/alerts`, (_req, res, ctx) =>
- res(ctx.json(mimirAlertmanagerMock))
+ http.get(`/api/alertmanager/${MIMIR_DATASOURCE_UID}/config/api/v1/alerts`, () =>
+ HttpResponse.json(mimirAlertmanagerMock)
),
- rest.get(`/api/datasources/proxy/uid/${MIMIR_DATASOURCE_UID}/api/v1/status/buildinfo`, (_req, res, ctx) =>
- res(ctx.status(404))
+ http.get(`/api/datasources/proxy/uid/${MIMIR_DATASOURCE_UID}/api/v1/status/buildinfo`, () =>
+ HttpResponse.json(
+ {
+ template_files: {},
+ alertmanager_config: {},
+ },
+ { status: 404 }
+ )
),
// this endpoint will respond if the OnCall plugin is installed
- rest.get('/api/plugins/grafana-oncall-app/settings', (_req, res, ctx) => res(ctx.status(404)))
+ http.get('/api/plugins/grafana-oncall-app/settings', () => HttpResponse.json({}, { status: 404 }))
);
return server;
diff --git a/public/app/features/alerting/unified/components/contact-points/__mocks__/vanillaAlertmanagerServer.ts b/public/app/features/alerting/unified/components/contact-points/__mocks__/vanillaAlertmanagerServer.ts
index b834a5a515f..6c4943e28a2 100644
--- a/public/app/features/alerting/unified/components/contact-points/__mocks__/vanillaAlertmanagerServer.ts
+++ b/public/app/features/alerting/unified/components/contact-points/__mocks__/vanillaAlertmanagerServer.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { AlertmanagerStatus } from 'app/plugins/datasource/alertmanager/types';
@@ -10,11 +11,11 @@ export const VANILLA_ALERTMANAGER_DATASOURCE_UID = 'alertmanager';
export default (server: SetupServer) => {
server.use(
- rest.get(`/api/alertmanager/${VANILLA_ALERTMANAGER_DATASOURCE_UID}/api/v2/status`, (_req, res, ctx) =>
- res(ctx.json(vanillaAlertManagerConfig))
+ http.get(`/api/alertmanager/${VANILLA_ALERTMANAGER_DATASOURCE_UID}/api/v2/status`, () =>
+ HttpResponse.json(vanillaAlertManagerConfig)
),
// this endpoint will respond if the OnCall plugin is installed
- rest.get('/api/plugins/grafana-oncall-app/settings', (_req, res, ctx) => res(ctx.status(404)))
+ http.get('/api/plugins/grafana-oncall-app/settings', () => HttpResponse.json({}, { status: 404 }))
);
return server;
diff --git a/public/app/features/alerting/unified/components/rule-viewer/v2/__mocks__/server.ts b/public/app/features/alerting/unified/components/rule-viewer/v2/__mocks__/server.ts
index a9ec31748fe..83584bb4155 100644
--- a/public/app/features/alerting/unified/components/rule-viewer/v2/__mocks__/server.ts
+++ b/public/app/features/alerting/unified/components/rule-viewer/v2/__mocks__/server.ts
@@ -1,7 +1,7 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
-import 'whatwg-fetch';
import { AlertmanagersChoiceResponse } from 'app/features/alerting/unified/api/alertmanagerApi';
import { mockAlertmanagerChoiceResponse } from 'app/features/alerting/unified/mocks/alertmanagerApi';
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
@@ -33,16 +33,15 @@ export function createMockGrafanaServer() {
// a user must alsso have permissions for the folder (namespace) in which the alert rule is stored
function mockFolderAccess(server: SetupServer, accessControl: Partial>) {
server.use(
- rest.get('/api/folders/:uid', (req, res, ctx) => {
- const uid = req.params.uid;
+ http.get('/api/folders/:uid', ({ request }) => {
+ const url = new URL(request.url);
+ const uid = url.searchParams.get('uid');
- return res(
- ctx.json({
- title: 'My Folder',
- uid,
- accessControl,
- })
- );
+ return HttpResponse.json({
+ title: 'My Folder',
+ uid,
+ accessControl,
+ });
})
);
@@ -51,8 +50,8 @@ function mockFolderAccess(server: SetupServer, accessControl: Partial {
- return res(ctx.status(200));
+ http.get('/api/plugins/grafana-incident-app/settings', () => {
+ return HttpResponse.json({});
})
);
}
diff --git a/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx b/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
index 9ee4496bd17..59e89009881 100644
--- a/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RuleDetails.test.tsx
@@ -1,4 +1,6 @@
+import 'whatwg-fetch';
import { render, screen, waitFor } from '@testing-library/react';
+import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';
import { Provider } from 'react-redux';
@@ -18,6 +20,7 @@ import { AlertmanagersChoiceResponse } from '../../api/alertmanagerApi';
import { useIsRuleEditable } from '../../hooks/useIsRuleEditable';
import { getCloudRule, getGrafanaRule } from '../../mocks';
import { mockAlertmanagerChoiceResponse } from '../../mocks/alertmanagerApi';
+import { SupportedPlugin } from '../../types/pluginBridges';
import { RuleDetails } from './RuleDetails';
@@ -42,7 +45,13 @@ const ui = {
},
};
-const server = setupServer();
+const server = setupServer(
+ http.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async () => {
+ return HttpResponse.json({
+ enabled: false,
+ });
+ })
+);
const alertmanagerChoiceMockedResponse: AlertmanagersChoiceResponse = {
alertmanagersChoice: AlertmanagerChoice.Internal,
@@ -74,6 +83,7 @@ beforeEach(() => {
],
});
server.resetHandlers();
+ mockAlertmanagerChoiceResponse(server, alertmanagerChoiceMockedResponse);
});
describe('RuleDetails RBAC', () => {
@@ -107,7 +117,6 @@ describe('RuleDetails RBAC', () => {
it('Should not render Silence button for users wihout the instance create permission', async () => {
// Arrange
jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(false);
- mockAlertmanagerChoiceResponse(server, alertmanagerChoiceMockedResponse);
// Act
renderRuleDetails(grafanaRule);
@@ -118,8 +127,6 @@ describe('RuleDetails RBAC', () => {
});
it('Should render Silence button for users with the instance create permissions', async () => {
- mockAlertmanagerChoiceResponse(server, alertmanagerChoiceMockedResponse);
-
// Arrange
jest
.spyOn(contextSrv, 'hasPermission')
diff --git a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
index b224dd8db30..3093caf579c 100644
--- a/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/RulesGroup.test.tsx
@@ -108,10 +108,12 @@ describe('Rules group tests', () => {
groups: [group],
};
- it('Should hide delete and edit group buttons', () => {
+ it('Should hide delete and edit group buttons', async () => {
// Act
mockUseHasRuler(true, true);
+ mockFolderApi(server).folder('cpu-usage', mockFolder({ uid: 'cpu-usage', canSave: false }));
renderRulesGroup(namespace, group);
+ expect(await screen.findByTestId('rule-group')).toBeInTheDocument();
// Assert
expect(ui.deleteGroupButton.query()).not.toBeInTheDocument();
diff --git a/public/app/features/alerting/unified/components/rules/state-history/LokiStateHistory.test.tsx b/public/app/features/alerting/unified/components/rules/state-history/LokiStateHistory.test.tsx
index 24380f45f3f..e9ba271cdec 100644
--- a/public/app/features/alerting/unified/components/rules/state-history/LokiStateHistory.test.tsx
+++ b/public/app/features/alerting/unified/components/rules/state-history/LokiStateHistory.test.tsx
@@ -1,9 +1,9 @@
+import 'whatwg-fetch';
import { render, waitFor } from '@testing-library/react';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';
import { byRole, byText } from 'testing-library-selector';
-import 'whatwg-fetch';
import { DataFrameJSON } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
@@ -20,53 +20,51 @@ beforeAll(() => {
server.listen({ onUnhandledRequest: 'error' });
server.use(
- rest.get('/api/v1/rules/history', (req, res, ctx) =>
- res(
- ctx.json({
- data: {
- values: [
- [1681739580000, 1681739580000, 1681739580000],
- [
- {
- previous: 'Normal',
- current: 'Pending',
- values: {
- B: 0.010344684900897919,
- C: 1,
- },
- labels: {
- handler: '/api/prometheus/grafana/api/v1/rules',
- },
+ http.get('/api/v1/rules/history', () =>
+ HttpResponse.json({
+ data: {
+ values: [
+ [1681739580000, 1681739580000, 1681739580000],
+ [
+ {
+ previous: 'Normal',
+ current: 'Pending',
+ values: {
+ B: 0.010344684900897919,
+ C: 1,
},
- {
- previous: 'Normal',
- current: 'Pending',
- values: {
- B: 0.010344684900897919,
- C: 1,
- },
- dashboardUID: '',
- panelID: 0,
- labels: {
- handler: '/api/live/ws',
- },
+ labels: {
+ handler: '/api/prometheus/grafana/api/v1/rules',
},
- {
- previous: 'Normal',
- current: 'Pending',
- values: {
- B: 0.010344684900897919,
- C: 1,
- },
- labels: {
- handler: '/api/folders/:uid/',
- },
+ },
+ {
+ previous: 'Normal',
+ current: 'Pending',
+ values: {
+ B: 0.010344684900897919,
+ C: 1,
},
- ],
+ dashboardUID: '',
+ panelID: 0,
+ labels: {
+ handler: '/api/live/ws',
+ },
+ },
+ {
+ previous: 'Normal',
+ current: 'Pending',
+ values: {
+ B: 0.010344684900897919,
+ C: 1,
+ },
+ labels: {
+ handler: '/api/folders/:uid/',
+ },
+ },
],
- },
- })
- )
+ ],
+ },
+ })
)
);
});
@@ -100,8 +98,8 @@ describe('LokiStateHistory', () => {
it('should render no entries message when no records are returned', async () => {
server.use(
- rest.get('/api/v1/rules/history', (req, res, ctx) =>
- res(ctx.json({ data: { values: [] }, schema: { fields: [] } }))
+ http.get('/api/v1/rules/history', () =>
+ HttpResponse.json({ data: { values: [] }, schema: { fields: [] } })
)
);
diff --git a/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.tsx b/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.tsx
index 6feda94a91c..1e15071190b 100644
--- a/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.tsx
+++ b/public/app/features/alerting/unified/hooks/useExternalAMSelector.test.tsx
@@ -1,10 +1,9 @@
+import 'whatwg-fetch';
import { renderHook, waitFor } from '@testing-library/react';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import { TestProvider } from 'test/helpers/TestProvider';
-import 'whatwg-fetch';
-
import { DataSourceSettings } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
@@ -215,8 +214,8 @@ function setupAlertmanagerDataSource(
};
server.use(
- rest.get('/api/datasources', (_req, res, ctx) => {
- return res(ctx.json([dsSettings]));
+ http.get('/api/datasources', () => {
+ return HttpResponse.json([dsSettings]);
})
);
}
diff --git a/public/app/features/alerting/unified/mockApi.ts b/public/app/features/alerting/unified/mockApi.ts
index d603cbe42be..cd85c322815 100644
--- a/public/app/features/alerting/unified/mockApi.ts
+++ b/public/app/features/alerting/unified/mockApi.ts
@@ -1,7 +1,7 @@
-import { uniqueId } from 'lodash';
-import { rest } from 'msw';
-import { setupServer, SetupServer } from 'msw/node';
import 'whatwg-fetch';
+import { uniqueId } from 'lodash';
+import { http, HttpResponse } from 'msw';
+import { setupServer, SetupServer } from 'msw/node';
import { DataSourceInstanceSettings, PluginMeta } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
@@ -190,85 +190,74 @@ export function mockApi(server: SetupServer) {
configure(builder);
server.use(
- rest.get(`api/alertmanager/${amName}/config/api/v1/alerts`, (req, res, ctx) =>
- res(
- ctx.status(200),
- ctx.json({
- alertmanager_config: builder.build(),
- template_files: {},
- })
- )
+ http.get(`api/alertmanager/${amName}/config/api/v1/alerts`, () =>
+ HttpResponse.json({
+ alertmanager_config: builder.build(),
+ template_files: {},
+ })
)
);
},
eval: (response: AlertingQueryResponse) => {
server.use(
- rest.post('/api/v1/eval', (_, res, ctx) => {
- return res(ctx.status(200), ctx.json(response));
+ http.post('/api/v1/eval', () => {
+ return HttpResponse.json(response);
})
);
},
grafanaNotifiers: (response: NotifierDTO[]) => {
- server.use(
- rest.get(`api/alert-notifiers`, (req, res, ctx) => res(ctx.status(200), ctx.json(response)))
- );
+ server.use(http.get(`api/alert-notifiers`, () => HttpResponse.json(response)));
},
plugins: {
getPluginSettings: (response: PluginMeta) => {
- server.use(
- rest.get(`api/plugins/${response.id}/settings`, (req, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
- )
- );
+ server.use(http.get(`api/plugins/${response.id}/settings`, () => HttpResponse.json(response)));
},
},
oncall: {
getOnCallIntegrations: (response: OnCallIntegrationDTO[]) => {
server.use(
- rest.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels`, (_, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
+ http.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels`, () =>
+ HttpResponse.json(response)
)
);
},
features: (response: string[]) => {
server.use(
- rest.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/features`, (_, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
- )
+ http.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/features`, () => HttpResponse.json(response))
);
},
validateIntegrationName: (invalidNames: string[]) => {
server.use(
- rest.get(
+ http.get(
`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels/validate_name`,
- (req, res, ctx) => {
- const isValid = !invalidNames.includes(req.url.searchParams.get('verbal_name') ?? '');
- return res(ctx.status(isValid ? 200 : 409), ctx.json(isValid));
+ ({ request }) => {
+ const url = new URL(request.url);
+ const isValid = !invalidNames.includes(url.searchParams.get('verbal_name') ?? '');
+ return HttpResponse.json(isValid, {
+ status: isValid ? 200 : 409,
+ });
}
)
);
},
createIntegraion: () => {
server.use(
- rest.post(
+ http.post<{}, CreateIntegrationDTO>(
`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels`,
- async (req, res, ctx) => {
- const body = await req.json();
+ async ({ request }) => {
+ const body = await request.json();
const integrationId = uniqueId('oncall-integration-');
- return res(
- ctx.status(200),
- ctx.json({
- id: integrationId,
- integration: body.integration,
- integration_url: `https://oncall-endpoint.example.com/${integrationId}`,
- verbal_name: body.verbal_name,
- connected_escalations_chains_count: 0,
- })
- );
+ return HttpResponse.json({
+ id: integrationId,
+ integration: body.integration,
+ integration_url: `https://oncall-endpoint.example.com/${integrationId}`,
+ verbal_name: body.verbal_name,
+ connected_escalations_chains_count: 0,
+ });
}
)
);
@@ -281,21 +270,15 @@ export function mockAlertRuleApi(server: SetupServer) {
return {
prometheusRuleNamespaces: (dsName: string, response: PromRulesResponse) => {
server.use(
- rest.get(`api/prometheus/${dsName}/api/v1/rules`, (req, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
- )
+ http.get(`api/prometheus/${dsName}/api/v1/rules`, () => HttpResponse.json(response))
);
},
rulerRules: (dsName: string, response: RulerRulesConfigDTO) => {
- server.use(
- rest.get(`/api/ruler/${dsName}/api/v1/rules`, (req, res, ctx) => res(ctx.status(200), ctx.json(response)))
- );
+ server.use(http.get(`/api/ruler/${dsName}/api/v1/rules`, () => HttpResponse.json(response)));
},
rulerRuleGroup: (dsName: string, namespace: string, group: string, response: RulerRuleGroupDTO) => {
server.use(
- rest.get(`/api/ruler/${dsName}/api/v1/rules/${namespace}/${group}`, (req, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
- )
+ http.get(`/api/ruler/${dsName}/api/v1/rules/${namespace}/${group}`, () => HttpResponse.json(response))
);
},
};
@@ -312,9 +295,7 @@ export function mockFeatureDiscoveryApi(server: SetupServer) {
* @param response Use `buildInfoResponse` to get a pre-defined response for Prometheus and Mimir
*/
discoverDsFeatures: (dsSettings: DataSourceInstanceSettings, response: PromBuildInfoResponse) => {
- server.use(
- rest.get(`${dsSettings.url}/api/v1/status/buildinfo`, (_, res, ctx) => res(ctx.status(200), ctx.json(response)))
- );
+ server.use(http.get(`${dsSettings.url}/api/v1/status/buildinfo`, () => HttpResponse.json(response)));
},
};
}
@@ -323,16 +304,20 @@ export function mockProvisioningApi(server: SetupServer) {
return {
exportRuleGroup: (folderUid: string, groupName: string, response: Record) => {
server.use(
- rest.get(`/api/v1/provisioning/folder/${folderUid}/rule-groups/${groupName}/export`, (req, res, ctx) =>
- res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']))
- )
+ http.get(`/api/v1/provisioning/folder/${folderUid}/rule-groups/${groupName}/export`, ({ request }) => {
+ const url = new URL(request.url);
+ const format = url.searchParams.get('format') ?? 'yaml';
+ return HttpResponse.text(response[format]);
+ })
);
},
exportReceiver: (response: Record) => {
server.use(
- rest.get(`/api/v1/provisioning/contact-points/export/`, (req, res, ctx) =>
- res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']))
- )
+ http.get(`/api/v1/provisioning/contact-points/export/`, ({ request }) => {
+ const url = new URL(request.url);
+ const format = url.searchParams.get('format') ?? 'yaml';
+ return HttpResponse.text(response[format]);
+ })
);
},
};
@@ -344,43 +329,51 @@ export function mockExportApi(server: SetupServer) {
// exportRule requires ruleUid parameter and doesn't allow folderUid and group parameters
exportRule: (ruleUid: string, response: Record) => {
server.use(
- rest.get('/api/ruler/grafana/api/v1/export/rules', (req, res, ctx) => {
- if (req.url.searchParams.get('ruleUid') === ruleUid) {
- return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
+ http.get('/api/ruler/grafana/api/v1/export/rules', ({ request }) => {
+ const url = new URL(request.url);
+ if (url.searchParams.get('ruleUid') === ruleUid) {
+ const format = url.searchParams.get('format') ?? 'yaml';
+ return HttpResponse.text(response[format]);
}
- return res(ctx.status(500));
+ return HttpResponse.text('', { status: 500 });
})
);
},
// exportRulesGroup requires folderUid and group parameters and doesn't allow ruleUid parameter
exportRulesGroup: (folderUid: string, group: string, response: Record) => {
server.use(
- rest.get('/api/ruler/grafana/api/v1/export/rules', (req, res, ctx) => {
- if (req.url.searchParams.get('folderUid') === folderUid && req.url.searchParams.get('group') === group) {
- return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
+ http.get('/api/ruler/grafana/api/v1/export/rules', ({ request }) => {
+ const url = new URL(request.url);
+ if (url.searchParams.get('folderUid') === folderUid && url.searchParams.get('group') === group) {
+ const format = url.searchParams.get('format') ?? 'yaml';
+ return HttpResponse.text(response[format]);
}
- return res(ctx.status(500));
+ return HttpResponse.text('', { status: 500 });
})
);
},
// exportRulesFolder requires folderUid parameter
exportRulesFolder: (folderUid: string, response: Record) => {
server.use(
- rest.get('/api/ruler/grafana/api/v1/export/rules', (req, res, ctx) => {
- if (req.url.searchParams.get('folderUid') === folderUid) {
- return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
+ http.get('/api/ruler/grafana/api/v1/export/rules', ({ request }) => {
+ const url = new URL(request.url);
+ if (url.searchParams.get('folderUid') === folderUid) {
+ const format = url.searchParams.get('format') ?? 'yaml';
+ return HttpResponse.text(response[format]);
}
- return res(ctx.status(500));
+ return HttpResponse.text('', { status: 500 });
})
);
},
modifiedExport: (namespaceUID: string, response: Record) => {
server.use(
- rest.post(`/api/ruler/grafana/api/v1/rules/${namespaceUID}/export`, (req, res, ctx) => {
- return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
+ http.post(`/api/ruler/grafana/api/v1/rules/${namespaceUID}/export`, ({ request }) => {
+ const url = new URL(request.url);
+ const format = url.searchParams.get('format') ?? 'yaml';
+ return HttpResponse.text(response[format]);
})
);
},
@@ -390,7 +383,7 @@ export function mockExportApi(server: SetupServer) {
export function mockFolderApi(server: SetupServer) {
return {
folder: (folderUid: string, response: FolderDTO) => {
- server.use(rest.get(`/api/folders/${folderUid}`, (_, res, ctx) => res(ctx.status(200), ctx.json(response))));
+ server.use(http.get(`/api/folders/${folderUid}`, () => HttpResponse.json(response)));
},
};
}
@@ -398,7 +391,7 @@ export function mockFolderApi(server: SetupServer) {
export function mockSearchApi(server: SetupServer) {
return {
search: (results: DashboardSearchItem[]) => {
- server.use(rest.get(`/api/search`, (_, res, ctx) => res(ctx.status(200), ctx.json(results))));
+ server.use(http.get(`/api/search`, () => HttpResponse.json(results)));
},
};
}
@@ -406,14 +399,10 @@ export function mockSearchApi(server: SetupServer) {
export function mockDashboardApi(server: SetupServer) {
return {
search: (results: DashboardSearchItem[]) => {
- server.use(rest.get(`/api/search`, (_, res, ctx) => res(ctx.status(200), ctx.json(results))));
+ server.use(http.get(`/api/search`, () => HttpResponse.json(results)));
},
dashboard: (response: DashboardDTO) => {
- server.use(
- rest.get(`/api/dashboards/uid/${response.dashboard.uid}`, (_, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
- )
- );
+ server.use(http.get(`/api/dashboards/uid/${response.dashboard.uid}`, () => HttpResponse.json(response)));
},
};
}
diff --git a/public/app/features/alerting/unified/mocks/alertRuleApi.ts b/public/app/features/alerting/unified/mocks/alertRuleApi.ts
index 7eb598b37fa..d748fb8973a 100644
--- a/public/app/features/alerting/unified/mocks/alertRuleApi.ts
+++ b/public/app/features/alerting/unified/mocks/alertRuleApi.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { PromRulesResponse } from 'app/types/unified-alerting-dto';
@@ -6,9 +7,9 @@ import { PromRulesResponse } from 'app/types/unified-alerting-dto';
import { PreviewResponse, PREVIEW_URL, PROM_RULES_URL } from '../api/alertRuleApi';
export function mockPreviewApiResponse(server: SetupServer, result: PreviewResponse) {
- server.use(rest.post(PREVIEW_URL, (req, res, ctx) => res(ctx.json(result))));
+ server.use(http.post(PREVIEW_URL, () => HttpResponse.json(result)));
}
export function mockPromRulesApiResponse(server: SetupServer, result: PromRulesResponse) {
- server.use(rest.get(PROM_RULES_URL, (req, res, ctx) => res(ctx.json(result))));
+ server.use(http.get(PROM_RULES_URL, () => HttpResponse.json(result)));
}
diff --git a/public/app/features/alerting/unified/mocks/alertmanagerApi.ts b/public/app/features/alerting/unified/mocks/alertmanagerApi.ts
index 492e01e74a2..1b7e98806dc 100644
--- a/public/app/features/alerting/unified/mocks/alertmanagerApi.ts
+++ b/public/app/features/alerting/unified/mocks/alertmanagerApi.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import {
@@ -14,7 +15,7 @@ export const defaultAlertmanagerChoiceResponse: AlertmanagersChoiceResponse = {
numExternalAlertmanagers: 0,
};
export function mockAlertmanagerChoiceResponse(server: SetupServer, response: AlertmanagersChoiceResponse) {
- server.use(rest.get('/api/v1/ngalert', (req, res, ctx) => res(ctx.status(200), ctx.json(response))));
+ server.use(http.get('/api/v1/ngalert', () => HttpResponse.json(response)));
}
export const emptyExternalAlertmanagersResponse: ExternalAlertmanagersResponse = {
@@ -24,7 +25,7 @@ export const emptyExternalAlertmanagersResponse: ExternalAlertmanagersResponse =
},
};
export function mockAlertmanagersResponse(server: SetupServer, response: ExternalAlertmanagersResponse) {
- server.use(rest.get('/api/v1/ngalert/alertmanagers', (req, res, ctx) => res(ctx.status(200), ctx.json(response))));
+ server.use(http.get('/api/v1/ngalert/alertmanagers', () => HttpResponse.json(response)));
}
export function mockAlertmanagerConfigResponse(
@@ -33,8 +34,8 @@ export function mockAlertmanagerConfigResponse(
response: AlertManagerCortexConfig
) {
server.use(
- rest.get(`/api/alertmanager/${getDatasourceAPIUid(alertManagerSourceName)}/config/api/v1/alerts`, (req, res, ctx) =>
- res(ctx.status(200), ctx.json(response))
+ http.get(`/api/alertmanager/${getDatasourceAPIUid(alertManagerSourceName)}/config/api/v1/alerts`, () =>
+ HttpResponse.json(response)
)
);
}
diff --git a/public/app/features/alerting/unified/mocks/plugins.ts b/public/app/features/alerting/unified/mocks/plugins.ts
index eb8a2b5eab7..df657222de9 100644
--- a/public/app/features/alerting/unified/mocks/plugins.ts
+++ b/public/app/features/alerting/unified/mocks/plugins.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { PluginMeta } from '@grafana/data';
@@ -7,8 +8,11 @@ import { SupportedPlugin } from '../types/pluginBridges';
export function mockPluginSettings(server: SetupServer, plugin: SupportedPlugin, response?: PluginMeta) {
server.use(
- rest.get(`/api/plugins/${plugin}/settings`, (_req, res, ctx) => {
- return response ? res(ctx.status(200), ctx.json(response)) : res(ctx.status(404));
+ http.get(`/api/plugins/${plugin}/settings`, () => {
+ if (response) {
+ return HttpResponse.json(response);
+ }
+ return HttpResponse.json({}, { status: 404 });
})
);
}
diff --git a/public/app/features/alerting/unified/mocks/rulerApi.ts b/public/app/features/alerting/unified/mocks/rulerApi.ts
index 71339a4cf72..d689d02382f 100644
--- a/public/app/features/alerting/unified/mocks/rulerApi.ts
+++ b/public/app/features/alerting/unified/mocks/rulerApi.ts
@@ -1,14 +1,11 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { RulerRuleGroupDTO, RulerRulesConfigDTO } from '../../../../types/unified-alerting-dto';
export function mockRulerRulesApiResponse(server: SetupServer, rulesSourceName: string, response: RulerRulesConfigDTO) {
- server.use(
- rest.get(`/api/ruler/${rulesSourceName}/api/v1/rules`, (req, res, ctx) =>
- res(ctx.json(response))
- )
- );
+ server.use(http.get(`/api/ruler/${rulesSourceName}/api/v1/rules`, () => HttpResponse.json(response)));
}
export function mockRulerRulesGroupApiResponse(
@@ -19,8 +16,6 @@ export function mockRulerRulesGroupApiResponse(
response: RulerRuleGroupDTO
) {
server.use(
- rest.get(`/api/ruler/${rulesSourceName}/api/v1/rules/${namespace}/${group}`, (req, res, ctx) =>
- res(ctx.json(response))
- )
+ http.get(`/api/ruler/${rulesSourceName}/api/v1/rules/${namespace}/${group}`, () => HttpResponse.json(response))
);
}
diff --git a/public/app/features/alerting/unified/mocks/templatesApi.ts b/public/app/features/alerting/unified/mocks/templatesApi.ts
index cb6d18d4cf3..d0e591fb3c5 100644
--- a/public/app/features/alerting/unified/mocks/templatesApi.ts
+++ b/public/app/features/alerting/unified/mocks/templatesApi.ts
@@ -1,12 +1,13 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { previewTemplateUrl, TemplatePreviewResponse } from '../api/templateApi';
export function mockPreviewTemplateResponse(server: SetupServer, response: TemplatePreviewResponse) {
- server.use(rest.post(previewTemplateUrl, (req, res, ctx) => res(ctx.status(200), ctx.json(response))));
+ server.use(http.post(previewTemplateUrl, () => HttpResponse.json(response)));
}
export function mockPreviewTemplateResponseRejected(server: SetupServer) {
- server.use(rest.post(previewTemplateUrl, (req, res, ctx) => res(ctx.status(500), ctx.json('error'))));
+ server.use(http.post(previewTemplateUrl, () => HttpResponse.json('error', { status: 500 })));
}
diff --git a/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx b/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx
index bb9f53b1afb..ab005ac3d48 100644
--- a/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx
+++ b/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx
@@ -1,7 +1,7 @@
-import 'whatwg-fetch'; // fetch polyfill
+import 'whatwg-fetch';
import { render as rtlRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { rest } from 'msw';
+import { HttpResponse, http } from 'msw';
import { setupServer, SetupServer } from 'msw/node';
import React, { ComponentProps } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
@@ -120,25 +120,19 @@ describe('browse-dashboards BrowseDashboardsPage', () => {
beforeAll(() => {
server = setupServer(
- rest.get('/api/folders/:uid', (_, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- title: folderA.item.title,
- uid: folderA.item.uid,
- })
- );
+ http.get('/api/folders/:uid', () => {
+ return HttpResponse.json({
+ title: folderA.item.title,
+ uid: folderA.item.uid,
+ });
}),
- rest.get('/api/search', (_, res, ctx) => {
- return res(ctx.status(200), ctx.json({}));
+ http.get('/api/search', () => {
+ return HttpResponse.json({});
}),
- rest.get('/api/search/sorting', (_, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- sortOptions: [],
- })
- );
+ http.get('/api/search/sorting', () => {
+ return HttpResponse.json({
+ sortOptions: [],
+ });
})
);
server.listen();
diff --git a/public/app/features/browse-dashboards/BrowseFolderAlertingPage.test.tsx b/public/app/features/browse-dashboards/BrowseFolderAlertingPage.test.tsx
index e7f01c2a7e1..9c101f9bb54 100644
--- a/public/app/features/browse-dashboards/BrowseFolderAlertingPage.test.tsx
+++ b/public/app/features/browse-dashboards/BrowseFolderAlertingPage.test.tsx
@@ -1,6 +1,6 @@
-import 'whatwg-fetch'; // fetch polyfill
+import 'whatwg-fetch';
import { render as rtlRender, screen } from '@testing-library/react';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
@@ -47,20 +47,17 @@ describe('browse-dashboards BrowseFolderAlertingPage', () => {
beforeAll(() => {
server = setupServer(
- rest.get('/api/folders/:uid', (_, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- title: mockFolderName,
- uid: mockFolderUid,
- })
- );
+ http.get('/api/folders/:uid', () => {
+ return HttpResponse.json({
+ title: mockFolderName,
+ uid: mockFolderUid,
+ });
}),
- rest.get('api/ruler/grafana/api/v1/rules', (_, res, ctx) => {
- return res(ctx.status(200), ctx.json(mockRulerRulesResponse));
+ http.get('api/ruler/grafana/api/v1/rules', () => {
+ return HttpResponse.json(mockRulerRulesResponse);
}),
- rest.get('api/prometheus/grafana/api/v1/rules', (_, res, ctx) => {
- return res(ctx.status(200), ctx.json(mockPrometheusRulesResponse));
+ http.get('api/prometheus/grafana/api/v1/rules', () => {
+ return HttpResponse.json(mockPrometheusRulesResponse);
})
);
server.listen();
diff --git a/public/app/features/browse-dashboards/BrowseFolderLibraryPanelsPage.test.tsx b/public/app/features/browse-dashboards/BrowseFolderLibraryPanelsPage.test.tsx
index b188fd20a93..1c6632d580b 100644
--- a/public/app/features/browse-dashboards/BrowseFolderLibraryPanelsPage.test.tsx
+++ b/public/app/features/browse-dashboards/BrowseFolderLibraryPanelsPage.test.tsx
@@ -1,6 +1,6 @@
-import 'whatwg-fetch'; // fetch polyfill
+import 'whatwg-fetch';
import { render as rtlRender, screen } from '@testing-library/react';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
@@ -47,25 +47,19 @@ describe('browse-dashboards BrowseFolderLibraryPanelsPage', () => {
beforeAll(() => {
server = setupServer(
- rest.get('/api/folders/:uid', (_, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- title: mockFolderName,
- uid: mockFolderUid,
- })
- );
+ http.get('/api/folders/:uid', () => {
+ return HttpResponse.json({
+ title: mockFolderName,
+ uid: mockFolderUid,
+ });
}),
- rest.get('/api/library-elements', (_, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- result: mockLibraryElementsResponse,
- })
- );
+ http.get('/api/library-elements', () => {
+ return HttpResponse.json({
+ result: mockLibraryElementsResponse,
+ });
}),
- rest.get('/api/search/sorting', (_, res, ctx) => {
- return res(ctx.status(200), ctx.json({}));
+ http.get('/api/search/sorting', () => {
+ return HttpResponse.json({});
})
);
server.listen();
diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx
index e5d26f503a8..56970d1487f 100644
--- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx
+++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboard.test.tsx
@@ -1,9 +1,9 @@
+import 'whatwg-fetch';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
-import 'whatwg-fetch';
import { BootData, DataQuery } from '@grafana/data/src';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
import { reportInteraction, setEchoSrv } from '@grafana/runtime';
@@ -87,20 +87,27 @@ afterEach(() => {
});
const getNonExistentPublicDashboardResponse = () =>
- rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
- return res(
- ctx.status(404),
- ctx.json({
+ http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', () => {
+ return HttpResponse.json(
+ {
message: 'Public dashboard not found',
messageId: 'publicdashboards.notFound',
statusCode: 404,
traceID: '',
- })
+ },
+ {
+ status: 404,
+ }
);
});
const getErrorPublicDashboardResponse = () =>
- rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
- return res(ctx.status(500));
+ http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', () => {
+ return HttpResponse.json(
+ {},
+ {
+ status: 500,
+ }
+ );
});
const alertTests = () => {
@@ -277,14 +284,11 @@ describe('SharePublic - Already persisted', () => {
});
it('when modal is opened, then time range switch is enabled and not checked when its not checked in the db', async () => {
server.use(
- rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- ...pubdashResponse,
- timeSelectionEnabled: false,
- })
- );
+ http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', () => {
+ return HttpResponse.json({
+ ...pubdashResponse,
+ timeSelectionEnabled: false,
+ });
})
);
@@ -303,17 +307,16 @@ describe('SharePublic - Already persisted', () => {
});
it('when pubdash is disabled in the db, then link url is not copyable and switch is checked', async () => {
server.use(
- rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- isEnabled: false,
- annotationsEnabled: false,
- uid: 'a-uid',
- dashboardUid: req.params.dashboardUid,
- accessToken: 'an-access-token',
- })
- );
+ http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', ({ request }) => {
+ const url = new URL(request.url);
+ const dashboardUid = url.searchParams.get('dashboardUid');
+ return HttpResponse.json({
+ isEnabled: false,
+ annotationsEnabled: false,
+ uid: 'a-uid',
+ dashboardUid,
+ accessToken: 'an-access-token',
+ });
})
);
@@ -339,15 +342,14 @@ describe('SharePublic - Report interactions', () => {
jest.clearAllMocks();
server.use(getExistentPublicDashboardResponse());
server.use(
- rest.patch('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', (req, res, ctx) =>
- res(
- ctx.status(200),
- ctx.json({
- ...pubdashResponse,
- dashboardUid: req.params.dashboardUid,
- })
- )
- )
+ http.patch('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', ({ request }) => {
+ const url = new URL(request.url);
+ const dashboardUid = url.searchParams.get('dashboardUid');
+ return HttpResponse.json({
+ ...pubdashResponse,
+ dashboardUid,
+ });
+ })
);
});
diff --git a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/utilsTest.tsx b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/utilsTest.tsx
index 3d2bc135502..382c499e3a5 100644
--- a/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/utilsTest.tsx
+++ b/public/app/features/dashboard/components/ShareModal/SharePublicDashboard/utilsTest.tsx
@@ -1,5 +1,6 @@
+import 'whatwg-fetch';
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import React from 'react';
import { Provider } from 'react-redux';
@@ -32,15 +33,14 @@ export const pubdashResponse: sharePublicDashboardUtils.PublicDashboard = {
};
export const getExistentPublicDashboardResponse = (publicDashboard?: Partial) =>
- rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
- return res(
- ctx.status(200),
- ctx.json({
- ...pubdashResponse,
- ...publicDashboard,
- dashboardUid: req.params.dashboardUid,
- })
- );
+ http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', ({ request }) => {
+ const url = new URL(request.url);
+ const dashboardUid = url.searchParams.get('dashboardUid');
+ return HttpResponse.json({
+ ...pubdashResponse,
+ ...publicDashboard,
+ dashboardUid,
+ });
});
export const renderSharePublicDashboard = async (
diff --git a/public/app/features/manage-dashboards/components/PublicDashboardListTable/PublicDashboardListTable.test.tsx b/public/app/features/manage-dashboards/components/PublicDashboardListTable/PublicDashboardListTable.test.tsx
index 5c69c16bc2c..f98ecb38cda 100644
--- a/public/app/features/manage-dashboards/components/PublicDashboardListTable/PublicDashboardListTable.test.tsx
+++ b/public/app/features/manage-dashboards/components/PublicDashboardListTable/PublicDashboardListTable.test.tsx
@@ -1,8 +1,8 @@
+import 'whatwg-fetch';
import { render, screen, waitForElementToBeRemoved, within } from '@testing-library/react';
-import { rest } from 'msw';
+import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';
-import 'whatwg-fetch';
import { BrowserRouter } from 'react-router-dom';
import { TestProvider } from 'test/helpers/TestProvider';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
@@ -60,10 +60,13 @@ const paginationResponse: Omit
- res(ctx.status(200), ctx.json({ ...paginationResponse, publicDashboards: publicDashboardListResponse }))
+ http.get('/api/dashboards/public-dashboards', () =>
+ HttpResponse.json({
+ ...paginationResponse,
+ publicDashboards: publicDashboardListResponse,
+ })
),
- rest.delete('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', (_, res, ctx) => res(ctx.status(200)))
+ http.delete('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', () => HttpResponse.json({}))
);
jest.mock('@grafana/runtime', () => ({
@@ -122,8 +125,8 @@ describe('Show table', () => {
};
server.use(
- rest.get('/api/dashboards/public-dashboards', (req, res, ctx) => {
- return res(ctx.status(200), ctx.json(emptyListRS));
+ http.get('/api/dashboards/public-dashboards', () => {
+ return HttpResponse.json(emptyListRS);
})
);
@@ -171,8 +174,8 @@ describe('Orphaned public dashboard', () => {
publicDashboards: [...publicDashboardListResponse, ...orphanedDashboardListResponse],
};
server.use(
- rest.get('/api/dashboards/public-dashboards', (req, res, ctx) => {
- return res(ctx.status(200), ctx.json(response));
+ http.get('/api/dashboards/public-dashboards', () => {
+ return HttpResponse.json(response);
})
);
jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(true);
diff --git a/public/app/features/plugins/loader/pluginLoader.mock.ts b/public/app/features/plugins/loader/pluginLoader.mock.ts
index 530b245a592..c683090ad6c 100644
--- a/public/app/features/plugins/loader/pluginLoader.mock.ts
+++ b/public/app/features/plugins/loader/pluginLoader.mock.ts
@@ -1,4 +1,5 @@
-import { rest } from 'msw';
+import 'whatwg-fetch';
+import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
export const mockSystemModule = `System.register(['./dependencyA'], function (_export, _context) {
@@ -85,38 +86,104 @@ export const mockModuleWithDefineMethod = `ace.define(function() {
});`;
const server = setupServer(
- rest.get('/public/plugins/mockAmdModule/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModule))
+ http.get(
+ '/public/plugins/mockAmdModule/module.js',
+ () =>
+ new HttpResponse(mockAmdModule, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockSystemModule/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockSystemModule))
+ http.get(
+ '/public/plugins/mockSystemModule/module.js',
+ () =>
+ new HttpResponse(mockSystemModule, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/my-plugin/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModule))
+ http.get(
+ 'http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/my-plugin/module.js',
+ () =>
+ new HttpResponse(mockAmdModule, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleNamedNoDeps/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedNoDeps))
+ http.get(
+ '/public/plugins/mockAmdModuleNamedNoDeps/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleNamedNoDeps, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleNamedWithDeps/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedWithDeps))
+ http.get(
+ '/public/plugins/mockAmdModuleNamedWithDeps/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleNamedWithDeps, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleNamedWithDeps2/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedWithDeps2))
+ http.get(
+ '/public/plugins/mockAmdModuleNamedWithDeps2/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleNamedWithDeps2, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleNamedWithDeps3/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedWithDeps3))
+ http.get(
+ '/public/plugins/mockAmdModuleNamedWithDeps3/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleNamedWithDeps3, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleOnlyFunction/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleOnlyFunction))
+ http.get(
+ '/public/plugins/mockAmdModuleOnlyFunction/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleOnlyFunction, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleWithComments/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleWithComments))
+ http.get(
+ '/public/plugins/mockAmdModuleWithComments/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleWithComments, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockAmdModuleWithComments2/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleWithComments2))
+ http.get(
+ '/public/plugins/mockAmdModuleWithComments2/module.js',
+ () =>
+ new HttpResponse(mockAmdModuleWithComments2, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
),
- rest.get('/public/plugins/mockModuleWithDefineMethod/module.js', async (_req, res, ctx) =>
- res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockModuleWithDefineMethod))
+ http.get(
+ '/public/plugins/mockModuleWithDefineMethod/module.js',
+ () =>
+ new HttpResponse(mockModuleWithDefineMethod, {
+ headers: {
+ 'Content-Type': 'text/javascript',
+ },
+ })
)
);
diff --git a/public/app/features/plugins/loader/systemjsHooks.test.ts b/public/app/features/plugins/loader/systemjsHooks.test.ts
index 08d33e2c644..9cd499b0c04 100644
--- a/public/app/features/plugins/loader/systemjsHooks.test.ts
+++ b/public/app/features/plugins/loader/systemjsHooks.test.ts
@@ -28,11 +28,13 @@ describe('SystemJS Loader Hooks', () => {
const originalFetch = systemJSPrototype.fetch;
const originalResolve = systemJSPrototype.resolve;
- systemJSPrototype.resolve = (moduleId: string) => moduleId;
- systemJSPrototype.shouldFetch = () => true;
-
beforeAll(() => {
server.listen();
+ systemJSPrototype.resolve = (moduleId: string) => moduleId;
+ systemJSPrototype.shouldFetch = () => true;
+ // because server.listen() patches fetch, we need to reassign this to the systemJSPrototype
+ // this is identical to what happens in the original code: https://github.com/systemjs/systemjs/blob/main/src/features/fetch-load.js#L12
+ systemJSPrototype.fetch = window.fetch;
});
afterEach(() => server.resetHandlers());
afterAll(() => {
@@ -43,7 +45,11 @@ describe('SystemJS Loader Hooks', () => {
describe('decorateSystemJSFetch', () => {
it('wraps AMD modules in an AMD iife', async () => {
- const basicResult = await decorateSystemJSFetch(originalFetch, '/public/plugins/mockAmdModule/module.js', {});
+ const basicResult = await decorateSystemJSFetch(
+ systemJSPrototype.fetch,
+ '/public/plugins/mockAmdModule/module.js',
+ {}
+ );
const basicSource = await basicResult.text();
const basicExpected = `(function(define) {
${mockAmdModule}
@@ -51,7 +57,7 @@ describe('SystemJS Loader Hooks', () => {
expect(basicSource).toBe(basicExpected);
const mockAmdModuleNamedNoDepsResult = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedNoDeps/module.js',
{}
);
@@ -63,7 +69,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedNoDepsSource).toBe(mockAmdModuleNamedNoDepsExpected);
const mockAmdModuleNamedWithDepsResult = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedWithDeps/module.js',
{}
);
@@ -75,7 +81,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedWithDepsSource).toBe(mockAmdModuleNamedWithDepsExpected);
const mockAmdModuleNamedWithDeps2Result = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedWithDeps2/module.js',
{}
);
@@ -87,7 +93,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedWithDeps2Source).toBe(mockAmdModuleNamedWithDeps2Expected);
const mockAmdModuleNamedWithDeps3Result = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedWithDeps3/module.js',
{}
);
@@ -99,7 +105,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedWithDeps3Source).toBe(mockAmdModuleNamedWithDeps3Expected);
const mockAmdModuleOnlyFunctionResult = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleOnlyFunction/module.js',
{}
);
@@ -111,7 +117,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleOnlyFunctionSource).toBe(mockAmdModuleOnlyFunctionExpected);
const mockAmdModuleWithCommentsResult = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleWithComments/module.js',
{}
);
@@ -123,7 +129,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleWithCommentsSource).toBe(mockAmdModuleWithCommentsExpected);
const mockAmdModuleWithComments2Result = await decorateSystemJSFetch(
- originalFetch,
+ systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleWithComments2/module.js',
{}
);
@@ -136,14 +142,14 @@ describe('SystemJS Loader Hooks', () => {
});
it("doesn't wrap system modules in an AMD iife", async () => {
const url = '/public/plugins/mockSystemModule/module.js';
- const result = await decorateSystemJSFetch(originalFetch, url, {});
+ const result = await decorateSystemJSFetch(systemJSPrototype.fetch, url, {});
const source = await result.text();
expect(source).toBe(mockSystemModule);
});
it("doesn't wrap modules with a define method in an AMD iife", async () => {
const url = '/public/plugins/mockModuleWithDefineMethod/module.js';
- const result = await decorateSystemJSFetch(originalFetch, url, {});
+ const result = await decorateSystemJSFetch(systemJSPrototype.fetch, url, {});
const source = await result.text();
expect(source).toBe(mockModuleWithDefineMethod);
@@ -151,13 +157,13 @@ describe('SystemJS Loader Hooks', () => {
it('only transforms plugin source code hosted on cdn with cdn paths', async () => {
config.pluginsCDNBaseURL = 'http://my-cdn.com/plugins';
const cdnUrl = 'http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/my-plugin/module.js';
- const cdnResult = await decorateSystemJSFetch(originalFetch, cdnUrl, {});
+ const cdnResult = await decorateSystemJSFetch(systemJSPrototype.fetch, cdnUrl, {});
const cdnSource = await cdnResult.text();
expect(cdnSource).toContain('var pluginPath = "http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/";');
const url = '/public/plugins/mockAmdModule/module.js';
- const result = await decorateSystemJSFetch(originalFetch, url, {});
+ const result = await decorateSystemJSFetch(systemJSPrototype.fetch, url, {});
const source = await result.text();
expect(source).toContain('var pluginPath = "/public/plugins/";');
});
diff --git a/public/test/jest-resolver.js b/public/test/jest-resolver.js
index 75b29ad00dc..40046b872d5 100644
--- a/public/test/jest-resolver.js
+++ b/public/test/jest-resolver.js
@@ -27,6 +27,23 @@ module.exports = (path, options) => {
delete pkg['exports'];
delete pkg['module'];
}
+ // Jest + jsdom acts like a browser (i.e., it looks for "browser" imports
+ // under pkg.exports), but msw knows that you're operating in a Node
+ // environment:
+ //
+ // https://github.com/mswjs/msw/issues/1786#issuecomment-1782559851
+ //
+ // The MSW project's recommended workaround is to disable Jest's
+ // customExportConditions completely, so no packages use their browser's
+ // versions. We'll instead clear export conditions only for MSW.
+ //
+ // Taken from https://github.com/mswjs/msw/issues/1786#issuecomment-1787730599
+ if (pkg.name === 'msw') {
+ delete pkg.exports['./node'].browser;
+ }
+ if (pkg.name === '@mswjs/interceptors') {
+ delete pkg.exports;
+ }
return pkg;
},
});
diff --git a/yarn.lock b/yarn.lock
index a3bfcbd3626..01192c34e23 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1865,6 +1865,24 @@ __metadata:
languageName: node
linkType: hard
+"@bundled-es-modules/cookie@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "@bundled-es-modules/cookie@npm:2.0.0"
+ dependencies:
+ cookie: "npm:^0.5.0"
+ checksum: 10/c8ef02aa5d3f6c786cfa407e1c93b4af29c600eb09990973f47a7a49e4771c1bec37c8f8e567638bb9cbc41f4e38d065ff1d8eaf9bf91f0c3613a6d60bc82c8c
+ languageName: node
+ linkType: hard
+
+"@bundled-es-modules/statuses@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "@bundled-es-modules/statuses@npm:1.0.1"
+ dependencies:
+ statuses: "npm:^2.0.1"
+ checksum: 10/9bf6a2bcf040a66fb805da0e1446041fd9def7468bb5da29c5ce02adf121a3f7cec123664308059a62a46fcaee666add83094b76df6dce72e5cafa8e6bebe60d
+ languageName: node
+ linkType: hard
+
"@colors/colors@npm:1.5.0":
version: 1.5.0
resolution: "@colors/colors@npm:1.5.0"
@@ -4298,6 +4316,45 @@ __metadata:
languageName: node
linkType: hard
+"@inquirer/confirm@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "@inquirer/confirm@npm:3.0.0"
+ dependencies:
+ "@inquirer/core": "npm:^7.0.0"
+ "@inquirer/type": "npm:^1.2.0"
+ checksum: 10/ed16dc0e5b22115474853ca57dbe3dacdcd15bcb37cc50020e8e76ff8d0875d62d8b63b93b3092c653faeb6c83a139eac997ff05638b0f1f78ae919f29ee29d4
+ languageName: node
+ linkType: hard
+
+"@inquirer/core@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "@inquirer/core@npm:7.0.0"
+ dependencies:
+ "@inquirer/type": "npm:^1.2.0"
+ "@types/mute-stream": "npm:^0.0.4"
+ "@types/node": "npm:^20.11.16"
+ "@types/wrap-ansi": "npm:^3.0.0"
+ ansi-escapes: "npm:^4.3.2"
+ chalk: "npm:^4.1.2"
+ cli-spinners: "npm:^2.9.2"
+ cli-width: "npm:^4.1.0"
+ figures: "npm:^3.2.0"
+ mute-stream: "npm:^1.0.0"
+ run-async: "npm:^3.0.0"
+ signal-exit: "npm:^4.1.0"
+ strip-ansi: "npm:^6.0.1"
+ wrap-ansi: "npm:^6.2.0"
+ checksum: 10/78c0ef4bb82cb7be23f16a80c9cff02839c77e378d272327f49878788a4c3b1cc00137387317053d242a87634954850a4d2546b3e48b1abd27130a21f598afef
+ languageName: node
+ linkType: hard
+
+"@inquirer/type@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "@inquirer/type@npm:1.2.0"
+ checksum: 10/12f68a16d8995efb409bd243d6ccc501b366e8009630a075071a9d9497cebd36bbd6c46d7d59b37435629e5e50236394679f414f7676b68b913ecc28a85cba0a
+ languageName: node
+ linkType: hard
+
"@internationalized/date@npm:^3.5.1":
version: 3.5.1
resolution: "@internationalized/date@npm:3.5.1"
@@ -5134,6 +5191,13 @@ __metadata:
languageName: node
linkType: hard
+"@mswjs/cookies@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "@mswjs/cookies@npm:1.1.0"
+ checksum: 10/168ed1966e579a4f454e6d2af5a015150cca570ac4c660f5b656e7bc021afacbf0b3d4ed3d03e9293550f3965c28ce1e293fa7037c6cf46ed7e268e21a1053a4
+ languageName: node
+ linkType: hard
+
"@mswjs/interceptors@npm:^0.17.10":
version: 0.17.10
resolution: "@mswjs/interceptors@npm:0.17.10"
@@ -5150,6 +5214,20 @@ __metadata:
languageName: node
linkType: hard
+"@mswjs/interceptors@npm:^0.25.16":
+ version: 0.25.16
+ resolution: "@mswjs/interceptors@npm:0.25.16"
+ dependencies:
+ "@open-draft/deferred-promise": "npm:^2.2.0"
+ "@open-draft/logger": "npm:^0.3.0"
+ "@open-draft/until": "npm:^2.0.0"
+ is-node-process: "npm:^1.2.0"
+ outvariant: "npm:^1.2.1"
+ strict-event-emitter: "npm:^0.5.1"
+ checksum: 10/d8fb74db45a63971e9da7367c8d120343c8f49fec7bcc3f0c77c04c3f628d307b70875f52e4a99df561547b92d0d53edacc421e42d69940d44999254b5d028b5
+ languageName: node
+ linkType: hard
+
"@ndelangen/get-tarball@npm:^3.0.7":
version: 3.0.7
resolution: "@ndelangen/get-tarball@npm:3.0.7"
@@ -5588,6 +5666,23 @@ __metadata:
languageName: node
linkType: hard
+"@open-draft/deferred-promise@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "@open-draft/deferred-promise@npm:2.2.0"
+ checksum: 10/bc3bb1668a555bb87b33383cafcf207d9561e17d2ca0d9e61b7ce88e82b66e36a333d3676c1d39eb5848022c03c8145331fcdc828ba297f88cb1de9c5cef6c19
+ languageName: node
+ linkType: hard
+
+"@open-draft/logger@npm:^0.3.0":
+ version: 0.3.0
+ resolution: "@open-draft/logger@npm:0.3.0"
+ dependencies:
+ is-node-process: "npm:^1.2.0"
+ outvariant: "npm:^1.4.0"
+ checksum: 10/7a280f170bcd4e91d3eedbefe628efd10c3bd06dd2461d06a7fdbced89ef457a38785847f88cc630fb4fd7dfa176d6f77aed17e5a9b08000baff647433b5ff78
+ languageName: node
+ linkType: hard
+
"@open-draft/until@npm:^1.0.3":
version: 1.0.3
resolution: "@open-draft/until@npm:1.0.3"
@@ -5595,6 +5690,13 @@ __metadata:
languageName: node
linkType: hard
+"@open-draft/until@npm:^2.0.0, @open-draft/until@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "@open-draft/until@npm:2.1.0"
+ checksum: 10/622be42950afc8e89715d0fd6d56cbdcd13e36625e23b174bd3d9f06f80e25f9adf75d6698af93bca1e1bf465b9ce00ec05214a12189b671fb9da0f58215b6f4
+ languageName: node
+ linkType: hard
+
"@opentelemetry/api-logs@npm:0.45.1":
version: 0.45.1
resolution: "@opentelemetry/api-logs@npm:0.45.1"
@@ -8581,6 +8683,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/cookie@npm:^0.6.0":
+ version: 0.6.0
+ resolution: "@types/cookie@npm:0.6.0"
+ checksum: 10/b883348d5bf88695fbc2c2276b1c49859267a55cae3cf11ea1dccc1b3be15b466e637ce3242109ba27d616c77c6aa4efe521e3d557110b4fdd9bc332a12445c2
+ languageName: node
+ linkType: hard
+
"@types/cross-spawn@npm:^6.0.2":
version: 6.0.3
resolution: "@types/cross-spawn@npm:6.0.3"
@@ -9363,6 +9472,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/mute-stream@npm:^0.0.4":
+ version: 0.0.4
+ resolution: "@types/mute-stream@npm:0.0.4"
+ dependencies:
+ "@types/node": "npm:*"
+ checksum: 10/af8d83ad7b68ea05d9357985daf81b6c9b73af4feacb2f5c2693c7fd3e13e5135ef1bd083ce8d5bdc8e97acd28563b61bb32dec4e4508a8067fcd31b8a098632
+ languageName: node
+ linkType: hard
+
"@types/node-fetch@npm:^2.6.4":
version: 2.6.4
resolution: "@types/node-fetch@npm:2.6.4"
@@ -9382,7 +9500,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/node@npm:*, @types/node@npm:20.11.17, @types/node@npm:>=13.7.0":
+"@types/node@npm:*, @types/node@npm:20.11.17, @types/node@npm:>=13.7.0, @types/node@npm:^20.11.16":
version: 20.11.17
resolution: "@types/node@npm:20.11.17"
dependencies:
@@ -9808,6 +9926,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/statuses@npm:^2.0.4":
+ version: 2.0.4
+ resolution: "@types/statuses@npm:2.0.4"
+ checksum: 10/3a806c3b96d1845e3e7441fbf0839037e95f717334760ddb7c29223c9a34a7206b68e2998631f89f1a1e3ef5b67b15652f6e8fa14987ebd7f6d38587c1bffd18
+ languageName: node
+ linkType: hard
+
"@types/string-hash@npm:1.1.3":
version: 1.1.3
resolution: "@types/string-hash@npm:1.1.3"
@@ -9912,6 +10037,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/wrap-ansi@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "@types/wrap-ansi@npm:3.0.0"
+ checksum: 10/8aa644946ca4e859668c36b8e2bcf2ac4bdee59dac760414730ea57be8a93ae9166ebd40a088f2ab714843aaea2a2a67f0e6e6ec11cfc9c8701b2466ca1c4089
+ languageName: node
+ linkType: hard
+
"@types/ws@npm:^8.5.5":
version: 8.5.5
resolution: "@types/ws@npm:8.5.5"
@@ -11114,7 +11246,7 @@ __metadata:
languageName: node
linkType: hard
-"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0":
+"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2":
version: 4.3.2
resolution: "ansi-escapes@npm:4.3.2"
dependencies:
@@ -12814,6 +12946,13 @@ __metadata:
languageName: node
linkType: hard
+"cli-spinners@npm:^2.9.2":
+ version: 2.9.2
+ resolution: "cli-spinners@npm:2.9.2"
+ checksum: 10/a0a863f442df35ed7294424f5491fa1756bd8d2e4ff0c8736531d886cec0ece4d85e8663b77a5afaf1d296e3cbbebff92e2e99f52bbea89b667cbe789b994794
+ languageName: node
+ linkType: hard
+
"cli-table3@npm:^0.6.1, cli-table3@npm:~0.6.1":
version: 0.6.3
resolution: "cli-table3@npm:0.6.3"
@@ -12844,6 +12983,13 @@ __metadata:
languageName: node
linkType: hard
+"cli-width@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "cli-width@npm:4.1.0"
+ checksum: 10/b58876fbf0310a8a35c79b72ecfcf579b354e18ad04e6b20588724ea2b522799a758507a37dfe132fafaf93a9922cafd9514d9e1598e6b2cd46694853aed099f
+ languageName: node
+ linkType: hard
+
"cliui@npm:^7.0.2":
version: 7.0.4
resolution: "cliui@npm:7.0.4"
@@ -13421,6 +13567,13 @@ __metadata:
languageName: node
linkType: hard
+"cookie@npm:^0.5.0":
+ version: 0.5.0
+ resolution: "cookie@npm:0.5.0"
+ checksum: 10/aae7911ddc5f444a9025fbd979ad1b5d60191011339bce48e555cb83343d0f98b865ff5c4d71fecdfb8555a5cafdc65632f6fce172f32aaf6936830a883a0380
+ languageName: node
+ linkType: hard
+
"copy-to-clipboard@npm:^3.3.1":
version: 3.3.1
resolution: "copy-to-clipboard@npm:3.3.1"
@@ -18231,7 +18384,7 @@ __metadata:
mousetrap: "npm:1.6.5"
mousetrap-global-bind: "npm:1.1.0"
moveable: "npm:0.53.0"
- msw: "npm:1.3.2"
+ msw: "npm:2.2.0"
mutationobserver-shim: "npm:0.3.7"
nanoid: "npm:^5.0.4"
ngtemplate-loader: "npm:2.1.0"
@@ -18564,6 +18717,13 @@ __metadata:
languageName: node
linkType: hard
+"headers-polyfill@npm:^4.0.2":
+ version: 4.0.2
+ resolution: "headers-polyfill@npm:4.0.2"
+ checksum: 10/70b53abf48a1d50760150624d6c7ca974a0d286ba102e411538f6dad6687ce51ce7cc60197e326df96f844548d6ff77d900e28c3cdbc0ba1fe09a05eae47156a
+ languageName: node
+ linkType: hard
+
"heimdalljs-logger@npm:^0.1.10, heimdalljs-logger@npm:^0.1.7":
version: 0.1.10
resolution: "heimdalljs-logger@npm:0.1.10"
@@ -22717,6 +22877,38 @@ __metadata:
languageName: node
linkType: hard
+"msw@npm:2.2.0":
+ version: 2.2.0
+ resolution: "msw@npm:2.2.0"
+ dependencies:
+ "@bundled-es-modules/cookie": "npm:^2.0.0"
+ "@bundled-es-modules/statuses": "npm:^1.0.1"
+ "@inquirer/confirm": "npm:^3.0.0"
+ "@mswjs/cookies": "npm:^1.1.0"
+ "@mswjs/interceptors": "npm:^0.25.16"
+ "@open-draft/until": "npm:^2.1.0"
+ "@types/cookie": "npm:^0.6.0"
+ "@types/statuses": "npm:^2.0.4"
+ chalk: "npm:^4.1.2"
+ graphql: "npm:^16.8.1"
+ headers-polyfill: "npm:^4.0.2"
+ is-node-process: "npm:^1.2.0"
+ outvariant: "npm:^1.4.2"
+ path-to-regexp: "npm:^6.2.0"
+ strict-event-emitter: "npm:^0.5.1"
+ type-fest: "npm:^4.9.0"
+ yargs: "npm:^17.7.2"
+ peerDependencies:
+ typescript: ">= 4.7.x <= 5.3.x"
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+ bin:
+ msw: cli/index.js
+ checksum: 10/36e6a1f0bc89d1c84bf24c1cf7ca7c3fe5d5b032c825d52a832e9b815830976a86c17a8c3f1f506db720f44e99d04c9302e014cf569b51b2d2af62562a9fe62a
+ languageName: node
+ linkType: hard
+
"multicast-dns@npm:^7.2.4":
version: 7.2.4
resolution: "multicast-dns@npm:7.2.4"
@@ -22756,7 +22948,7 @@ __metadata:
languageName: node
linkType: hard
-"mute-stream@npm:~1.0.0":
+"mute-stream@npm:^1.0.0, mute-stream@npm:~1.0.0":
version: 1.0.0
resolution: "mute-stream@npm:1.0.0"
checksum: 10/36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7
@@ -23607,10 +23799,10 @@ __metadata:
languageName: node
linkType: hard
-"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0":
- version: 1.4.0
- resolution: "outvariant@npm:1.4.0"
- checksum: 10/07b9bcb9b3a2ff1b3db02af6b07d70e663082b30ddc08ff475d7c85fc623fdcc4433a4ab5b88f6902b62dbb284eef1be386aa537e14cef0519fad887ec483054
+"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0, outvariant@npm:^1.4.2":
+ version: 1.4.2
+ resolution: "outvariant@npm:1.4.2"
+ checksum: 10/f16ba035fb65d1cbe7d2e06693dd42183c46bc8456713d9ddb5182d067defa7d78217edab0a2d3e173d3bacd627b2bd692195c7087c225b82548fbf52c677b38
languageName: node
linkType: hard
@@ -27278,6 +27470,13 @@ __metadata:
languageName: node
linkType: hard
+"run-async@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "run-async@npm:3.0.0"
+ checksum: 10/97fb8747f7765b77ebcd311d3a33548099336f04c6434e0763039b98c1de0f1b4421000695aff8751f309c0b995d8dfd620c1f1e4c35572da38c101488165305
+ languageName: node
+ linkType: hard
+
"run-parallel@npm:^1.1.9":
version: 1.2.0
resolution: "run-parallel@npm:1.2.0"
@@ -27732,6 +27931,13 @@ __metadata:
languageName: node
linkType: hard
+"signal-exit@npm:^4.1.0":
+ version: 4.1.0
+ resolution: "signal-exit@npm:4.1.0"
+ checksum: 10/c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f
+ languageName: node
+ linkType: hard
+
"sigstore@npm:^1.3.0, sigstore@npm:^1.4.0":
version: 1.9.0
resolution: "sigstore@npm:1.9.0"
@@ -28376,6 +28582,13 @@ __metadata:
languageName: node
linkType: hard
+"statuses@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "statuses@npm:2.0.1"
+ checksum: 10/18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb
+ languageName: node
+ linkType: hard
+
"stop-iteration-iterator@npm:^1.0.0":
version: 1.0.0
resolution: "stop-iteration-iterator@npm:1.0.0"
@@ -28518,6 +28731,13 @@ __metadata:
languageName: node
linkType: hard
+"strict-event-emitter@npm:^0.5.1":
+ version: 0.5.1
+ resolution: "strict-event-emitter@npm:0.5.1"
+ checksum: 10/25c84d88be85940d3547db665b871bfecea4ea0bedfeb22aae8db48126820cfb2b0bc2fba695392592a09b1aa36b686d6eede499e1ecd151593c03fe5a50d512
+ languageName: node
+ linkType: hard
+
"string-hash@npm:^1.1.3":
version: 1.1.3
resolution: "string-hash@npm:1.1.3"
@@ -29819,6 +30039,13 @@ __metadata:
languageName: node
linkType: hard
+"type-fest@npm:^4.9.0":
+ version: 4.10.2
+ resolution: "type-fest@npm:4.10.2"
+ checksum: 10/2b1ad1270d9fabeeb506ba831d513caeb05bfc852e5e012511d785ce9dc68d773fe0a42bddf857a362c7f3406244809c5b8a698b743bb7617d4a8c470672087f
+ languageName: node
+ linkType: hard
+
"type-is@npm:~1.6.18":
version: 1.6.18
resolution: "type-is@npm:1.6.18"
@@ -31485,7 +31712,7 @@ __metadata:
languageName: node
linkType: hard
-"yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2":
+"yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
version: 17.7.2
resolution: "yargs@npm:17.7.2"
dependencies: