Skip to content

Commit

Permalink
feat: [UIE-8194] - DBaaS major and minor upgrades 3
Browse files Browse the repository at this point in the history
  • Loading branch information
corya-akamai committed Nov 1, 2024
1 parent 58d25ce commit a4710bf
Show file tree
Hide file tree
Showing 7 changed files with 645 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@linode/manager": Upcoming Features
---

DBaaS add new Maintenance component, Upgrade version dialog, Review udpates dialog ([#11198](https://github.com/linode/manager/pull/11198))
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import React from 'react';

import { databaseFactory } from 'src/factories';
import DatabaseSettingsMaintenance from 'src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsMaintenance';
import { renderWithTheme } from 'src/utilities/testHelpers';

import type { Engine } from '@linode/api-v4';

const queryMocks = vi.hoisted(() => ({
useDatabaseEnginesQuery: vi.fn().mockReturnValue({
data: [
{
engine: 'mysql' as Engine,
id: 'mysql/8',
version: '8',
},
{
engine: 'postgresql' as Engine,
id: 'postgresql/13',
version: '13',
},
{
engine: 'postgresql' as Engine,
id: 'postgresql/14',
version: '14',
},
{
engine: 'postgresql' as Engine,
id: 'postgresql/15',
version: '15',
},
{
engine: 'postgresql' as Engine,
id: 'postgresql/16',
version: '16',
},
],
}),
}));

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

describe('Database Settings Maintenance', () => {
it('should disable upgrade version modal button when there are no upgrades available', async () => {
const database = databaseFactory.build({
engine: 'mysql',
version: '8.0.30',
});

const onReviewUpdates = vi.fn();
const onUpgradeVersion = vi.fn();

const { findByText } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = (await findByText('Upgrade Version')).closest('button');

expect(button).toBeDisabled();
});

it('should enabes upgrade version modal button when there are upgrades available', async () => {
const database = databaseFactory.build({
engine: 'postgresql',
version: '13',
});

const onReviewUpdates = vi.fn();
const onUpgradeVersion = vi.fn();

const { findByText } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = (await findByText('Upgrade Version')).closest('button');

expect(button).toBeEnabled();
});

it('should show review text and modal button when there are updates', async () => {
const database = databaseFactory.build();

const onReviewUpdates = vi.fn();
const onUpgradeVersion = vi.fn();

const { findByText } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = (await findByText('Click to review')).closest('button');

expect(button).toBeEnabled();
});

it('should not show review text and modal button when there are no updates', async () => {
const database = databaseFactory.build({
updates: {
pending: [],
},
});

const onReviewUpdates = vi.fn();
const onUpgradeVersion = vi.fn();

const { queryByText } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = queryByText('Click to review');

expect(button).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Grid, styled, useTheme } from '@mui/material';
import * as React from 'react';

import { StyledLinkButton } from 'src/components/Button/StyledLinkButton';
import { Typography } from 'src/components/Typography';
import {
getDatabasesDescription,
hasPendingUpdates,
upgradableVersions,
} from 'src/features/Databases/utilities';
import { useDatabaseEnginesQuery } from 'src/queries/databases/databases';

import type { Engine, PendingUpdates } from '@linode/api-v4';

interface Props {
databaseEngine: Engine;
databasePendingUpdates?: PendingUpdates[];
databaseVersion: string;
onReviewUpdates: () => void;
onUpgradeVersion: () => void;
}

export const DatabaseSettingsMaintenance = (props: Props) => {
const {
databaseEngine: engine,
databasePendingUpdates,
databaseVersion: version,
onReviewUpdates,
onUpgradeVersion,
} = props;
const theme = useTheme();
const engineVersion = getDatabasesDescription({ engine, version });
const { data: engines } = useDatabaseEnginesQuery(true);
const versions = upgradableVersions(engine, version, engines);
const hasUpdates = hasPendingUpdates(databasePendingUpdates);

return (
<Grid container data-qa-settings-section="Maintenance">
<Grid item xs={4}>
<StyledTypography variant="h3">Maintenance</StyledTypography>
<StyledTypography sx={{ fontFamily: theme.font.bold }}>
Version
</StyledTypography>
<StyledTypography>{engineVersion}</StyledTypography>
<StyledLinkButton
data-testid="upgrade"
disabled={!versions?.length}
onClick={onUpgradeVersion}
>
Upgrade Version
</StyledLinkButton>
</Grid>
<Grid item xs={4}>
{/*
TODO Uncomment and provide value when the EOL is returned by the API.
Currently, it is not supported, however they are working on returning it since it has value to the end user
<StyledTypography variant="h3">End of life</StyledTypography>
*/}
</Grid>
<Grid item xs={4}>
<StyledTypography variant="h3">Maintenance updates</StyledTypography>
{hasUpdates ? (
<StyledTypography sx={{ fontFamily: theme.font.bold }}>
One or more minor version upgrades or patches will be applied during
the next maintenance window.{' '}
<StyledLinkButton data-testid="review" onClick={onReviewUpdates}>
Click to review
</StyledLinkButton>
</StyledTypography>
) : (
<StyledTypography sx={{ fontFamily: theme.font.bold }}>
There are no minor version upgrades or patches planned for the next
maintenance window.{' '}
</StyledTypography>
)}
</Grid>
</Grid>
);
};

export const StyledTypography = styled(Typography)(({ theme }) => ({
marginBottom: theme.spacing(0.25),
}));

export default DatabaseSettingsMaintenance;
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';

import { databaseFactory } from 'src/factories/databases';
import DatabaseSettingsReviewUpdatesDialog from 'src/features/Databases/DatabaseDetail/DatabaseSettings/DatabaseSettingsReviewUpdatesDialog';
import { renderWithTheme } from 'src/utilities/testHelpers';

describe('Database Settings Review Updates Dialog', () => {
it('should list updates', async () => {
const database = databaseFactory.build({
updates: {
pending: [
{
deadline: null,
description: 'Update a',
planned_for: '2044-09-15T17:15:12',
},
{
deadline: null,
description: 'Update b',
planned_for: '2044-09-15T17:15:12',
},
],
},
});

const onClose = vi.fn();

const { findByText } = renderWithTheme(
<DatabaseSettingsReviewUpdatesDialog
databaseEngine={database.engine}
databaseID={database.id}
databasePendingUpdates={database.updates.pending}
onClose={onClose}
open={true}
/>
);

const a = await findByText('Update a');
const b = await findByText('Update b');

expect(a).toBeDefined();
expect(b).toBeDefined();
});

it('should enable buttons', async () => {
const database = databaseFactory.build();

const onClose = vi.fn();

const { findByTestId } = renderWithTheme(
<DatabaseSettingsReviewUpdatesDialog
databaseEngine={database.engine}
databaseID={database.id}
databasePendingUpdates={database.updates.pending}
onClose={onClose}
open={true}
/>
);

const start = await findByTestId('start');
const close = await findByTestId('close');

expect(start).toBeEnabled();
expect(close).toBeEnabled();
});
});
Loading

0 comments on commit a4710bf

Please sign in to comment.