Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upcoming: [DI-20595] - ACLP Supported regions per service type #11382

Merged
merged 21 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ae045fb
upcoming: [DI-20595] - ACLP Supported regions per service type
ankita-akamai Dec 2, 2024
b576975
upcoming: [DI-20595] - small fix
ankita-akamai Dec 2, 2024
1832509
upcoming: [DI-20595] - improved test quality
ankita-akamai Dec 3, 2024
78a1489
upcoming: [DI-20595] - PR Comments
ankita-akamai Dec 3, 2024
615c573
upcoming: [DI-20595] - small fix
ankita-akamai Dec 3, 2024
19db96e
upcoming: [DI-20595] - updated UT
ankita-akamai Dec 3, 2024
00d89ed
upcoming: [DI-20595] - updated UT
ankita-akamai Dec 3, 2024
5614b9b
upcoming: [DI-20595] - updated types
ankita-akamai Dec 3, 2024
1dcb4af
upcoming: [DI-20595] - small linting fix
ankita-akamai Dec 3, 2024
a6cb633
upcoming: [DI-20595] - handle empty regions
ankita-akamai Dec 5, 2024
d748c7d
upcoming: [DI-20595] - Added changeset
ankita-akamai Dec 6, 2024
2854e2d
upcoming: [DI-20595] - Added changeset
ankita-akamai Dec 6, 2024
d224809
upcoming: [DI-20595] - edge case fix
ankita-akamai Dec 9, 2024
9cef426
upcoming: [DI-20595] - linting fix
ankita-akamai Dec 9, 2024
0e3f89c
Test[DI-20595] -add region select testcases
agorthi-akamai Dec 9, 2024
398d3b6
Merge pull request #1 from agorthi-akamai/supported_regions
ankita-akamai Dec 9, 2024
f5cfdb2
upcoming: [DI-20595] - PR Comments
ankita-akamai Dec 10, 2024
c94801d
upcoming: [DI-20595] - PR Comments
ankita-akamai Dec 10, 2024
e74d09f
upcoming: [DI-20595] - linting fix
ankita-akamai Dec 10, 2024
9edb799
upcoming: [DI-20595] - linting fix
ankita-akamai Dec 10, 2024
1cb3c4b
upcoming: [DI-20595] - linting fix
ankita-akamai Dec 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

Show ACLP supported regions per service type in region select ([#11382](https://github.com/linode/manager/pull/11382))
1 change: 1 addition & 0 deletions packages/manager/src/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export interface CloudPulseResourceTypeMapFlag {
dimensionKey: string;
maxResourceSelections?: number;
serviceType: string;
supportedRegionIds?: string;
}

interface gpuV2 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import { CloudPulseSelectTypes } from './models';
import type { CloudPulseServiceTypeFilterMap } from './models';

const TIME_DURATION = 'Time Range';
export const DBAAS_CAPABILITY = 'Managed Databases';
export const LINODE_CAPABILITY = 'Linodes';

export const LINODE_CONFIG: Readonly<CloudPulseServiceTypeFilterMap> = {
capability: LINODE_CAPABILITY,
filters: [
{
configuration: {
Expand Down Expand Up @@ -52,6 +55,7 @@ export const LINODE_CONFIG: Readonly<CloudPulseServiceTypeFilterMap> = {
};

export const DBAAS_CONFIG: Readonly<CloudPulseServiceTypeFilterMap> = {
capability: DBAAS_CAPABILITY,
filters: [
{
configuration: {
Expand Down
10 changes: 9 additions & 1 deletion packages/manager/src/features/CloudPulse/Utils/models.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type { DatabaseEngine, DatabaseType } from '@linode/api-v4';
import type {
Capabilities,
DatabaseEngine,
DatabaseType,
} from '@linode/api-v4';
import type { QueryFunction, QueryKey } from '@tanstack/react-query';

/**
* The CloudPulseServiceTypeMap has list of filters to be built for different service types like dbaas, linode etc.,The properties here are readonly as it is only for reading and can't be modified in code
*/
export interface CloudPulseServiceTypeFilterMap {
/**
* Current capability corresponding to a service type
*/
readonly capability: Capabilities;
/**
* The list of filters for a service type
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,49 @@
import userEvent from '@testing-library/user-event';
import * as React from 'react';

import * as regions from 'src/queries/regions/regions';
import { dashboardFactory, regionFactory } from 'src/factories';
import { renderWithTheme } from 'src/utilities/testHelpers';

import { DBAAS_CAPABILITY, LINODE_CAPABILITY } from '../Utils/FilterConfig';
import { CloudPulseRegionSelect } from './CloudPulseRegionSelect';

import type { CloudPulseRegionSelectProps } from './CloudPulseRegionSelect';
import type { Region } from '@linode/api-v4';
import type { CloudPulseResourceTypeMapFlag, Flags } from 'src/featureFlags';
import type * as regions from 'src/queries/regions/regions';

const props: CloudPulseRegionSelectProps = {
handleRegionChange: vi.fn(),
label: 'Region',
selectedDashboard: undefined,
};

describe('CloudPulseRegionSelect', () => {
vi.spyOn(regions, 'useRegionsQuery').mockReturnValue({
data: Array<Region>(),
} as ReturnType<typeof regions.useRegionsQuery>);
const queryMocks = vi.hoisted(() => ({
useRegionsQuery: vi.fn().mockReturnValue({}),
}));

const flags: Partial<Flags> = {
aclpResourceTypeMap: [
{
serviceType: 'dbaas',
supportedRegionIds: 'us-west, us-east, ,',
mjac0bs marked this conversation as resolved.
Show resolved Hide resolved
},
{
serviceType: 'linode',
supportedRegionIds: 'us-lax, us-mia',
},
] as CloudPulseResourceTypeMapFlag[],
};

vi.mock('src/queries/regions/regions', async () => {
const actual = await vi.importActual('src/queries/regions/regions');
return {
...actual,
useRegionsQuery: queryMocks.useRegionsQuery,
};
});

describe('CloudPulseRegionSelect', () => {
it('should render a Region Select component', () => {
const { getByLabelText, getByTestId } = renderWithTheme(
<CloudPulseRegionSelect {...props} />
Expand All @@ -29,7 +54,7 @@ describe('CloudPulseRegionSelect', () => {
});

it('should render a Region Select component with proper error message on api call failure', () => {
vi.spyOn(regions, 'useRegionsQuery').mockReturnValue({
queryMocks.useRegionsQuery.mockReturnValue({
data: undefined,
isError: true,
isLoading: false,
Expand All @@ -40,4 +65,79 @@ describe('CloudPulseRegionSelect', () => {

expect(getByText('Failed to fetch Region.'));
});

it('should render a Region Select component with capability specific and launchDarkly based supported regions', async () => {
const user = userEvent.setup();

const allRegions: Region[] = [
regionFactory.build({
capabilities: [LINODE_CAPABILITY],
id: 'us-lax',
label: 'US, Los Angeles, CA',
}),
regionFactory.build({
capabilities: [LINODE_CAPABILITY],
id: 'us-mia',
label: 'US, Miami, FL',
}),
regionFactory.build({
capabilities: [DBAAS_CAPABILITY],
id: 'us-west',
label: 'US, Fremont, CA',
}),
regionFactory.build({
capabilities: [DBAAS_CAPABILITY],
id: 'us-east',
label: 'US, Newark, NJ',
}),
regionFactory.build({
capabilities: [DBAAS_CAPABILITY],
id: 'us-central',
label: 'US, Dallas, TX',
}),
];

queryMocks.useRegionsQuery.mockReturnValue({
data: allRegions,
isError: false,
isLoading: false,
});

const { getByRole, queryByRole } = renderWithTheme(
<CloudPulseRegionSelect
{...props}
// eslint-disable-next-line camelcase
selectedDashboard={dashboardFactory.build({ service_type: 'dbaas' })}
/>,
{ flags }
);

await user.click(getByRole('button', { name: 'Open' }));
// example: region id => 'us-west' belongs to service type - 'dbass', capability -'Managed Databases', and is supported via launchDarkly
ankita-akamai marked this conversation as resolved.
Show resolved Hide resolved
expect(
getByRole('option', {
name: 'US, Fremont, CA (us-west)',
})
).toBeInTheDocument();
expect(
getByRole('option', {
name: 'US, Newark, NJ (us-east)',
})
).toBeInTheDocument();
expect(
queryByRole('option', {
name: 'US, Dallas, TX (us-central)',
})
).toBeNull();
expect(
queryByRole('option', {
name: 'US, Los Angeles, CA (us-lax)',
})
).toBeNull();
expect(
queryByRole('option', {
name: 'US, Miami, FL (us-mia)',
})
).toBeNull();
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import * as React from 'react';

import { RegionSelect } from 'src/components/RegionSelect/RegionSelect';
import { useFlags } from 'src/hooks/useFlags';
import { useRegionsQuery } from 'src/queries/regions/regions';

import type { Dashboard, FilterValue } from '@linode/api-v4';
import { FILTER_CONFIG } from '../Utils/FilterConfig';

import type { Dashboard, FilterValue, Region } from '@linode/api-v4';
import type { CloudPulseResourceTypeMapFlag } from 'src/featureFlags';

export interface CloudPulseRegionSelectProps {
defaultValue?: FilterValue;
Expand All @@ -18,6 +22,8 @@ export const CloudPulseRegionSelect = React.memo(
(props: CloudPulseRegionSelectProps) => {
const { data: regions, isError, isLoading } = useRegionsQuery();

const flags = useFlags();

const {
defaultValue,
handleRegionChange,
Expand All @@ -27,6 +33,11 @@ export const CloudPulseRegionSelect = React.memo(
selectedDashboard,
} = props;

const serviceType: string | undefined = selectedDashboard?.service_type;
const capability = serviceType
? FILTER_CONFIG.get(serviceType)?.capability
: undefined;

const [selectedRegion, setSelectedRegion] = React.useState<string>();
// Once the data is loaded, set the state variable with value stored in preferences
React.useEffect(() => {
Expand All @@ -40,13 +51,33 @@ export const CloudPulseRegionSelect = React.memo(
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [regions]);

// validate launchDrakly region_ids with the ids from the fetched 'all-regions'
ankita-akamai marked this conversation as resolved.
Show resolved Hide resolved
const supportedRegions = React.useMemo<Region[] | undefined>(() => {
const resourceTypeFlag = flags.aclpResourceTypeMap?.find(
(item: CloudPulseResourceTypeMapFlag) =>
item.serviceType === serviceType
);
const supportedRegionsIdList =
resourceTypeFlag?.supportedRegionIds
?.split(',')
.map((regionId: string) => regionId.trim())
.filter((regionId: string) => regionId.length > 0) || [];

if (!supportedRegionsIdList.length) {
return regions;
}
return regions?.filter((region) =>
supportedRegionsIdList?.includes(region.id)
);
}, [flags.aclpResourceTypeMap, regions, serviceType]);

return (
<RegionSelect
onChange={(_, region) => {
setSelectedRegion(region?.id);
handleRegionChange(region?.id, savePreferences);
}}
currentCapability={undefined}
currentCapability={capability}
data-testid="region-select"
disableClearable={false}
disabled={!selectedDashboard || !regions}
Expand All @@ -56,7 +87,7 @@ export const CloudPulseRegionSelect = React.memo(
loading={isLoading}
noMarginTop
placeholder={placeholder ?? 'Select a Region'}
regions={regions ? regions : []}
regions={supportedRegions ? supportedRegions : []}
mjac0bs marked this conversation as resolved.
Show resolved Hide resolved
value={selectedRegion}
/>
);
Expand Down
Loading