Skip to content

Commit

Permalink
Added tests for PerconaUpdateVersion
Browse files Browse the repository at this point in the history
  • Loading branch information
doracretu3pillar committed Sep 28, 2024
1 parent 2a4b943 commit 43ad471
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 94 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import { Provider } from 'react-redux';
import { waitFor } from 'test/test-utils';

import * as GrafanaUpdates from 'app/percona/shared/core/reducers/updates/updates';
import { UpdatesService } from 'app/percona/shared/services/updates';
import { configureStore } from 'app/store/configureStore';

import PerconaUpdateVersion from './PerconaUpdateVersion';

const checkUpdatesChangeLogsSpy = jest.spyOn(GrafanaUpdates, 'checkUpdatesChangeLogs');
describe('PerconaUpdateVersion', () => {
function setup(store) {
return render(
<Provider store={store}>
<PerconaUpdateVersion />
</Provider>
);
}

beforeEach(() => {
jest.clearAllMocks();
});

it('should render modal with one update', async () => {
const state = {
percona: {
updates: {
updateAvailable: true,
latest: { version: '3.0.1' },
lastChecked: '',
snoozeCurrentVersion: {
user_id: 0,
productTourCompleted: true,
alertingTourCompleted: true,
snoozedPmmVersion: '',
},
changeLogs: {
updates: [
{
version: 'PMM 3.0.1',
tag: 'string',
timestamp: '2024-09-24T09:12:31.488Z',
releaseNotesUrl: 'http://localhost:3000',
releaseNotesText: 'text1',
},
],
},
},
},
};
jest
.spyOn(UpdatesService, 'getUpdatesChangelogs')
.mockReturnValue(Promise.resolve({ ...state.percona.updates.changeLogs }));

const store = configureStore(state);

const { container } = setup(store);
await waitFor(() => {
expect(checkUpdatesChangeLogsSpy).toHaveBeenCalled();
});

expect(screen.getByTestId('one-update-modal')).toBeInTheDocument();
});

it('should render modal with multiple updates', async () => {
const state = {
percona: {
updates: {
updateAvailable: true,
latest: { version: '3.0.1' },
lastChecked: '',
snoozeCurrentVersion: {
user_id: 0,
productTourCompleted: true,
alertingTourCompleted: true,
snoozedPmmVersion: '',
},
changeLogs: {
updates: [
{
version: 'PMM 3.0.1',
tag: 'string',
timestamp: '2024-09-24T09:12:31.488Z',
releaseNotesUrl: 'http://localhost:3000',
releaseNotesText: 'text1',
},
{
version: 'PMM 3.0.2',
tag: 'string',
timestamp: '2024-09-24T09:12:31.488Z',
releaseNotesUrl: 'http://localhost:3000',
releaseNotesText: 'text2',
},
],
},
},
},
};
jest
.spyOn(UpdatesService, 'getUpdatesChangelogs')
.mockReturnValue(Promise.resolve({ ...state.percona.updates.changeLogs }));

const store = configureStore(state);

const { container } = setup(store);
await waitFor(() => {
expect(checkUpdatesChangeLogsSpy).toHaveBeenCalled();
});

expect(screen.getByTestId('multiple-updates-modal')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@ const PerconaUpdateVersion: FC = () => {
const styles = useStyles2(getStyles);

useEffect(() => {
const showModal = async () => {
await dispatch(checkUpdatesChangeLogs());
setShowUpdate(true);
};

const differenceInDays = () => {
if (lastChecked) {
const lastCheckDate = new Date(lastChecked);
Expand All @@ -40,9 +35,9 @@ const PerconaUpdateVersion: FC = () => {
}
};

if (updateAvailable) {
const prepareModal = async () => {
if (!snoozeCurrentVersion) {
dispatch(getSnoozeCurrentVersion());
await dispatch(getSnoozeCurrentVersion());
}
const days = differenceInDays();
if (
Expand All @@ -51,16 +46,21 @@ const PerconaUpdateVersion: FC = () => {
snoozeCurrentVersion?.snoozedPmmVersion !== latest?.version) ||
!lastChecked
) {
showModal();
setShowUpdate(true);
await dispatch(checkUpdatesChangeLogs());
}
};

if (updateAvailable) {
prepareModal();
}
}, [dispatch, updateAvailable, installed, latest, snoozeCurrentVersion, lastChecked]);

const snoozeUpdate = async () => {
if (latest && latest.version) {
const payload = {
productTourCompleted: true, // ?
alertingTourCompleted: true, // ?
productTourCompleted: snoozeCurrentVersion?.productTourCompleted || true,
alertingTourCompleted: snoozeCurrentVersion?.alertingTourCompleted || true,
snoozedPmmVersion: latest.version,
};
await dispatch(setSnoozeCurrentUpdate(payload));
Expand All @@ -77,49 +77,53 @@ const PerconaUpdateVersion: FC = () => {
<Modal
onDismiss={onDismiss}
title={Messages.titleOneUpdate}
isOpen={showUpdate && changeLogs && changeLogs?.updates.length === 1}
isOpen={showUpdate && changeLogs && changeLogs?.updates?.length === 1}
className={styles.updateVersionModal}
>
<h5 className={styles.version}>{changeLogs?.updates[0].version}</h5>
<p className={styles.releaseNotesText}>
<a href={changeLogs?.updates[0].releaseNotesUrl}>{Messages.fullReleaseNotes}</a>
</p>
<h5 className={styles.howToUpdateTitle}>{Messages.howToUpdate}</h5>
<p className={styles.howToUpdateDescription}>{Messages.howToUpdateDescription}</p>
<div className={styles.updateButtons}>
<Button type="button" variant="secondary" onClick={snoozeUpdate} className={styles.snoozeButton}>
{Messages.snooze}
</Button>
<Button type="button" variant="primary">
<a href="/pmm-ui/updates">{Messages.goToUpdatesPage}</a>
</Button>
<div data-testid="one-update-modal">
<h5 className={styles.version}>{changeLogs?.updates[0]?.version || ''}</h5>
<p className={styles.releaseNotesText}>
<a href={changeLogs?.updates[0]?.releaseNotesUrl || ''}>{Messages.fullReleaseNotes}</a>
</p>
<h5 className={styles.howToUpdateTitle}>{Messages.howToUpdate}</h5>
<p className={styles.howToUpdateDescription}>{Messages.howToUpdateDescription}</p>
<div className={styles.updateButtons}>
<Button type="button" variant="secondary" onClick={snoozeUpdate} className={styles.snoozeButton}>
{Messages.snooze}
</Button>
<Button type="button" variant="primary">
<a href="/pmm-ui/updates">{Messages.goToUpdatesPage}</a>
</Button>
</div>
</div>
</Modal>
<Modal
onDismiss={onDismiss}
title={Messages.titleMultipleUpdates}
isOpen={showUpdate && changeLogs && changeLogs?.updates.length > 1}
isOpen={showUpdate && changeLogs && changeLogs?.updates?.length > 1}
className={styles.updateVersionModal}
>
<h5 className={styles.newVersionsTitle}>{Messages.newVersions}</h5>
<ul className={styles.listOfReleaseNotes}>
{changeLogs?.updates.map((update: UpdatesChangelogs) => (
<li key={update.toString()}>
<a href={update.releaseNotesUrl}>
{update.version}, {dateTimeFormat(update.timestamp, { format: 'MMM DD, YYYY' })}
</a>
</li>
))}
</ul>
<h5 className={styles.notesTitle}>{Messages.notes}</h5>
<p>{Messages.notesDescription}</p>
<div className={styles.updateButtons}>
<Button type="button" variant="secondary" onClick={snoozeUpdate} className={styles.snoozeButton}>
{Messages.snooze}
</Button>
<Button type="button" variant="primary">
<a href="/pmm-ui/updates">{Messages.goToUpdatesPage}</a>
</Button>
<div data-testid="multiple-updates-modal">
<h5 className={styles.newVersionsTitle}>{Messages.newVersions}</h5>
<ul className={styles.listOfReleaseNotes}>
{changeLogs?.updates.map((update: UpdatesChangelogs) => (
<li key={update.toString()}>
<a href={update.releaseNotesUrl}>
{update.version}, {dateTimeFormat(update.timestamp, { format: 'MMM DD, YYYY' })}
</a>
</li>
))}
</ul>
<h5 className={styles.notesTitle}>{Messages.notes}</h5>
<p>{Messages.notesDescription}</p>
<div className={styles.updateButtons}>
<Button type="button" variant="secondary" onClick={snoozeUpdate} className={styles.snoozeButton}>
{Messages.snooze}
</Button>
<Button type="button" variant="primary">
<a href="/pmm-ui/updates">{Messages.goToUpdatesPage}</a>
</Button>
</div>
</div>
</Modal>
</>
Expand Down
58 changes: 8 additions & 50 deletions public/app/percona/shared/core/reducers/updates/updates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import { withSerializedError } from 'app/features/alerting/unified/utils/redux';
import { UpdatesService } from 'app/percona/shared/services/updates';

import {
CheckUpdatesChangeLogsResponse,
CheckUpdatesPayload,
SnoozePayloadBody,
SnoozePayloadResponse,
UpdatesState,
} from './updates.types';
import { CheckUpdatesPayload, SnoozePayloadBody, SnoozePayloadResponse, UpdatesState } from './updates.types';
import { responseToPayload } from './updates.utils';

const initialState: UpdatesState = {
Expand All @@ -22,52 +16,26 @@ export const updatesSlice = createSlice({
reducers: {},
extraReducers: (builder) => {
builder.addCase(checkUpdatesAction.pending, (state) => ({
...initialState,
...state,
isLoading: true,
}));

builder.addCase(checkUpdatesAction.fulfilled, (state, { payload }) => ({
...state,
...payload,
updateAvailable: true, // to remove
latest: { version: '3.0.1' }, // to remove
isLoading: false,
lastChecked: '',
}));

builder.addCase(checkUpdatesAction.rejected, (state) => ({
...initialState,
...state,
isLoading: false,
}));
builder.addCase(checkUpdatesChangeLogs.pending, (state) => ({
...initialState,
...state,
isLoading: true,
}));

builder.addCase(checkUpdatesChangeLogs.fulfilled, (state, { payload }) => ({
...state,
isLoading: false,
changeLogs: {
...payload,
updates: [
{
version: 'PMM 3.0.1',
tag: 'string',
timestamp: '2024-09-24T09:12:31.488Z',
releaseNotesUrl: 'https://google.com',
releaseNotesText: 'asdasd',
},
{
version: 'PMM 3.0.1',
tag: 'string',
timestamp: '2024-09-24T09:12:31.488Z',
releaseNotesUrl: 'https://google.com',
releaseNotesText: 'asdasd',
},
],
},
changeLogs: payload,
}));

builder.addCase(checkUpdatesChangeLogs.rejected, (state) => ({
...state,
isLoading: false,
Expand All @@ -76,13 +44,11 @@ export const updatesSlice = createSlice({
...state,
isLoading: true,
}));

builder.addCase(getSnoozeCurrentVersion.fulfilled, (state, { payload }) => ({
...state,
snoozeCurrentVersion: payload,
isLoading: false,
}));

builder.addCase(getSnoozeCurrentVersion.rejected, (state) => ({
...state,
isLoading: false,
Expand All @@ -91,13 +57,11 @@ export const updatesSlice = createSlice({
...state,
isLoading: true,
}));

builder.addCase(setSnoozeCurrentUpdate.fulfilled, (state, { payload }) => ({
...state,
snoozeCurrentVersion: payload,
isLoading: false,
}));

builder.addCase(setSnoozeCurrentUpdate.rejected, (state) => ({
...state,
isLoading: false,
Expand All @@ -115,15 +79,9 @@ export const checkUpdatesAction = createAsyncThunk('percona/checkUpdates', async
}
});

export const checkUpdatesChangeLogs = createAsyncThunk(
'percona/checkUpdatesChangelogs',
async (): Promise<CheckUpdatesChangeLogsResponse> =>
withSerializedError(
(async () => {
return await UpdatesService.getUpdatesChangelogs();
})()
)
);
export const checkUpdatesChangeLogs = createAsyncThunk('percona/checkUpdatesChangelogs', async () => {
return await UpdatesService.getUpdatesChangelogs();
});

export const setSnoozeCurrentUpdate = createAsyncThunk(
'percona/setSnoozeCurrentUpdate',
Expand Down

0 comments on commit 43ad471

Please sign in to comment.