1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-11-10 01:19:53 +01:00

feat: prioritize first production environments in FeatureExposureMetrics (#10891)

This commit is contained in:
mohammedlaniyan-unleash 2025-11-04 11:53:41 +00:00 committed by GitHub
parent a1ebd0d114
commit 366827de6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 103 additions and 6 deletions

View File

@ -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(
<Routes>
<Route path={PATH} element={<FeatureExposureMetrics />} />
</Routes>,
{ 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(
<Routes>
<Route path={PATH} element={<FeatureExposureMetrics />} />
</Routes>,
{ route: ROUTE },
);
const selectedChip = await screen.findByTestId(
'selected-chip-development-1',
);
expect(selectedChip).toHaveAttribute('aria-pressed', 'true');
expect(selectedChip).toHaveTextContent('development-1');
});
});

View File

@ -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<string> => {
): { environments: Set<string>; 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

View File

@ -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}`
}
/>
</StyledItem>
))}