Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
70d9918
[DI-26394] - Add new flag to control services types in alerts and met…
ankita-akamai Jul 25, 2025
8267ed6
[DI-26394] - Update type
ankita-akamai Aug 11, 2025
9927786
[DI-26394] - fix eslint issues
ankita-akamai Jul 28, 2025
ec290d2
[DI-26394] - Cleanup
ankita-akamai Jul 28, 2025
706e4ec
[DI-26394] - Remove aclpBetaServices flag
ankita-akamai Jul 28, 2025
f523b3b
[DI-26394] - Update type
ankita-akamai Jul 28, 2025
d4a297c
[DI-26394] - Remove fallbacks
ankita-akamai Jul 28, 2025
2a2606a
[DI-26394] - Update reusable comp as per aclp-dev
ankita-akamai Jul 28, 2025
14365a2
[DI-26394] - Update comments
ankita-akamai Jul 29, 2025
5b653db
[DI-26394] - reuse type
ankita-akamai Jul 30, 2025
b44c9d1
upcoming: [DI-26394] - Update comment
ankita-akamai Jul 30, 2025
c5f2388
[DI-26394] - Make props optional and update test cases
ankita-akamai Jul 31, 2025
2b07efa
[DI-26394] - Update component
ankita-akamai Jul 31, 2025
2f3631d
[DI-26394] - Update component
ankita-akamai Jul 31, 2025
4b67914
test[DI-26398]: Add/Update spec to cover aclpServices LaunchDarkly fl…
agorthi-akamai Jul 31, 2025
67b8c66
test[DI-26398]: Add/Update spec to cover aclpServices
agorthi-akamai Aug 1, 2025
a150a88
test[DI-26398]: Fix typecheck issue
ankita-akamai Aug 11, 2025
8702688
[DI-26394] - remove type assertion
ankita-akamai Aug 11, 2025
abb91dd
[DI-26394] - Add changeset
ankita-akamai Aug 12, 2025
30a3ca9
upcoming:[DI-26394]: Use appropriate flag prop for linode create and …
ankita-akamai Aug 12, 2025
de48fe6
Merge branch 'develop' into feature/HandleAclpServicesFlag
ankita-akamai Aug 12, 2025
37bc95c
[DI-26394] - update flag check and e2e test desc
ankita-akamai Aug 13, 2025
f543470
Merge branch 'feature/HandleAclpServicesFlag' of github.com:ankitaaka…
ankita-akamai Aug 13, 2025
1e74c59
Merge branch 'develop' into feature/HandleAclpServicesFlag
dmcintyr-akamai Aug 13, 2025
598ba57
upcoming:[DI-26394]: Update flag correctly
ankita-akamai Aug 13, 2025
b565a06
Merge branch 'feature/HandleAclpServicesFlag' of github.com:ankitaaka…
ankita-akamai Aug 13, 2025
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
---

CloudPulse: Add new flag - 'aclpServices', filter services at `CloudPulseDashboardSelect.tsx`, `AlertListing.tsx`, `ServiceTypeSelect.tsx` ([#12671](https://github.com/linode/manager/pull/12671))
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ import type { Stats } from '@linode/api-v4';
describe('ACLP Components UI varies according to ACLP support by region and user preference', function () {
beforeEach(function () {
mockAppendFeatureFlags({
aclpBetaServices: {
aclpServices: {
linode: {
alerts: false,
metrics: true,
alerts: { beta: false, enabled: false },
metrics: { beta: true, enabled: true },
},
},
}).as('getFeatureFlags');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ import {
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { ui } from 'support/ui';

import { accountFactory, alertFactory } from 'src/factories';

import type { Flags } from 'src/featureFlags';

const flags: Partial<Flags> = { aclp: { beta: true, enabled: true } };
import { accountFactory, alertFactory, flagsFactory } from 'src/factories';
const mockAccount = accountFactory.build();
const mockAlerts = [
alertFactory.build({
Expand Down Expand Up @@ -39,7 +35,7 @@ describe('Alerts Listing Page - Error Handling', () => {
* - Confirms that the UI does not reflect a successful state change if the request fails.
*/
beforeEach(() => {
mockAppendFeatureFlags(flags);
mockAppendFeatureFlags(flagsFactory.build());
mockGetAccount(mockAccount);
mockGetCloudPulseServices(['linode', 'dbaas']);
mockGetAllAlertDefinitions(mockAlerts).as('getAlertDefinitionsList');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { mockGetProfile } from 'support/intercepts/profile';
import { ui } from 'support/ui';

import { accountFactory, alertFactory, alertRulesFactory } from 'src/factories';
import {
accountFactory,
alertFactory,
alertRulesFactory,
flagsFactory,
} from 'src/factories';
import {
alertLimitMessage,
alertToolTipText,
Expand All @@ -33,19 +38,11 @@ import type {
AlertStatusType,
CloudPulseServiceType,
} from '@linode/api-v4';
import type { Flags } from 'src/featureFlags';
const alertDefinitionsUrl = '/alerts/definitions';

const mockProfile = profileFactory.build({
timezone: 'gmt',
});
const flags: Partial<Flags> = {
aclp: { beta: true, enabled: true },
aclpBetaServices: {
dbaas: { metrics: true, alerts: true },
linode: { metrics: true, alerts: true },
},
};
const mockAccount = accountFactory.build();
const now = new Date();
const mockAlerts = [
Expand Down Expand Up @@ -215,7 +212,7 @@ describe('Integration Tests for CloudPulse Alerts Listing Page', () => {
* - Ensures API calls return correct responses and status codes.
*/
beforeEach(() => {
mockAppendFeatureFlags(flags);
mockAppendFeatureFlags(flagsFactory.build());
mockGetAccount(mockAccount);
mockGetProfile(mockProfile);
mockGetCloudPulseServices(['linode', 'dbaas']);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
* @file Integration tests for feature flag behavior on the alert page.
*/
import { widgetDetails } from 'support/constants/widgets';
import { mockGetAccount } from 'support/intercepts/account';
import {
mockGetCloudPulseMetricDefinitions,
mockGetCloudPulseServices,
} from 'support/intercepts/cloudpulse';
import { mockAppendFeatureFlags } from 'support/intercepts/feature-flags';
import { mockGetUserPreferences } from 'support/intercepts/profile';
import { ui } from 'support/ui';

import {
accountFactory,
dashboardMetricFactory,
flagsFactory,
} from 'src/factories';
/**
* This test ensures that widget titles are displayed correctly on the dashboard.
* This test suite is dedicated to verifying the functionality and display of widgets on the Cloudpulse dashboard.
* It includes:
* Validating that widgets are correctly loaded and displayed.
* Ensuring that widget titles and data match the expected values.
* Verifying that widget settings, such as granularity and aggregation, are applied correctly.
* Testing widget interactions, including zooming and filtering, to ensure proper behavior.
* Each test ensures that widgets on the dashboard operate correctly and display accurate information.
*/

const { metrics } = widgetDetails.linode;
const serviceType = 'linode';

const metricDefinitions = metrics.map(({ name, title, unit }) =>
dashboardMetricFactory.build({
label: title,
metric: name,
unit,
})
);

const mockAccount = accountFactory.build();
const CREATE_ALERT_PAGE_URL = '/alerts/definitions/create';
const NO_OPTIONS_TEXT = 'You have no options to choose from';

describe('Linode ACLP Metrics and Alerts Flag Behavior', () => {
beforeEach(() => {
mockGetAccount(mockAccount); // Enables the account to have capability for Akamai Cloud Pulse
mockGetCloudPulseMetricDefinitions(serviceType, metricDefinitions);
mockGetCloudPulseServices([serviceType]).as('fetchServices');
mockGetUserPreferences({});
});

it('should show Linode with beta tag in Service dropdown on Alert page when alerts.beta is true', () => {
mockAppendFeatureFlags(flagsFactory.build());
cy.visitWithLogin(CREATE_ALERT_PAGE_URL);
ui.autocomplete.findByLabel('Service').as('serviceInput');
cy.get('@serviceInput').click();

Check warning on line 57 in packages/manager/cypress/e2e/core/cloudpulse/alerts-service-ld-flags.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 6 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 6 times.","line":57,"column":12,"nodeType":"Literal","endLine":57,"endColumn":27}

cy.get('[data-qa-id="linode"]')
.should('have.text', 'Linode')
.parent()
.as('linodeBetaServiceOption');

cy.get('@linodeBetaServiceOption')
.find('[data-testid="betaChip"]')
.should('be.visible')

Check warning on line 66 in packages/manager/cypress/e2e/core/cloudpulse/alerts-service-ld-flags.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 6 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 6 times.","line":66,"column":15,"nodeType":"Literal","endLine":66,"endColumn":27}
.and('have.text', 'beta');

cy.get('@serviceInput').should('be.visible').type('Linode');
ui.autocompletePopper.findByTitle('Linode').should('be.visible').click();
});
it('should exclude Linode beta in Service dropdown when alerts.beta is false', () => {
// Mock feature flags with alerts beta disabled
const mockflags = flagsFactory.build({
aclpServices: {
linode: {
alerts: { beta: false, enabled: false },
},
},
});

mockAppendFeatureFlags(mockflags);

// Visit the alert creation page
cy.visitWithLogin(CREATE_ALERT_PAGE_URL);

// Click the Service dropdown
ui.autocomplete.findByLabel('Service').as('serviceInput');
cy.get('@serviceInput').click();

// Assert dropdown behavior
cy.get('[data-qa-autocomplete-popper]')

Check warning on line 92 in packages/manager/cypress/e2e/core/cloudpulse/alerts-service-ld-flags.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":92,"column":12,"nodeType":"Literal","endLine":92,"endColumn":43}
.should('be.visible')
.and('have.text', NO_OPTIONS_TEXT)
.and('not.contain.text', 'Linode beta');

Check warning on line 95 in packages/manager/cypress/e2e/core/cloudpulse/alerts-service-ld-flags.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":95,"column":32,"nodeType":"Literal","endLine":95,"endColumn":45}

Check warning on line 95 in packages/manager/cypress/e2e/core/cloudpulse/alerts-service-ld-flags.spec.ts

View workflow job for this annotation

GitHub Actions / ESLint Review (manager)

[eslint] reported by reviewdog 🐢 Define a constant instead of duplicating this literal 3 times. Raw Output: {"ruleId":"sonarjs/no-duplicate-string","severity":1,"message":"Define a constant instead of duplicating this literal 3 times.","line":95,"column":12,"nodeType":"Literal","endLine":95,"endColumn":30}
});

it('should show no available services in the Service dropdown when Linode alerts are disabled but beta is true', () => {
const mockflags = flagsFactory.build({
aclpServices: {
linode: {
alerts: { beta: true, enabled: false },
},
},
});

mockAppendFeatureFlags(mockflags);
// Visit the alert creation page
cy.visitWithLogin(CREATE_ALERT_PAGE_URL);
// Click the Service dropdown
ui.autocomplete.findByLabel('Service').as('serviceInput');
cy.get('@serviceInput').click();

// ---------- Assert ----------
cy.get('[data-qa-autocomplete-popper]')
.should('be.visible')
.and('have.text', NO_OPTIONS_TEXT)
.and('not.contain.text', 'Linode beta');
});

it('should show no options and exclude Linode beta in Service dropdown when alerts are disabled but beta is true', () => {
const mockflags = flagsFactory.build({
aclpServices: {
linode: {
alerts: { beta: true, enabled: false },
},
},
});

mockAppendFeatureFlags(mockflags);
// Visit the alert creation page
cy.visitWithLogin(CREATE_ALERT_PAGE_URL);
// Click the Service dropdown
ui.autocomplete.findByLabel('Service').as('serviceInput');
cy.get('@serviceInput').click();

// ---------- Assert ----------
cy.get('[data-qa-autocomplete-popper]')
.should('be.visible')
.and('contain.text', 'You have no options to choose from')
.and('not.contain.text', 'Linode beta');
});

it('should show Linode without beta tag in Service dropdown when alerts are enabled but not in beta', () => {
const mockflags = flagsFactory.build({
aclpServices: {
linode: {
alerts: { beta: false, enabled: true },
},
},
});
mockAppendFeatureFlags(mockflags);
cy.visitWithLogin(CREATE_ALERT_PAGE_URL);
ui.autocomplete.findByLabel('Service').as('serviceInput');
cy.get('@serviceInput').click();

// ---------- Assert ----------
cy.get('[data-qa-id="linode"]')
.should('have.text', 'Linode')
.parent()
.as('linodeBetaServiceOption');

cy.get('@linodeBetaServiceOption')
.find('[data-testid="betaChip"]')
.should('not.exist');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ import {
dashboardFactory,
dashboardMetricFactory,
databaseFactory,
flagsFactory,
widgetFactory,
} from 'src/factories';

import type { Database } from '@linode/api-v4';
import type { Flags } from 'src/featureFlags';

/**
* Verifies the presence and values of specific properties within the aclpPreference object
Expand All @@ -47,22 +47,6 @@ import type { Flags } from 'src/featureFlags';
* @param requestPayload - The payload received from the request, containing the aclpPreference object.
* @param expectedValues - An object containing the expected values for properties to validate against the requestPayload.
*/

const flags: Partial<Flags> = {
aclp: { beta: true, enabled: true },
aclpResourceTypeMap: [
{
dimensionKey: 'LINODE_ID',
maxResourceSelections: 10,
serviceType: 'linode',
},
{
dimensionKey: 'cluster_id',
maxResourceSelections: 10,
serviceType: 'dbaas',
},
],
};
const { clusterName, dashboardName, engine, id, metrics, nodeType } =
widgetDetails.dbaas;
const serviceType = 'dbaas';
Expand Down Expand Up @@ -132,7 +116,7 @@ const mockAccount = accountFactory.build();

describe('Tests for API error handling', () => {
beforeEach(() => {
mockAppendFeatureFlags(flags);
mockAppendFeatureFlags(flagsFactory.build());
mockGetAccount(mockAccount);
mockGetCloudPulseMetricDefinitions(serviceType, metricDefinitions);
mockGetCloudPulseDashboards(serviceType, [dashboard]).as('fetchDashboard');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ import {
cpuRulesFactory,
dashboardMetricFactory,
databaseFactory,
flagsFactory,
memoryRulesFactory,
notificationChannelFactory,
triggerConditionFactory,
} from 'src/factories';
import { CREATE_ALERT_SUCCESS_MESSAGE } from 'src/features/CloudPulse/Alerts/constants';
import { formatDate } from 'src/utilities/formatDate';

import type { Flags } from 'src/featureFlags';

export interface MetricDetails {
aggregationType: string;
dataField: string;
Expand All @@ -43,8 +41,6 @@ export interface MetricDetails {
threshold: string;
}

const flags: Partial<Flags> = { aclp: { beta: true, enabled: true } };

// Create mock data
const mockAccount = accountFactory.build();
const mockRegions = [
Expand Down Expand Up @@ -176,7 +172,7 @@ describe('Create Alert', () => {
* - Confirms that the UI displays a success message after creating an alert.
*/
beforeEach(() => {
mockAppendFeatureFlags(flags);
mockAppendFeatureFlags(flagsFactory.build());
mockGetAccount(mockAccount);
mockGetProfile(mockProfile);
mockGetCloudPulseServices([serviceType]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
dashboardMetricFactory,
databaseFactory,
dimensionFilterFactory,
flagsFactory,
kubeLinodeFactory,
widgetFactory,
} from 'src/factories';
Expand All @@ -40,7 +41,6 @@ import type {
DimensionFilter,
Widgets,
} from '@linode/api-v4';
import type { Flags } from 'src/featureFlags';
import type { Interception } from 'support/cypress-exports';

/**
Expand All @@ -55,23 +55,6 @@ import type { Interception } from 'support/cypress-exports';
*/
const expectedGranularityArray = ['Auto', '1 day', '1 hr', '5 min'];
const timeDurationToSelect = 'Last 24 Hours';

const flags: Partial<Flags> = {
aclp: { beta: true, enabled: true },
aclpResourceTypeMap: [
{
dimensionKey: 'LINODE_ID',
maxResourceSelections: 10,
serviceType: 'linode',
},
{
dimensionKey: 'cluster_id',
maxResourceSelections: 10,
serviceType: 'dbaas',
},
],
};

const { clusterName, dashboardName, engine, id, metrics, nodeType } =
widgetDetails.dbaas;
const serviceType = 'dbaas';
Expand Down Expand Up @@ -199,7 +182,7 @@ const validateWidgetFilters = (widget: Widgets) => {

describe('Integration Tests for DBaaS Dashboard ', () => {
beforeEach(() => {
mockAppendFeatureFlags(flags);
mockAppendFeatureFlags(flagsFactory.build());
mockGetAccount(mockAccount); // Enables the account to have capability for Akamai Cloud Pulse
mockGetLinodes([mockLinode]);
mockGetCloudPulseMetricDefinitions(serviceType, metricDefinitions);
Expand Down
Loading
Loading