diff options
author | Viktor Vorona <viktor.vorona@sonarsource.com> | 2024-04-09 16:43:01 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2024-04-10 20:02:53 +0000 |
commit | ecdde07064702a375eff133e94d1c1dc0b65ecf8 (patch) | |
tree | 0a8931869cfc4fa89f143f45097a0fbab0591898 | |
parent | 791659dd5e60709f28f9afa7983cee5375acb136 (diff) | |
download | sonarqube-ecdde07064702a375eff133e94d1c1dc0b65ecf8.tar.gz sonarqube-ecdde07064702a375eff133e94d1c1dc0b65ecf8.zip |
SONAR-22018 Introduce active version in notification banner
5 files changed, 44 insertions, 15 deletions
diff --git a/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx b/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx index d63ffc032ca..b15c1268be8 100644 --- a/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx +++ b/server/sonar-web/src/main/js/app/components/update-notification/UpdateNotification.tsx @@ -23,7 +23,8 @@ import { getSystemUpgrades } from '../../../api/system'; import { Alert, AlertVariant } from '../../../components/ui/Alert'; import DismissableAlert from '../../../components/ui/DismissableAlert'; import SystemUpgradeButton from '../../../components/upgrade/SystemUpgradeButton'; -import { sortUpgrades, UpdateUseCase } from '../../../components/upgrade/utils'; +import { UpdateUseCase, sortUpgrades } from '../../../components/upgrade/utils'; +import { now, parseDate } from '../../../helpers/dates'; import { translate } from '../../../helpers/l10n'; import { hasGlobalPermission } from '../../../helpers/users'; import { AppState } from '../../../types/appstate'; @@ -158,7 +159,7 @@ export class UpdateNotification extends React.PureComponent<Props, State> { const { upgrades, latestLTS } = await getSystemUpgrades(); - if (isEmpty(upgrades)) { + if (isEmpty(upgrades) && parseDate(this.props.appState.versionEOL) > now()) { // No new upgrades this.noPromptToShow(); return; @@ -177,7 +178,9 @@ export class UpdateNotification extends React.PureComponent<Props, State> { let useCase = UpdateUseCase.NewMinorVersion; - if (this.isPreviousLTSUpdate(parsedVersion, latestLTS, systemUpgrades)) { + if (parseDate(this.props.appState.versionEOL) <= now()) { + useCase = UpdateUseCase.PreviousLTS; + } else if (this.isPreviousLTSUpdate(parsedVersion, latestLTS, systemUpgrades)) { useCase = UpdateUseCase.PreviousLTS; } else if (this.isPreLTSUpdate(parsedVersion, latestLTS)) { useCase = UpdateUseCase.PreLTS; @@ -193,7 +196,7 @@ export class UpdateNotification extends React.PureComponent<Props, State> { new Date(upgrade1.releaseDate || '').getTime() )[0]; - const dismissKey = useCase + latest.version; + const dismissKey = useCase + latest?.version; if (this.mounted) { this.setState({ diff --git a/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx b/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx index 622b0c3dca4..f770c53cceb 100644 --- a/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx +++ b/server/sonar-web/src/main/js/app/components/update-notification/__tests__/UpdateNotification-test.tsx @@ -43,14 +43,14 @@ function formatDate(date: Date): string { it('should render correctly', async () => { let wrapper = shallowRender({ - appState: mockAppState({ version: '9.0' }), + appState: mockAppState({ version: '9.0', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); expect(wrapper).toMatchSnapshot('default'); wrapper = shallowRender({ - appState: mockAppState({ version: '9.0' }), + appState: mockAppState({ version: '9.0', versionEOL: '2026-01-01' }), currentUser: mockCurrentUser(), }); expect(wrapper.type()).toBeNull(); @@ -69,7 +69,9 @@ it('should not show prompt when not admin', async () => { }); it('should not show prompt when no current version', async () => { - const wrapper = shallowRender({ appState: mockAppState({ version: 'NOVERSION' }) }); + const wrapper = shallowRender({ + appState: mockAppState({ version: 'NOVERSION', versionEOL: '2026-01-01' }), + }); await waitAndUpdate(wrapper); expect(wrapper.type()).toBeNull(); }); @@ -77,7 +79,7 @@ it('should not show prompt when no current version', async () => { it('should not show prompt when no upgrade', async () => { (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({ upgrades: [], latestLTS: '8.9' }); const wrapper = shallowRender({ - appState: mockAppState({ version: '9.1' }), + appState: mockAppState({ version: '9.1', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -90,7 +92,7 @@ it('should show prompt when no lts date', async () => { latestLTS: '8.9', }); const wrapper = shallowRender({ - appState: mockAppState({ version: '8.1' }), + appState: mockAppState({ version: '8.1', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -104,7 +106,7 @@ it('should show prompt when minor upgrade', async () => { latestLTS: '8.9', }); const wrapper = shallowRender({ - appState: mockAppState({ version: '9.1' }), + appState: mockAppState({ version: '9.1', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -118,7 +120,7 @@ it('should show prompt when patch upgrade', async () => { latestLTS: '8.9', }); const wrapper = shallowRender({ - appState: mockAppState({ version: '9.1' }), + appState: mockAppState({ version: '9.1', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -136,7 +138,7 @@ it('should show prompt when lts upgrade', async () => { latestLTS: '8.9', }); const wrapper = shallowRender({ - appState: mockAppState({ version: '8.8' }), + appState: mockAppState({ version: '8.8', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -156,7 +158,7 @@ it('should show prompt when lts upgrade is more than 6 month', async () => { latestLTS: '8.9', }); const wrapper = shallowRender({ - appState: mockAppState({ version: '8.8' }), + appState: mockAppState({ version: '8.8', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -174,7 +176,7 @@ it('should show correct alert when not dismissable', async () => { latestLTS: '8.9', }); const wrapper = shallowRender({ - appState: mockAppState({ version: '8.8' }), + appState: mockAppState({ version: '8.8', versionEOL: '2026-01-01' }), currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), }); await waitAndUpdate(wrapper); @@ -183,6 +185,16 @@ it('should show correct alert when not dismissable', async () => { expect(wrapper.find(Alert).type).toBeDefined(); }); +it('should show alert if version has reached eol, but there are no upgrades', async () => { + (getSystemUpgrades as jest.Mock).mockResolvedValueOnce({ upgrades: [], latestLTS: '9.9' }); + const wrapper = shallowRender({ + appState: mockAppState({ version: '9.9', versionEOL: '2020-01-01' }), + currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Admin] } }), + }); + await waitAndUpdate(wrapper); + expect(wrapper.contains('admin_notification.update.previous_lts')).toBe(true); +}); + function shallowRender(props: Partial<UpdateNotification['props']> = {}) { return shallow( <UpdateNotification diff --git a/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeButton.tsx b/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeButton.tsx index ed1b3573c3b..cbd8ba2f1a5 100644 --- a/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeButton.tsx +++ b/server/sonar-web/src/main/js/components/upgrade/SystemUpgradeButton.tsx @@ -48,6 +48,11 @@ export default class SystemUpgradeButton extends React.PureComponent<Props, Stat render() { const { latestLTS, systemUpgrades, updateUseCase } = this.props; const { openSystemUpgradeForm } = this.state; + + if (systemUpgrades.length === 0) { + return null; + } + return ( <> <Button className="spacer-left" onClick={this.handleOpenSystemUpgradeForm}> diff --git a/server/sonar-web/src/main/js/components/upgrade/__tests__/SystemUpgradeButton-test.tsx b/server/sonar-web/src/main/js/components/upgrade/__tests__/SystemUpgradeButton-test.tsx index 7cd2ccbeada..0a6f6a6af69 100644 --- a/server/sonar-web/src/main/js/components/upgrade/__tests__/SystemUpgradeButton-test.tsx +++ b/server/sonar-web/src/main/js/components/upgrade/__tests__/SystemUpgradeButton-test.tsx @@ -19,6 +19,7 @@ */ import { shallow } from 'enzyme'; import * as React from 'react'; +import { mockSystemUpgrade } from '../../../helpers/mocks/system-upgrades'; import { click } from '../../../helpers/testUtils'; import { Button } from '../../controls/buttons'; import SystemUpgradeButton from '../SystemUpgradeButton'; @@ -31,8 +32,14 @@ it('should open modal correctly', () => { expect(wrapper.find(SystemUpgradeForm)).toBeDefined(); }); +it('should not show button if there are no upgrades', () => { + const wrapper = shallowRender({ systemUpgrades: [] }); + expect(wrapper).toMatchSnapshot(); + expect(wrapper.find(Button).exists()).toBe(false); +}); + function shallowRender(props: Partial<SystemUpgradeButton['props']> = {}) { return shallow<SystemUpgradeButton['props']>( - <SystemUpgradeButton systemUpgrades={[]} latestLTS="9.2" {...props} /> + <SystemUpgradeButton systemUpgrades={[mockSystemUpgrade()]} latestLTS="9.2" {...props} /> ); } diff --git a/server/sonar-web/src/main/js/components/upgrade/__tests__/__snapshots__/SystemUpgradeButton-test.tsx.snap b/server/sonar-web/src/main/js/components/upgrade/__tests__/__snapshots__/SystemUpgradeButton-test.tsx.snap index 037b14bb219..1b581220ca7 100644 --- a/server/sonar-web/src/main/js/components/upgrade/__tests__/__snapshots__/SystemUpgradeButton-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/upgrade/__tests__/__snapshots__/SystemUpgradeButton-test.tsx.snap @@ -1,5 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should not show button if there are no upgrades 1`] = `""`; + exports[`should open modal correctly 1`] = ` <Fragment> <Button |