diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.test.tsx new file mode 100644 index 0000000000000..059ce60f16799 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.test.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; + +import { ThemeProvider } from 'styled-components'; + +import type { Agent } from '../../../../../types'; +import { useLink } from '../../../../../hooks'; +import { createPackagePolicyMock } from '../../../../../../../../common/mocks'; + +import { AgentDetailsIntegrationInputs } from './agent_details_integration_inputs'; + +jest.mock('../../../../../hooks'); +const mockUseLink = useLink as jest.Mock; + +describe('AgentDetailsIntegrationInputs', () => { + const agent: Agent = { + id: '123', + packages: [], + type: 'PERMANENT', + active: true, + enrolled_at: `${Date.now()}`, + user_provided_metadata: {}, + local_metadata: {}, + }; + + const packageMock = createPackagePolicyMock(); + + beforeEach(() => { + mockUseLink.mockReturnValue({ getHref: jest.fn() }); + }); + + const renderComponent = () => { + return render( + + ({ eui: { euiSizeS: '15px' } })}> + + + + ); + }; + + it('renders a default health icon when the agent has no components at all', () => { + const component = renderComponent(); + userEvent.click(component.getByTestId('agentIntegrationsInputsTitle')); + expect( + component.getByTestId('agentDetailsIntegrationsInputStatusHealthDefault') + ).toBeInTheDocument(); + }); + + it('renders a default health icon when the package input has no match in the agent component units', () => { + agent.components = [ + { + id: 'endpoint-default', + type: 'endpoint', + status: 'HEALTHY', + message: 'Healthy', + units: [ + { + id: 'endpoint-default', + type: 'input', + status: 'HEALTHY', + message: 'Applied policy', + }, + ], + }, + ]; + + const component = renderComponent(); + userEvent.click(component.getByTestId('agentIntegrationsInputsTitle')); + expect( + component.getByTestId('agentDetailsIntegrationsInputStatusHealthDefault') + ).toBeInTheDocument(); + }); + + it('renders a success health icon when the package input has a match in the agent component units', () => { + agent.components = [ + { + id: 'endpoint-default', + type: 'endpoint', + status: 'HEALTHY', + message: 'Healthy', + units: [ + { + id: `endpoint-default-${packageMock.id}`, + type: 'input', + status: 'HEALTHY', + message: 'Applied policy', + }, + ], + }, + ]; + + const component = renderComponent(); + userEvent.click(component.getByTestId('agentIntegrationsInputsTitle')); + expect( + component.getByTestId('agentDetailsIntegrationsInputStatusHealthSuccess') + ).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.tsx index 4a21a3ddba344..bb3b6ee5ef701 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_details_page/components/agent_details/agent_details_integration_inputs.tsx @@ -94,11 +94,11 @@ export const AgentDetailsIntegrationInputs: React.FunctionComponent<{ const getInputStatusIcon = (inputType: string) => { const inputStatus = inputStatusMap.get(inputType)!; - if (inputStatus.status === undefined) { + if (inputStatus?.status === undefined) { return ( ); @@ -106,19 +106,27 @@ export const AgentDetailsIntegrationInputs: React.FunctionComponent<{ return inputStatus.status === 'HEALTHY' ? ( ) : ( - + {1} ); }; - const generateInputReponse = () => { + const generateInputResponse = () => { return packagePolicy.inputs.reduce( - (acc: Array<{ label: JSX.Element; id: string }>, current) => { + ( + acc: Array<{ + label: JSX.Element; + id: string; + icon: JSX.Element; + children: Array<{ label: JSX.Element; id: string }>; + }>, + current + ) => { if (current.enabled) { return [ ...acc, @@ -196,7 +204,7 @@ export const AgentDetailsIntegrationInputs: React.FunctionComponent<{ {inputsTotalErrors} ) : undefined, - children: generateInputReponse(), + children: generateInputResponse(), }, ]; };