Skip to content

Commit

Permalink
change, test: [M3-7073, M3-7176] - Remove dcSpecificPricing and `ob…
Browse files Browse the repository at this point in the history
…jDcSpecificPricing` feature flags (#9881)

* Remove flag from Migrate dialog and Region selection

* Remove flag from MNTP dialog and Linode Details Network tab

* Remove flag from backups

* Remove flag from invoices

* Remove flag from Volumes and NodeBalancers

* Remove OBJ flag from OBJ

* Remove flag from linodes and kubernetes

* Remove flags from dev tools and feature flags list

* Remove flag on lke tests; fix HA in Create Cluster flow

* Remove flags in Migrate test, OBJ test, and Volumes test

* Remove flags in backup, clone, and create linode tests

* Remove flags in nodebalancer test

* Remove flag from billing test and consolidate... with failure WIP

* Add changesets

* Fix initial unknown prices for Database Create flow

* Remove duplicate instances of "$5.00" by updating mock, move header and summary assertions out of table context

* Make changelogs consistent

* Address feedback: simplify dialog copy

* Address feedback: make variable name more clear

---------

Co-authored-by: Joe D'Amore <jdamore@linode.com>
  • Loading branch information
mjac0bs and Joe D'Amore authored Nov 14, 2023
1 parent ea2bf71 commit 52f0f71
Show file tree
Hide file tree
Showing 75 changed files with 412 additions and 1,748 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-9881-removed-1699393859653.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Removed
---

`dcSpecificPricing` and `objDcSpecificPricing` feature flags ([#9881](https://github.com/linode/manager/pull/9881))
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-9881-tests-1699393816148.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Tests
---

Remove `dcSpecificPricing` and `objDcSpecificPricing` feature flags ([#9881](https://github.com/linode/manager/pull/9881))
273 changes: 109 additions & 164 deletions packages/manager/cypress/e2e/core/billing/billing-invoices.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,9 @@ import {
mockGetInvoice,
mockGetInvoiceItems,
} from 'support/intercepts/account';
import {
mockAppendFeatureFlags,
mockGetFeatureFlagClientstream,
} from 'support/intercepts/feature-flags';
import { ui } from 'support/ui';
import { buildArray } from 'support/util/arrays';
import { formatUsd } from 'support/util/currency';
import { makeFeatureFlagData } from 'support/util/feature-flags';
import { randomItem, randomLabel, randomNumber } from 'support/util/random';
import { chooseRegion, getRegionById } from 'support/util/regions';

Expand All @@ -41,10 +36,13 @@ describe('Account invoices', () => {
* - Confirms that subtotals and tax breakdowns are shown in summary.
* - Confirms that download buttons are present and enabled.
* - Confirms that clicking the "Back to Billing" button redirects to billing page.
* - Confirms that the "Region" column is not present when DC-specific pricing is disabled.
* - Confirms that the "Region" column is present after the MAGIC_DATE_THAT_DC_PRICING_WAS_IMPLEMENTED.
* - Confirms that invoice items that do not have a region are displayed as expected.
* - Confirms that outbound transfer overage items display the associated region when applicable.
* - Confirms that outbound transfer overage items display "Global" when no region is applicable.
*/
it('lists invoice items on invoice details page', () => {
const mockInvoiceItems = buildArray(20, (i) => {
const mockInvoiceItemsWithRegions = buildArray(20, (i) => {
const subtotal = randomNumber(101, 999);
const tax = randomNumber(1, 100);
const hours = randomNumber(1, 24);
Expand Down Expand Up @@ -72,12 +70,38 @@ describe('Account invoices', () => {
});
});

// Regular (non-overage) invoice items.
const mockInvoiceItemsWithAndWithoutRegions = [
...mockInvoiceItemsWithRegions,
invoiceItemFactory.build({
amount: 5,
total: 6,
region: null,
tax: 1,
}),
];

// Outbound transfer overage items.
const mockInvoiceItemsOverages = [
invoiceItemFactory.build({
label: 'Outbound Transfer Overage',
region: null,
}),
invoiceItemFactory.build({
label: 'Outbound Transfer Overage',
region: chooseRegion().id,
}),
];

// Calculate the sum of each item's tax and subtotal.
const sumTax = mockInvoiceItems.reduce((acc: number, cur: InvoiceItem) => {
return acc + cur.tax;
}, 0);
const sumTax = mockInvoiceItemsWithAndWithoutRegions.reduce(
(acc: number, cur: InvoiceItem) => {
return acc + cur.tax;
},
0
);

const sumSubtotal = mockInvoiceItems.reduce(
const sumSubtotal = mockInvoiceItemsWithAndWithoutRegions.reduce(
(acc: number, cur: InvoiceItem) => {
return acc + cur.amount;
},
Expand All @@ -101,43 +125,86 @@ describe('Account invoices', () => {
tax: Math.ceil(sumTax / 2),
},
],
date: MAGIC_DATE_THAT_DC_SPECIFIC_PRICING_WAS_IMPLEMENTED,
});

// TODO: DC Pricing - M3-7073: Remove feature flag mocks when DC specific pricing goes live.
mockAppendFeatureFlags({
dcSpecificPricing: makeFeatureFlagData(false),
}).as('getFeatureFlags');
mockGetFeatureFlagClientstream().as('getClientstream');
// All mocked invoice items.
const mockInvoiceItems = [
...mockInvoiceItemsWithAndWithoutRegions,
...mockInvoiceItemsOverages,
];

mockGetInvoice(mockInvoice).as('getInvoice');
mockGetInvoiceItems(mockInvoice, mockInvoiceItems).as('getInvoiceItems');

cy.visitWithLogin(`/account/billing/invoices/${mockInvoice.id}`);
cy.wait([
'@getFeatureFlags',
'@getClientstream',
'@getInvoice',
'@getInvoiceItems',
]);

// Confirm that "Region" table column is not present.
cy.wait(['@getInvoice', '@getInvoiceItems']);

// Confirm that "Region" table column is not present; old invoices will not be backfilled and we don't want to display a blank column.
cy.findByLabelText('Invoice Details').within(() => {
cy.get('thead').findByText('Region').should('not.exist');
});
// Confirm that 'Region' table column is present.
cy.get('thead').findByText('Region').should('be.visible');

// Confirm that each invoice item is listed on the page with expected data.
mockInvoiceItems.forEach((invoiceItem: InvoiceItem) => {
cy.findByText(invoiceItem.label)
.should('be.visible')
.closest('tr')
.within(() => {
cy.findByText(`${invoiceItem.quantity}`).should('be.visible');
cy.findByText(`$${invoiceItem.unit_price}`).should('be.visible');
cy.findByText(`${formatUsd(invoiceItem.amount)}`).should(
'be.visible'
);
cy.findByText(`${formatUsd(invoiceItem.tax)}`).should('be.visible');
cy.findByText(`${formatUsd(invoiceItem.total)}`).should('be.visible');
});
// Confirm that each regular invoice item is shown, and that the region is
// displayed as expected.
mockInvoiceItemsWithAndWithoutRegions.forEach(
(invoiceItem: InvoiceItem) => {
cy.findByText(invoiceItem.label)
.should('be.visible')
.closest('tr')
.within(() => {
cy.findByText(`${invoiceItem.quantity}`).should('be.visible');
cy.findByText(`$${invoiceItem.unit_price}`).should('be.visible');
cy.findByText(`${formatUsd(invoiceItem.amount)}`).should(
'be.visible'
);
cy.findByText(`${formatUsd(invoiceItem.tax)}`).should(
'be.visible'
);
cy.findByText(`${formatUsd(invoiceItem.total)}`).should(
'be.visible'
);
// If the invoice item has a region, confirm that it is displayed
// in the table row. Otherwise, confirm that the table cell which
// would normally show the region is empty.
!!invoiceItem.region
? cy
.findByText(getRegionLabel(invoiceItem.region))
.should('be.visible')
: cy
.get('[data-qa-region]')
.should('be.visible')
.should('be.empty');
});
}
);

// Confirm that outbound transfer overages are listed as expected.
mockInvoiceItemsOverages.forEach(
(invoiceItem: InvoiceItem, i: number) => {
// There will be multiple instances of the label "Outbound Transfer Overage".
// Select them all, then select the individual item that corresponds to the
// item being iterated upon in the array.
//
// This relies on the items being shown in the same order on-screen as
// they are defined in the array. This may be fragile to breakage if
// we ever change the way invoice items are sorted on this page.
cy.findAllByText(invoiceItem.label)
.should('have.length', 2)
.eq(i)
.closest('tr')
.within(() => {
// If the invoice item has a region, confirm that it is displayed
// in the table row. Otherwise, confirm that "Global" is displayed
// in the region column.
!!invoiceItem.region
? cy
.findByText(getRegionLabel(invoiceItem.region))
.should('be.visible')
: cy.findByText('Global').should('be.visible');
});
}
);
});

// Confirm that invoice header contains invoice label, total, and download buttons.
Expand Down Expand Up @@ -181,120 +248,7 @@ describe('Account invoices', () => {
cy.url().should('endWith', '/account/billing');
});

/*
* - Confirms that invoice item region info is shown when DC-specific pricing is enabled.
* - Confirms that table "Region" column is shown when DC-specific pricing is enabled on new invoices.
* - Confirms that invoice items that do not have a region are displayed as expected.
* - Confirms that outbound transfer overage items display the associated region when applicable.
* - Confirms that outbound transfer overage items display "Global" when no region is applicable.
*/
it('lists invoice item region when DC-specific pricing flag is enabled', () => {
// TODO: DC Pricing - M3-7073: Delete most of this test when DC-specific pricing launches and move assertions to above test. Use this test for the region invoice column.
// We don't have to be fancy with the mocks here since we are only concerned with the region and invoice date.
const mockInvoice = invoiceFactory.build({
id: randomNumber(),
date: MAGIC_DATE_THAT_DC_SPECIFIC_PRICING_WAS_IMPLEMENTED,
});

// Regular invoice items.
const mockInvoiceItemsRegular = [
...buildArray(10, () =>
invoiceItemFactory.build({ region: chooseRegion().id })
),
invoiceItemFactory.build({
region: null,
}),
];

// Outbound transfer overage items.
const mockInvoiceItemsOverages = [
invoiceItemFactory.build({
label: 'Outbound Transfer Overage',
region: null,
}),
invoiceItemFactory.build({
label: 'Outbound Transfer Overage',
region: chooseRegion().id,
}),
];

// All mocked invoice items.
const mockInvoiceItems = [
...mockInvoiceItemsRegular,
...mockInvoiceItemsOverages,
];

mockAppendFeatureFlags({
dcSpecificPricing: makeFeatureFlagData(true),
}).as('getFeatureFlags');
mockGetFeatureFlagClientstream().as('getClientstream');
mockGetInvoice(mockInvoice).as('getInvoice');
mockGetInvoiceItems(mockInvoice, mockInvoiceItems).as('getInvoiceItems');

// Visit invoice details page, wait for relevant requests to resolve.
cy.visitWithLogin(`/account/billing/invoices/${mockInvoice.id}`);
cy.wait([
'@getFeatureFlags',
'@getClientstream',
'@getInvoice',
'@getInvoiceItems',
]);

cy.findByLabelText('Invoice Details').within(() => {
// Confirm that 'Region' table column is present.
cy.get('thead').findByText('Region').should('be.visible');

// Confirm that each regular invoice item is shown, and that the region is
// displayed as expected.
mockInvoiceItemsRegular.forEach((invoiceItem: InvoiceItem) => {
cy.findByText(invoiceItem.label)
.should('be.visible')
.closest('tr')
.within(() => {
// If the invoice item has a region, confirm that it is displayed
// in the table row. Otherwise, confirm that the table cell which
// would normally show the region is empty.
!!invoiceItem.region
? cy
.findByText(getRegionLabel(invoiceItem.region))
.should('be.visible')
: cy
.get('[data-qa-region]')
.should('be.visible')
.should('be.empty');
});

// Confirm that outbound transfer overages are listed as expected.
mockInvoiceItemsOverages.forEach(
(invoiceItem: InvoiceItem, i: number) => {
// There will be multiple instances of the label "Outbound Transfer Overage".
// Select them all, then select the individual item that corresponds to the
// item being iterated upon in the array.
//
// This relies on the items being shown in the same order on-screen as
// they are defined in the array. This may be fragile to breakage if
// we ever change the way invoice items are sorted on this page.
cy.findAllByText(invoiceItem.label)
.should('have.length', 2)
.eq(i)
.closest('tr')
.within(() => {
// If the invoice item has a region, confirm that it is displayed
// in the table row. Otherwise, confirm that "Global" is displayed
// in the region column.
!!invoiceItem.region
? cy
.findByText(getRegionLabel(invoiceItem.region))
.should('be.visible')
: cy.findByText('Global').should('be.visible');
});
}
);
});
});
});

it('does not list the region on past invoices when DC-specific pricing flag is enabled', () => {
it('does not list the region on past invoices', () => {
const mockInvoice = invoiceFactory.build({
id: randomNumber(),
date: '2023-09-30 00:00:00Z',
Expand All @@ -305,21 +259,12 @@ describe('Account invoices', () => {
...buildArray(10, () => invoiceItemFactory.build({ region: null })),
];

mockAppendFeatureFlags({
dcSpecificPricing: makeFeatureFlagData(true),
}).as('getFeatureFlags');
mockGetFeatureFlagClientstream().as('getClientstream');
mockGetInvoice(mockInvoice).as('getInvoice');
mockGetInvoiceItems(mockInvoice, mockInvoiceItems).as('getInvoiceItems');

// Visit invoice details page, wait for relevant requests to resolve.
cy.visitWithLogin(`/account/billing/invoices/${mockInvoice.id}`);
cy.wait([
'@getFeatureFlags',
'@getClientstream',
'@getInvoice',
'@getInvoiceItems',
]);
cy.wait(['@getInvoice', '@getInvoiceItems']);

cy.findByLabelText('Invoice Details').within(() => {
// Confirm that "Region" table column is not present in an invoice created before DC-specific pricing was released.
Expand Down
Loading

0 comments on commit 52f0f71

Please sign in to comment.