-
Notifications
You must be signed in to change notification settings - Fork 702
CONSOLE-5284: Put new node inventory items behind tech-preview #16414
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import type { FC } from 'react'; | ||
| import { useContext } from 'react'; | ||
| import { DescriptionListDescription, DescriptionListGroup } from '@patternfly/react-core'; | ||
| import { useTranslation } from 'react-i18next'; | ||
| import { Link } from 'react-router'; | ||
| import { | ||
| useWatchVirtualMachineInstances, | ||
| VirtualMachineModel, | ||
| } from '@console/app/src/components/nodes/NodeVmUtils'; | ||
| import { useIsKubevirtPluginActive } from '@console/app/src/utils/kubevirt'; | ||
| import { resourcePathFromModel } from '@console/internal/components/utils/resource-link'; | ||
| import { InventoryItem } from '@console/shared/src/components/dashboard/inventory-card/InventoryItem'; | ||
| import { DescriptionListTermHelp } from '@console/shared/src/components/description-list/DescriptionListTermHelp'; | ||
| import { NodeDashboardContext } from './NodeDashboardContext'; | ||
|
|
||
| const VirtualMachinesInventoryItems: FC = () => { | ||
| const { obj } = useContext(NodeDashboardContext); | ||
| const { t } = useTranslation(); | ||
| const showVms = useIsKubevirtPluginActive(); | ||
|
|
||
| const [vms, vmsLoaded, vmsLoadError] = useWatchVirtualMachineInstances(obj.metadata.name); | ||
|
|
||
| if (!showVms) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 Good extraction. The early-return guard pattern mirrors |
||
| return null; | ||
| } | ||
|
|
||
| return ( | ||
| <DescriptionListGroup> | ||
| <DescriptionListTermHelp | ||
| text={t('console-app~Virtual machines')} | ||
| textHelp={t( | ||
| 'console-app~This count reflects your access permissions and might not include all virtual machines.', | ||
| )} | ||
| /> | ||
| <DescriptionListDescription> | ||
| <Link | ||
| to={`${resourcePathFromModel(VirtualMachineModel)}/search?rowFilter-node=${ | ||
| obj.metadata.name | ||
| }`} | ||
| > | ||
| <InventoryItem | ||
| isLoading={!vmsLoaded} | ||
| title={t('console-app~Virtual machine')} | ||
| titlePlural={t('console-app~Virtual machines')} | ||
| count={vms.length} | ||
| error={!!vmsLoadError} | ||
| /> | ||
| </Link> | ||
| </DescriptionListDescription> | ||
| </DescriptionListGroup> | ||
| ); | ||
| }; | ||
|
|
||
| export default VirtualMachinesInventoryItems; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New component without unit tests. There's an existing
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,128 @@ | ||
| import { render, screen } from '@testing-library/react'; | ||
| import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook'; | ||
| import type { NodeKind } from '@console/internal/module/k8s'; | ||
| import { useFlag } from '@console/shared/src/hooks/useFlag'; | ||
| import BareMetalInventoryItems from '../BareMetalInventoryItems'; | ||
| import InventoryCard from '../InventoryCard'; | ||
| import { NodeDashboardContext } from '../NodeDashboardContext'; | ||
| import VirtualMachinesInventoryItems from '../VirtualMachinesInventoryItems'; | ||
|
|
||
| jest.mock('@console/shared/src/hooks/useFlag', () => ({ | ||
| useFlag: jest.fn(), | ||
| })); | ||
|
|
||
| jest.mock('@console/internal/components/utils/k8s-watch-hook', () => ({ | ||
| useK8sWatchResource: jest.fn(), | ||
| })); | ||
|
|
||
| // Mock child components using jest.fn | ||
| jest.mock('@console/app/src/components/nodes/node-dashboard/BareMetalInventoryItems', () => ({ | ||
| __esModule: true, | ||
| default: jest.fn(() => null), | ||
| })); | ||
|
|
||
| jest.mock('@console/app/src/components/nodes/node-dashboard/VirtualMachinesInventoryItems', () => ({ | ||
| __esModule: true, | ||
| default: jest.fn(() => null), | ||
| })); | ||
|
|
||
| // Mock InventoryItem components | ||
| jest.mock('@console/shared/src/components/dashboard/inventory-card/InventoryItem', () => ({ | ||
| InventoryItem: ({ count }) => `Images: ${count || 0}`, | ||
| ResourceInventoryItem: () => 'Pod Inventory', | ||
| })); | ||
|
|
||
| const useFlagMock = useFlag as jest.Mock; | ||
| const useK8sWatchResourceMock = useK8sWatchResource as jest.Mock; | ||
| const BareMetalInventoryItemsMock = BareMetalInventoryItems as jest.Mock; | ||
| const VirtualMachinesInventoryItemsMock = VirtualMachinesInventoryItems as jest.Mock; | ||
|
|
||
| describe('InventoryCard', () => { | ||
| const mockNode: NodeKind = { | ||
| apiVersion: 'v1', | ||
| kind: 'Node', | ||
| metadata: { | ||
| name: 'test-node', | ||
| uid: 'node-uid', | ||
| }, | ||
| spec: {}, | ||
| status: { | ||
| images: [{ names: ['image1'] }, { names: ['image2'] }], | ||
| }, | ||
| }; | ||
|
|
||
| const renderWithContext = (node: NodeKind = mockNode) => { | ||
| return render( | ||
| <NodeDashboardContext.Provider | ||
| value={{ | ||
| obj: node, | ||
| setCPULimit: () => {}, | ||
| setMemoryLimit: () => {}, | ||
| setHealthCheck: () => {}, | ||
| }} | ||
| > | ||
| <InventoryCard /> | ||
| </NodeDashboardContext.Provider>, | ||
| ); | ||
| }; | ||
|
|
||
| beforeEach(() => { | ||
| jest.clearAllMocks(); | ||
| useK8sWatchResourceMock.mockReturnValue([[], true, undefined]); | ||
| }); | ||
|
|
||
| it('should render the inventory card with title', () => { | ||
| useFlagMock.mockReturnValue(false); | ||
| renderWithContext(); | ||
|
|
||
| expect(screen.getByText('Inventory')).toBeVisible(); | ||
| }); | ||
|
|
||
| it('should render Pod and Image inventory items when NODE_MGMT_V1 flag state is false', () => { | ||
| useFlagMock.mockReturnValue(false); | ||
| renderWithContext(); | ||
|
|
||
| expect(screen.getByText('Pods')).toBeVisible(); | ||
| expect(screen.getByText('Pod Inventory')).toBeVisible(); | ||
| expect(screen.getByText('Images')).toBeVisible(); | ||
| expect(screen.getByText('Images: 2')).toBeVisible(); | ||
| }); | ||
|
|
||
| it('should render Pod and Image inventory items when NODE_MGMT_V1 flag state is true', () => { | ||
| useFlagMock.mockReturnValue(true); | ||
| renderWithContext(); | ||
|
|
||
| expect(screen.getByText('Pods')).toBeVisible(); | ||
| expect(screen.getByText('Pod Inventory')).toBeVisible(); | ||
| expect(screen.getByText('Images')).toBeVisible(); | ||
| expect(screen.getByText('Images: 2')).toBeVisible(); | ||
| }); | ||
|
|
||
| it('should not render BareMetalInventoryItems when NODE_MGMT_V1 flag is off', () => { | ||
| useFlagMock.mockReturnValue(false); | ||
| renderWithContext(); | ||
|
|
||
| expect(BareMetalInventoryItemsMock).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('should not render VirtualMachinesInventoryItems when NODE_MGMT_V1 flag is off', () => { | ||
| useFlagMock.mockReturnValue(false); | ||
| renderWithContext(); | ||
|
|
||
| expect(VirtualMachinesInventoryItemsMock).not.toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('should render BareMetalInventoryItems when NODE_MGMT_V1 flag is on', () => { | ||
| useFlagMock.mockReturnValue(true); | ||
| renderWithContext(); | ||
|
|
||
| expect(BareMetalInventoryItemsMock).toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('should render VirtualMachinesInventoryItems when NODE_MGMT_V1 flag is on', () => { | ||
| useFlagMock.mockReturnValue(true); | ||
| renderWithContext(); | ||
|
|
||
| expect(VirtualMachinesInventoryItemsMock).toHaveBeenCalled(); | ||
| }); | ||
| }); |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The core behavioral change of this PR — gating bare metal and VM items behind
NODE_MGMT_V1— has no automated test coverage. Please add tests forInventoryCardverifying:NODE_MGMT_V1off:BareMetalInventoryItemsandVirtualMachinesInventoryItemsdo not renderNODE_MGMT_V1on: both render