Skip to content

Commit

Permalink
fix: [M3-7739] - Fix error when enabling backups for Linodes in regio…
Browse files Browse the repository at this point in the history
…ns with $0 price (#10153)

* Fix error when enabling backups for Linodes in regions with $0 price

* Add unit tests for EnableBackupsDialog

---------

Co-authored-by: Mariah Jacobs <114685994+mjac0bs@users.noreply.github.com>
  • Loading branch information
jdamore-linode and mjac0bs authored Feb 9, 2024
1 parent 466d3c5 commit e68bbb0
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 2 deletions.
5 changes: 5 additions & 0 deletions packages/manager/.changeset/pr-10153-fixed-1707249479775.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Fixed
---

Error when enabling backups for Linodes in regions with $0 pricing ([#10153](https://github.com/linode/manager/pull/10153))
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import * as React from 'react';
import { renderWithTheme } from 'src/utilities/testHelpers';
import { EnableBackupsDialog } from './EnableBackupsDialog';
import { PRICES_RELOAD_ERROR_NOTICE_TEXT } from 'src/utilities/pricing/constants';
import { typeFactory } from 'src/factories/types';
import { linodeFactory } from 'src/factories';

const queryMocks = vi.hoisted(() => ({
useLinodeQuery: vi.fn().mockReturnValue({
data: undefined,
}),
useTypeQuery: vi.fn().mockReturnValue({
data: undefined,
}),
}));

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

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

describe('EnableBackupsDialog component', () => {
beforeEach(() => {
queryMocks.useTypeQuery.mockReturnValue({
data: typeFactory.build({
id: 'mock-linode-type',
label: 'Mock Linode Type',
addons: {
backups: {
price: {
hourly: 0.004,
monthly: 2.5,
},
region_prices: [
{
hourly: 0,
id: 'es-mad',
monthly: 0,
},
],
},
},
}),
});
});

it('Displays the monthly backup price', async () => {
queryMocks.useLinodeQuery.mockReturnValue({
data: linodeFactory.build({
id: 1,
label: 'Mock Linode',
type: 'mock-linode-type',
region: 'us-east',
}),
});

const { findByText } = renderWithTheme(
<EnableBackupsDialog linodeId={1} onClose={vi.fn()} open={true} />
);

// Confirm that the user is warned that they will be billed, and that the correct
// price is displayed.
expect(
await findByText(
/Are you sure you want to enable backups on this Linode\?.*/
)
).toHaveTextContent(/This will add .* to your monthly bill/);
expect(await findByText('$2.50')).toBeVisible();
});

it('Displays the monthly backup price when the price is $0', async () => {
queryMocks.useLinodeQuery.mockReturnValue({
data: linodeFactory.build({
id: 1,
label: 'Mock Linode',
type: 'mock-linode-type',
region: 'es-mad',
}),
});

const { getByTestId, findByText, queryByText } = renderWithTheme(
<EnableBackupsDialog linodeId={1} onClose={vi.fn()} open={true} />
);

// Confirm that the user is warned that they will be billed, and that $0.00
// is shown.
expect(
await findByText(
/Are you sure you want to enable backups on this Linode\?.*/
)
).toHaveTextContent(/This will add .* to your monthly bill/);
expect(await findByText('$0.00')).toBeVisible();

// Confirm that error message is not present.
expect(queryByText(PRICES_RELOAD_ERROR_NOTICE_TEXT)).toBeNull();

// Confirm that "Enable Backups" button is enabled.
expect(getByTestId('confirm-enable-backups')).toBeEnabled();
});

it('Displays an error when backup price cannot be determined', async () => {
queryMocks.useTypeQuery.mockReturnValue({
data: undefined,
});

queryMocks.useLinodeQuery.mockReturnValue({
data: linodeFactory.build({
id: 1,
label: 'Mock Linode',
type: 'mock-linode-type',
region: 'es-mad',
}),
});

const { getByTestId, findByText } = renderWithTheme(
<EnableBackupsDialog linodeId={1} onClose={vi.fn()} open={true} />
);

// Confirm that error message is not present.
expect(await findByText(PRICES_RELOAD_ERROR_NOTICE_TEXT)).toBeVisible();

// Confirm that "Enable Backups" button is disabled.
expect(getByTestId('confirm-enable-backups')).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export const EnableBackupsDialog = (props: Props) => {
type,
});

const hasBackupsMonthlyPriceError =
!backupsMonthlyPrice && backupsMonthlyPrice !== 0;

const { enqueueSnackbar } = useSnackbar();

const { checkForNewEvents } = useEventsPollingActions();
Expand All @@ -70,7 +73,7 @@ export const EnableBackupsDialog = (props: Props) => {
<ActionsPanel
primaryButtonProps={{
'data-testid': 'confirm-enable-backups',
disabled: !backupsMonthlyPrice,
disabled: hasBackupsMonthlyPriceError,
label: 'Enable Backups',
loading: isLoading,
onClick: handleEnableBackups,
Expand All @@ -92,7 +95,7 @@ export const EnableBackupsDialog = (props: Props) => {
open={open}
title="Enable backups?"
>
{backupsMonthlyPrice ? (
{!hasBackupsMonthlyPriceError ? (
<Typography>
Are you sure you want to enable backups on this Linode?{` `}
This will add <Currency quantity={backupsMonthlyPrice} />
Expand Down

0 comments on commit e68bbb0

Please sign in to comment.