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

feat: [UIE-8194] - DBaaS major and minor upgrades 3 #11198

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
---

DBaaS add new Maintenance component, Upgrade version dialog, Review udpates dialog ([#11198](https://github.com/linode/manager/pull/11198))
corya-akamai marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
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 UPGRADE_VERSION = 'Upgrade Version';

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 { findByRole } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = await findByRole('button', { name: UPGRADE_VERSION });

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

it('should enable 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 { findByRole } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = await findByRole('button', { name: UPGRADE_VERSION });

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 { findByRole } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = await findByRole('button', { name: UPGRADE_VERSION });

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 { queryByRole } = renderWithTheme(
<DatabaseSettingsMaintenance
databaseEngine={database.engine}
databasePendingUpdates={database.updates.pending}
databaseVersion={database.version}
onReviewUpdates={onReviewUpdates}
onUpgradeVersion={onUpgradeVersion}
/>
);

const button = queryByRole('button', { name: 'Click to review' });

expect(button).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Grid, styled } 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 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>
<BoldTypography>Version</BoldTypography>
<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 ? (
<BoldTypography>
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>
</BoldTypography>
) : (
<BoldTypography>
There are no minor version upgrades or patches planned for the next
maintenance window.{' '}
</BoldTypography>
)}
</Grid>
</Grid>
);
};

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

const BoldTypography = styled(StyledTypography)(({ theme }) => ({
fontFamily: theme.font.bold,
}));
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