Chore: Move feature toggles test util to test/test-utils (#111173)

This commit is contained in:
Tom Ratcliffe
2025-10-21 10:12:40 +01:00
committed by GitHub
parent 5c97059d5c
commit d1b9543189
12 changed files with 73 additions and 69 deletions
@@ -2,7 +2,7 @@ import { UserEvent } from '@testing-library/user-event';
import * as React from 'react';
import { renderRuleEditor, ui } from 'test/helpers/alertingRuleEditor';
import { clickSelectOption } from 'test/helpers/selectOptionInTest';
import { screen } from 'test/test-utils';
import { screen, testWithFeatureToggles } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { FeatureToggles } from '@grafana/data';
@@ -15,7 +15,6 @@ import { grantUserPermissions, mockDataSource } from './mocks';
import { grafanaRulerGroup } from './mocks/grafanaRulerApi';
import { captureRequests, serializeRequests } from './mocks/server/events';
import { FOLDER_TITLE_HAPPY_PATH } from './mocks/server/handlers/search';
import { testWithFeatureToggles } from './test/test-utils';
import { setupDataSources } from './testSetup/datasources';
import { setupPluginsExtensionsHook } from './testSetup/plugins';
@@ -72,7 +71,7 @@ describe('RuleEditor grafana recording rules', () => {
});
const testCreateGrafanaRR = (featureToggles: Array<keyof FeatureToggles>, testName: string) => {
testWithFeatureToggles(featureToggles);
testWithFeatureToggles({ enable: featureToggles });
it(testName, async () => {
const capture = captureRequests((r) => r.method === 'POST' && r.url.includes('/api/ruler/'));
@@ -98,7 +97,7 @@ describe('RuleEditor grafana recording rules', () => {
};
const testCreateGrafanaRRWithInvalidMetricName = (featureToggles: Array<keyof FeatureToggles>, testName: string) => {
testWithFeatureToggles(featureToggles);
testWithFeatureToggles({ enable: featureToggles });
it(testName, async () => {
const capture = captureRequests((r) => r.method === 'POST' && r.url.includes('/api/ruler/'));
@@ -1,4 +1,4 @@
import { render, waitFor } from 'test/test-utils';
import { render, testWithFeatureToggles, waitFor } from 'test/test-utils';
import { byLabelText, byRole } from 'testing-library-selector';
import { setPluginComponentsHook, setPluginLinksHook } from '@grafana/runtime';
@@ -7,7 +7,6 @@ import { AccessControlAction } from 'app/types/accessControl';
import { setupMswServer } from '../../mockApi';
import { grantUserPermissions } from '../../mocks';
import { alertingFactory } from '../../mocks/server/db';
import { testWithFeatureToggles } from '../../test/test-utils';
import ImportToGMARules from './ImportToGMARules';
@@ -49,7 +48,7 @@ alertingFactory.dataSource.mimir().build({ meta: { alerting: true } });
describe('ImportToGMARules', () => {
grantUserPermissions([AccessControlAction.AlertingRuleExternalRead, AccessControlAction.AlertingRuleCreate]);
testWithFeatureToggles(['alertingImportYAMLUI', 'alertingMigrationUI']);
testWithFeatureToggles({ enable: ['alertingImportYAMLUI', 'alertingMigrationUI'] });
it('should render the import source options', () => {
render(<ImportToGMARules />);
@@ -2,7 +2,7 @@ import { UserEvent } from '@testing-library/user-event';
import { ReactNode } from 'react';
import { GrafanaRuleFormStep, renderRuleEditor, ui } from 'test/helpers/alertingRuleEditor';
import { clickSelectOption } from 'test/helpers/selectOptionInTest';
import { screen, waitFor, within } from 'test/test-utils';
import { screen, testWithFeatureToggles, waitFor, within } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { setPluginLinksHook } from '@grafana/runtime';
@@ -13,7 +13,6 @@ import { setAlertmanagerChoices } from 'app/features/alerting/unified/mocks/serv
import { PROMETHEUS_DATASOURCE_UID } from 'app/features/alerting/unified/mocks/server/constants';
import { captureRequests, serializeRequests } from 'app/features/alerting/unified/mocks/server/events';
import { FOLDER_TITLE_HAPPY_PATH } from 'app/features/alerting/unified/mocks/server/handlers/search';
import { testWithFeatureToggles } from 'app/features/alerting/unified/test/test-utils';
import { setupDataSources } from 'app/features/alerting/unified/testSetup/datasources';
import { DataSourceType } from 'app/features/alerting/unified/utils/datasource';
import { MANUAL_ROUTING_KEY, SIMPLIFIED_QUERY_EDITOR_KEY } from 'app/features/alerting/unified/utils/rule-form';
@@ -171,7 +170,7 @@ describe('Can create a new grafana managed alert using simplified routing', () =
});
describe('switch modes enabled', () => {
testWithFeatureToggles(['alertingQueryAndExpressionsStepMode', 'alertingNotificationsStepMode']);
testWithFeatureToggles({ enable: ['alertingQueryAndExpressionsStepMode', 'alertingNotificationsStepMode'] });
it('can create the new grafana-managed rule with default modes', async () => {
const contactPointName = 'lotsa-emails';
@@ -1,5 +1,5 @@
import { produce } from 'immer';
import { render, screen } from 'test/test-utils';
import { render, screen, testWithFeatureToggles } from 'test/test-utils';
import { AppNotificationList } from 'app/core/components/AppNotifications/AppNotificationList';
import { DashboardSearchItemType } from 'app/features/search/types';
@@ -9,12 +9,14 @@ import { setupMswServer } from '../../../mockApi';
import { grantUserRole, mockFolder } from '../../../mocks';
import { grafanaRulerRule } from '../../../mocks/grafanaRulerApi';
import { setFolderResponse } from '../../../mocks/server/configure';
import { grantPermissionsHelper, testWithFeatureToggles } from '../../../test/test-utils';
import { grantPermissionsHelper } from '../../../test/test-utils';
import { DeletedRules } from './DeletedRules';
setupMswServer();
testWithFeatureToggles(['alertingRulePermanentlyDelete', 'alertingRuleRecoverDeleted', 'alertRuleRestore']);
testWithFeatureToggles({
enable: ['alertingRulePermanentlyDelete', 'alertingRuleRecoverDeleted', 'alertRuleRestore'],
});
beforeEach(() => {
grantUserRole('Admin');
grantPermissionsHelper([
@@ -1,7 +1,8 @@
import { testWithFeatureToggles } from 'test/test-utils';
import { config, getDataSourceSrv } from '@grafana/runtime';
import { mockAlertQuery, mockDataSource, mockReduceExpression, mockThresholdExpression } from '../mocks';
import { testWithFeatureToggles } from '../test/test-utils';
import { RuleFormType } from '../types/rule-form';
import { Annotation } from '../utils/constants';
import { DataSourceType, getDefaultOrFirstCompatibleDataSource } from '../utils/datasource';
@@ -76,7 +77,7 @@ describe('formValuesFromQueryParams', () => {
});
describe('when simplified query editor is enabled', () => {
testWithFeatureToggles(['alertingQueryAndExpressionsStepMode']);
testWithFeatureToggles({ enable: ['alertingQueryAndExpressionsStepMode'] });
it('should enable simplified query editor if queries are transformable to simple condition', () => {
const result = formValuesFromQueryParams(
@@ -1,5 +1,5 @@
import { HttpResponse } from 'msw';
import { render } from 'test/test-utils';
import { render, testWithFeatureToggles } from 'test/test-utils';
import { byRole, byTestId } from 'testing-library-selector';
import { OrgRole } from '@grafana/data';
@@ -11,7 +11,6 @@ import { grantUserPermissions, grantUserRole } from '../mocks';
import { setGrafanaRuleGroupExportResolver } from '../mocks/server/configure';
import { alertingFactory } from '../mocks/server/db';
import { RulesFilter } from '../search/rulesSearchParser';
import { testWithFeatureToggles } from '../test/test-utils';
import RuleList, { RuleListActions } from './RuleList.v2';
@@ -39,7 +38,7 @@ setPluginLinksHook(() => ({ links: [], isLoading: false }));
setPluginComponentsHook(() => ({ components: [], isLoading: false }));
grantUserPermissions([AccessControlAction.AlertingRuleExternalRead]);
testWithFeatureToggles(['alertingListViewV2']);
testWithFeatureToggles({ enable: ['alertingListViewV2'] });
setupMswServer();
@@ -253,7 +252,7 @@ describe('RuleListActions', () => {
});
describe('Import Alert Rules', () => {
testWithFeatureToggles(['alertingMigrationUI']);
testWithFeatureToggles({ enable: ['alertingMigrationUI'] });
it('should show "Import alert rules" option when user has required permissions and feature toggle is enabled', async () => {
grantUserPermissions([
@@ -1,11 +1,10 @@
import { render } from 'test/test-utils';
import { render, testWithFeatureToggles } from 'test/test-utils';
import { byRole } from 'testing-library-selector';
import { reportInteraction } from '@grafana/runtime';
import { mockLocalStorage } from '../mocks';
import { getPreviewToggle, setPreviewToggle } from '../previewToggles';
import { testWithFeatureToggles } from '../test/test-utils';
import { RuleListPageTitle } from './RuleListPageTitle';
@@ -56,7 +55,7 @@ describe('RuleListPageTitle', () => {
});
describe('with alertingListViewV2PreviewToggle enabled and alertingListViewV2 disabled', () => {
testWithFeatureToggles(['alertingListViewV2PreviewToggle']);
testWithFeatureToggles({ enable: ['alertingListViewV2PreviewToggle'] });
it('should show enable v2 button', () => {
renderRuleListPageTitle();
@@ -85,7 +84,7 @@ describe('RuleListPageTitle', () => {
});
describe('with alertingListViewV2PreviewToggle enabled and alertingListViewV2 enabled', () => {
testWithFeatureToggles(['alertingListViewV2PreviewToggle', 'alertingListViewV2']);
testWithFeatureToggles({ enable: ['alertingListViewV2PreviewToggle', 'alertingListViewV2'] });
it('should show disable v2 button', () => {
renderRuleListPageTitle();
@@ -1,7 +1,5 @@
import { act } from '@testing-library/react';
import { FeatureToggles } from '@grafana/data';
import { config } from '@grafana/runtime';
import { AccessControlAction } from 'app/types/accessControl';
import { grantUserPermissions } from '../mocks';
@@ -17,41 +15,6 @@ export const flushMicrotasks = async () => {
});
};
/**
* Enables feature toggles `beforeEach` test, and sets back to original settings `afterEach` test
*/
export const testWithFeatureToggles = (featureToggles: Array<keyof FeatureToggles>) => {
const originalToggles = { ...config.featureToggles };
beforeEach(() => {
featureToggles.forEach((featureToggle) => {
config.featureToggles[featureToggle] = true;
});
});
afterEach(() => {
config.featureToggles = originalToggles;
});
};
/**
* Enables license features `beforeEach` test, and sets back to original settings `afterEach` test
*/
export const testWithLicenseFeatures = (features: string[]) => {
const originalFeatures = { ...config.licenseInfo.enabledFeatures };
beforeEach(() => {
config.licenseInfo.enabledFeatures = config.licenseInfo.enabledFeatures || {};
features.forEach((feature) => {
config.licenseInfo.enabledFeatures[feature] = true;
});
});
afterEach(() => {
config.licenseInfo.enabledFeatures = originalFeatures;
});
};
/**
* "Grants" permissions via contextSrv mock, and additionally sets folder access control
* API response to match
@@ -1,12 +1,11 @@
import { ComponentProps } from 'react';
import { render, screen } from 'test/test-utils';
import { render, screen, testWithFeatureToggles } from 'test/test-utils';
import { setBackendSrv } from '@grafana/runtime';
import { DashboardLink } from '@grafana/schema';
import { setupMockServer } from '@grafana/test-utils/server';
import { getFolderFixtures } from '@grafana/test-utils/unstable';
import { backendSrv } from 'app/core/services/backend_srv';
import { testWithFeatureToggles } from 'app/features/alerting/unified/test/test-utils';
import { LinkSrv } from 'app/features/panel/panellinks/link_srv';
import { resetGrafanaSearcher } from 'app/features/search/service/searcher';
@@ -58,7 +57,7 @@ describe.each([
// Legacy APIs
false,
])('with unifiedStorageSearchUI: %s', (featureTogglesEnabled) => {
testWithFeatureToggles(featureTogglesEnabled ? ['unifiedStorageSearchUI'] : []);
testWithFeatureToggles({ enable: featureTogglesEnabled ? ['unifiedStorageSearchUI'] : [] });
describe('DashboardLinksDashboard', () => {
it('renders a dropdown', async () => {
@@ -1,11 +1,10 @@
import { render, screen } from 'test/test-utils';
import { render, screen, testWithFeatureToggles } from 'test/test-utils';
import { setBackendSrv } from '@grafana/runtime';
import { setupMockServer } from '@grafana/test-utils/server';
import { getFolderFixtures } from '@grafana/test-utils/unstable';
import { backendSrv } from 'app/core/services/backend_srv';
import impressionSrv from 'app/core/services/impression_srv';
import { testWithFeatureToggles } from 'app/features/alerting/unified/test/test-utils';
import { getPanelProps } from '../test-utils';
@@ -39,7 +38,7 @@ describe.each([
// Legacy APIs
false,
])('DashList - app platform APIs: %s', (featureTogglesEnabled) => {
testWithFeatureToggles(featureTogglesEnabled ? ['unifiedStorageSearchUI'] : []);
testWithFeatureToggles({ enable: featureTogglesEnabled ? ['unifiedStorageSearchUI'] : [] });
it('renders different groups of dashboards', async () => {
const props = getPanelProps({
@@ -1,10 +1,9 @@
import { render, screen } from 'test/test-utils';
import { render, screen, testWithFeatureToggles } from 'test/test-utils';
import { setBackendSrv } from '@grafana/runtime';
import { setupMockServer } from '@grafana/test-utils/server';
import { backendSrv } from 'app/core/services/backend_srv';
import { mockDataSource } from 'app/features/alerting/unified/mocks';
import { testWithFeatureToggles } from 'app/features/alerting/unified/test/test-utils';
import { setupDataSources } from 'app/features/alerting/unified/testSetup/datasources';
import { getPanelProps } from '../test-utils';
@@ -23,7 +22,7 @@ describe.each([
// Legacy APIs
false,
])('GettingStarted - app platform APIs: %s', (featureTogglesEnabled) => {
testWithFeatureToggles(featureTogglesEnabled ? ['unifiedStorageSearchUI'] : []);
testWithFeatureToggles({ enable: featureTogglesEnabled ? ['unifiedStorageSearchUI'] : [] });
it('renders getting started steps', async () => {
const props = getPanelProps({});
+46
View File
@@ -10,7 +10,9 @@ import { Router } from 'react-router-dom';
import { CompatRouter } from 'react-router-dom-v5-compat';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
import { FeatureToggles } from '@grafana/data';
import {
config,
HistoryWrapper,
LocationServiceProvider,
setChromeHeaderHeightHook,
@@ -121,5 +123,49 @@ const customRender = (
};
};
/**
* Enables and disables feature toggles `beforeEach` test, and sets back to empty object `afterEach` test
*/
export const testWithFeatureToggles = ({
enable,
disable,
}: {
enable?: Array<keyof FeatureToggles>;
disable?: Array<keyof FeatureToggles>;
}) => {
beforeEach(() => {
for (const featureToggle of enable || []) {
config.featureToggles[featureToggle] = true;
}
for (const featureToggle of disable || []) {
config.featureToggles[featureToggle] = false;
}
});
afterEach(() => {
config.featureToggles = {};
});
};
/**
* Enables license features `beforeEach` test, and sets back to empty object `afterEach` test
*/
export const testWithLicenseFeatures = ({ enable, disable }: { enable?: string[]; disable?: string[] }) => {
beforeEach(() => {
config.licenseInfo.enabledFeatures = config.licenseInfo.enabledFeatures || {};
for (const feature of enable || []) {
config.licenseInfo.enabledFeatures[feature] = true;
}
for (const feature of disable || []) {
config.licenseInfo.enabledFeatures[feature] = false;
}
});
afterEach(() => {
config.licenseInfo.enabledFeatures = {};
});
};
export * from '@testing-library/react';
export { customRender as render, getWrapper, userEvent };