diff --git a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.test.tsx b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.test.tsx new file mode 100644 index 0000000000..118906aa56 --- /dev/null +++ b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.test.tsx @@ -0,0 +1,86 @@ +import { render } from 'utils/testRenderer'; +import { screen } from '@testing-library/react'; +import { testServerRoute, testServerSetup } from 'utils/testServer'; +import { FeatureExposureMetrics } from './FeatureExposureMetrics.tsx'; +import { Route, Routes } from 'react-router-dom'; + +describe('FeatureExposureMetrics – default production selection', () => { + const server = testServerSetup(); + const PROJECT_ID = 'default'; + const FEATURE_ID = 'feature_name'; + const ROUTE = `/projects/${PROJECT_ID}/features/${FEATURE_ID}/metrics`; + const PATH = `/projects/:projectId/features/:featureId/metrics`; + + it('returns the name of the first production env (prod in middle)', async () => { + testServerRoute( + server, + `/api/admin/projects/${PROJECT_ID}/features/${FEATURE_ID}?variantEnvironments=true`, + { + environments: [ + { + name: 'development', + type: 'development', + sortOrder: 2, + }, + { + name: 'production-1', + type: 'production', + sortOrder: 3, + }, + { + name: 'production-2', + type: 'production', + sortOrder: 4, + }, + ], + }, + ); + + render( + + } /> + , + { route: ROUTE }, + ); + + const selectedChip = await screen.findByTestId( + 'selected-chip-production-1', + ); + expect(selectedChip).toHaveAttribute('aria-pressed', 'true'); + expect(selectedChip).toHaveTextContent('production-1'); + }); + + it('returns the first environment if production is not in the list', async () => { + testServerRoute( + server, + `/api/admin/projects/${PROJECT_ID}/features/${FEATURE_ID}?variantEnvironments=true`, + { + environments: [ + { + name: 'development-1', + type: 'development', + sortOrder: 2, + }, + { + name: 'development-2', + type: 'development', + sortOrder: 3, + }, + ], + }, + ); + + render( + + } /> + , + { route: ROUTE }, + ); + + const selectedChip = await screen.findByTestId( + 'selected-chip-development-1', + ); + expect(selectedChip).toHaveAttribute('aria-pressed', 'true'); + expect(selectedChip).toHaveTextContent('development-1'); + }); +}); diff --git a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.tsx b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.tsx index 04ffae7ec9..784636ce84 100644 --- a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureExposureMetrics.tsx @@ -26,17 +26,19 @@ import { PageHeader } from 'component/common/PageHeader/PageHeader.tsx'; export const FeatureExposureMetrics = () => { const projectId = useRequiredPathParam('projectId'); const featureId = useRequiredPathParam('featureId'); - const environments = useFeatureMetricsEnvironments(projectId, featureId); + const { environments, defaultProductionIndex } = + useFeatureMetricsEnvironments(projectId, featureId); usePageTitle('Metrics'); - const defaultEnvironment = Array.from(environments)[0]; + const defaultEnvironment = Array.from(environments)[defaultProductionIndex]; const [query, setQuery] = useQueryParams({ environment: withDefault(StringParam, defaultEnvironment), applications: withDefault(ArrayParam, []), hoursBack: withDefault(NumberParam, FEATURE_METRIC_HOURS_BACK_DEFAULT), }); + const applications = useFeatureMetricsApplications( featureId, query.hoursBack || FEATURE_METRIC_HOURS_BACK_DEFAULT, @@ -171,17 +173,21 @@ export const FeatureExposureMetrics = () => { // Get all the environment names for a feature, // not just the one's we have metrics for. -const useFeatureMetricsEnvironments = ( +export const useFeatureMetricsEnvironments = ( projectId: string, featureId: string, -): Set => { +): { environments: Set; defaultProductionIndex: number } => { const { feature } = useFeature(projectId, featureId); - const environments = feature.environments.map((environment) => { + let defaultProductionIndex = 0; + const environments = feature.environments.map((environment, index) => { + if (!defaultProductionIndex && environment.type === 'production') { + defaultProductionIndex = index; + } return environment.name; }); - return new Set(environments); + return { environments: new Set(environments), defaultProductionIndex }; }; // Get all application names for a feature. Respect current hoursBack since diff --git a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetricsChips/FeatureMetricsChips.tsx b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetricsChips/FeatureMetricsChips.tsx index 254be1a571..068da2354f 100644 --- a/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetricsChips/FeatureMetricsChips.tsx +++ b/frontend/src/component/feature/FeatureView/FeatureMetrics/FeatureMetricsChips/FeatureMetricsChips.tsx @@ -80,6 +80,11 @@ export const FeatureMetricsChips = ({ onClick={onClick(val)} aria-pressed={selectedValues?.includes(val)} sx={focusable} + data-testid={ + selectedValues?.includes(val) + ? `selected-chip-${val}` + : `unselected-chip-${val}` + } /> ))}