-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(RHINENG-12778): Add tooltip for locked OS versions
This PR notifies a user if a system's OS version is locked. When version locking is enabled for a system i.e. a system's OS is tied to a release version, that can affect the count of applicable and installable errata\advisories. The backend now passes a key from the `/systems` api endpoint called `rhsm_lock` and the value is the locked version number. With this PR, we check on the Systems table as well as the CVEs -> CVEDetails tables. When the `rhsm_lock` parameter has a value, we include an icon with a tooltip that tells the user "Your RHEL version is locked..." and at which version it is locked at.
- Loading branch information
1 parent
572579b
commit b1fa4a1
Showing
7 changed files
with
202 additions
and
91 deletions.
There are no files selected for viewing
26 changes: 26 additions & 0 deletions
26
src/Components/PresentationalComponents/VersionLockIconTooltip/VersionLockIconTooltip.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React from 'react'; | ||
import propTypes from 'prop-types'; | ||
import { Flex, FlexItem, Tooltip } from '@patternfly/react-core'; | ||
import { InfoCircleIcon } from '@patternfly/react-icons'; | ||
|
||
const VersionLockIconTooltip = ({ rhsmLock, osName }) => { | ||
return ( | ||
<Tooltip | ||
content={`Your RHEL version is locked at version ${rhsmLock}`} | ||
> | ||
<Flex flex={{ default: 'inlineFlex' }}> | ||
<FlexItem spacer={{ default: 'spacerSm' }}>{osName}</FlexItem> | ||
<FlexItem spacer={{ default: 'spacerSm' }}> | ||
<InfoCircleIcon size="sm" color="var(--pf-v5-global--info-color--100)" data-testid="version-lock-icon" /> | ||
</FlexItem> | ||
</Flex> | ||
</Tooltip> | ||
); | ||
}; | ||
|
||
VersionLockIconTooltip.propTypes = { | ||
rhsmLock: propTypes.string, | ||
osName: propTypes.string | ||
}; | ||
|
||
export default VersionLockIconTooltip; |
23 changes: 23 additions & 0 deletions
23
...Components/PresentationalComponents/VersionLockIconTooltip/VersionLockIconTooltip.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import VersionLockIconTooltip from './VersionLockIconTooltip'; | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import userEvent from '@testing-library/user-event'; | ||
|
||
describe('VersionLockIconTooltip', () => { | ||
it('display tooltip with data', async () => { | ||
render( | ||
<VersionLockIconTooltip rhsmLock='8.1' osName='RHEL 8.1' /> | ||
); | ||
|
||
const hoverBox = screen.getByTestId('version-lock-icon'); | ||
|
||
userEvent.hover(hoverBox); | ||
|
||
await waitFor(() => { | ||
expect (screen.queryByRole('tooltip')).toBeVisible(); | ||
expect(screen.queryByRole('tooltip')).toHaveTextContent( | ||
'Your RHEL version is locked at version 8.1' | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
src/Components/SmartComponents/SystemsPage/SystemsPage.fixtures.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
export const systemRows = [ | ||
{ | ||
culled_timestamp: '2025-02-07T20:02:37.035592+00:00', | ||
cve_count: 2032, | ||
display_name: 'system1', | ||
id: '1234', | ||
insights_id: null, | ||
inventory_group: [], | ||
inventory_id: '4321', | ||
last_evaluation: '2025-01-24T20:02:41.474380+00:00', | ||
last_upload: '2025-01-24T20:02:38.366587+00:00', | ||
opt_out: false, | ||
os: 'RHEL 8.1', | ||
rhsm_lock: '8.1', | ||
rules_evaluation: '2025-01-24T20:02:41.474380+00:00', | ||
selected: false, | ||
stale_timestamp: '2025-01-26T01:02:37.035592+00:00', | ||
stale_warning_timestamp: '2025-01-31T20:02:37.035592+00:00', | ||
tags: [], | ||
updated: '2025-01-24T20:02:37.035592+00:00' | ||
}, | ||
{ | ||
culled_timestamp: '2025-02-07T20:02:37.035592+00:00', | ||
cve_count: 4, | ||
display_name: 'system1', | ||
id: '5678', | ||
insights_id: null, | ||
inventory_group: [], | ||
inventory_id: '8765', | ||
last_evaluation: '2025-01-24T20:02:41.474380+00:00', | ||
last_upload: '2025-01-24T20:02:38.366587+00:00', | ||
opt_out: false, | ||
os: 'RHEL 8.0', | ||
rhsm_lock: '', | ||
rules_evaluation: '2025-01-24T20:02:41.474380+00:00', | ||
selected: false, | ||
stale_timestamp: '2025-01-26T01:02:37.035592+00:00', | ||
stale_warning_timestamp: '2025-01-31T20:02:37.035592+00:00', | ||
tags: [], | ||
updated: '2025-01-24T20:02:37.035592+00:00' | ||
} | ||
]; |
46 changes: 37 additions & 9 deletions
46
src/Components/SmartComponents/SystemsPage/SystemsPage.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,64 @@ | ||
import SystemsPage from './SystemsPage'; | ||
import { render } from '@testing-library/react'; | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom'; | ||
import { useDispatch, useSelector } from 'react-redux'; | ||
import TestWrapper from '../../../Utilities/TestWrapper'; | ||
import { initialState } from '../../../Store/Reducers/SystemsPageStore'; | ||
import { entitiesInitialState, initialState } from '../../../Store/Reducers/SystemsPageStore'; | ||
import configureStore from 'redux-mock-store'; | ||
|
||
jest.mock('../../../Helpers/Hooks', () => ({ | ||
...jest.requireActual('../../../Helpers/Hooks'), | ||
useRbac: () => [[true, true, true, true], false] | ||
})); | ||
|
||
jest.mock("react-redux", () => ({ | ||
...jest.requireActual("react-redux"), | ||
useDispatch: jest.fn(), | ||
useSelector: jest.fn() | ||
})); | ||
|
||
jest.mock('@unleash/proxy-client-react', () => ( { | ||
...jest.requireActual('@unleash/proxy-client-react'), | ||
useFlag: () => true, | ||
useFlagsStatus: () => ({ flagsReady: true }) | ||
})); | ||
|
||
const customMiddleWare = store => next => action => { | ||
useSelector.mockImplementation(callback => { | ||
return callback({ SystemsPageStore: initialState }); | ||
return callback({ SystemsPageStore: initialState, entities: entitiesInitialState }); | ||
}); | ||
next(action); | ||
}; | ||
|
||
const mockStore = configureStore([customMiddleWare]); | ||
const store = mockStore(initialState); | ||
const store = mockStore({ SystemsPageStore: initialState, entities: entitiesInitialState }); | ||
|
||
describe('SystemsPage', () => { | ||
let fetchData = jest.fn(); | ||
let systems = { data: [], meta: {} }; | ||
beforeEach(() => { | ||
useSelector.mockImplementation(callback => { | ||
return callback({ SystemsPageStore: initialState, entities: entitiesInitialState }); | ||
}); | ||
useDispatch.mockReturnValue(jest.fn()); | ||
}); | ||
|
||
afterEach(() => { | ||
useSelector.mockClear(); | ||
store.clearActions(); | ||
}); | ||
|
||
it.skip('should call fetchData function', () => { | ||
it('should call fetchData function', async () => { | ||
render( | ||
<TestWrapper store={ store }> | ||
<SystemsPage systems={systems} fetchData={fetchData} /> | ||
<SystemsPage /> | ||
</TestWrapper> | ||
); | ||
|
||
expect(fetchData).toBeCalled; | ||
await waitFor(() => { | ||
expect( | ||
screen.getByRole('heading', { | ||
name: /vulnerability systems/i | ||
}) | ||
).toBeVisible() | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters