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:
parent
a1ebd0d114
commit
366827de6f
@ -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');
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -26,17 +26,19 @@ import { PageHeader } from 'component/common/PageHeader/PageHeader.tsx';
|
|||||||
export const FeatureExposureMetrics = () => {
|
export const FeatureExposureMetrics = () => {
|
||||||
const projectId = useRequiredPathParam('projectId');
|
const projectId = useRequiredPathParam('projectId');
|
||||||
const featureId = useRequiredPathParam('featureId');
|
const featureId = useRequiredPathParam('featureId');
|
||||||
const environments = useFeatureMetricsEnvironments(projectId, featureId);
|
const { environments, defaultProductionIndex } =
|
||||||
|
useFeatureMetricsEnvironments(projectId, featureId);
|
||||||
|
|
||||||
usePageTitle('Metrics');
|
usePageTitle('Metrics');
|
||||||
|
|
||||||
const defaultEnvironment = Array.from(environments)[0];
|
const defaultEnvironment = Array.from(environments)[defaultProductionIndex];
|
||||||
|
|
||||||
const [query, setQuery] = useQueryParams({
|
const [query, setQuery] = useQueryParams({
|
||||||
environment: withDefault(StringParam, defaultEnvironment),
|
environment: withDefault(StringParam, defaultEnvironment),
|
||||||
applications: withDefault(ArrayParam, []),
|
applications: withDefault(ArrayParam, []),
|
||||||
hoursBack: withDefault(NumberParam, FEATURE_METRIC_HOURS_BACK_DEFAULT),
|
hoursBack: withDefault(NumberParam, FEATURE_METRIC_HOURS_BACK_DEFAULT),
|
||||||
});
|
});
|
||||||
|
|
||||||
const applications = useFeatureMetricsApplications(
|
const applications = useFeatureMetricsApplications(
|
||||||
featureId,
|
featureId,
|
||||||
query.hoursBack || FEATURE_METRIC_HOURS_BACK_DEFAULT,
|
query.hoursBack || FEATURE_METRIC_HOURS_BACK_DEFAULT,
|
||||||
@ -171,17 +173,21 @@ export const FeatureExposureMetrics = () => {
|
|||||||
|
|
||||||
// Get all the environment names for a feature,
|
// Get all the environment names for a feature,
|
||||||
// not just the one's we have metrics for.
|
// not just the one's we have metrics for.
|
||||||
const useFeatureMetricsEnvironments = (
|
export const useFeatureMetricsEnvironments = (
|
||||||
projectId: string,
|
projectId: string,
|
||||||
featureId: string,
|
featureId: string,
|
||||||
): Set<string> => {
|
): { environments: Set<string>; defaultProductionIndex: number } => {
|
||||||
const { feature } = useFeature(projectId, featureId);
|
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 environment.name;
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Set(environments);
|
return { environments: new Set(environments), defaultProductionIndex };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get all application names for a feature. Respect current hoursBack since
|
// Get all application names for a feature. Respect current hoursBack since
|
||||||
|
|||||||
@ -80,6 +80,11 @@ export const FeatureMetricsChips = ({
|
|||||||
onClick={onClick(val)}
|
onClick={onClick(val)}
|
||||||
aria-pressed={selectedValues?.includes(val)}
|
aria-pressed={selectedValues?.includes(val)}
|
||||||
sx={focusable}
|
sx={focusable}
|
||||||
|
data-testid={
|
||||||
|
selectedValues?.includes(val)
|
||||||
|
? `selected-chip-${val}`
|
||||||
|
: `unselected-chip-${val}`
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</StyledItem>
|
</StyledItem>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user