Skip to content

Commit

Permalink
adding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
agusruidiazgd committed Oct 7, 2024
1 parent 046aebd commit 7554939
Show file tree
Hide file tree
Showing 27 changed files with 521 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { integrationsCardConfig } from './cards/integrations';
import { dashboardsCardConfig } from './cards/dashboards';
import { rulesCardConfig } from './cards/rules';
import { alertsCardConfig } from './cards/alerts';
import { asistantCardConfig } from './cards/asistant';
import { assistantCardConfig } from './cards/assistant';
import { attackDiscoveryCardConfig } from './cards/attack_discovery';

export const bodyConfig: OnboardingGroupConfig[] = [
Expand All @@ -31,6 +31,6 @@ export const bodyConfig: OnboardingGroupConfig[] = [
title: i18n.translate('xpack.securitySolution.onboarding.discoverGroup.title', {
defaultMessage: 'Discover Elastic AI',
}),
cards: [asistantCardConfig, attackDiscoveryCardConfig],
cards: [assistantCardConfig, attackDiscoveryCardConfig],
},
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 { AlertsCard } from './alerts_card';
import { TestProviders } from '../../../../../common/mock';

const props = {
setComplete: jest.fn(),
checkComplete: jest.fn(),
isCardComplete: jest.fn(),
setExpandedCardId: jest.fn(),
};

describe('AlertsCard', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('description should be in the document', () => {
const { getByTestId } = render(
<TestProviders>
<AlertsCard {...props} />
</TestProviders>
);

expect(getByTestId('alertsCardDescription')).toBeInTheDocument();
});

it('card callout should be rendered if integrations cards is not complete', () => {
props.isCardComplete.mockReturnValueOnce(false);

const { getByText } = render(
<TestProviders>
<AlertsCard {...props} />
</TestProviders>
);

expect(getByText('To view alerts add integrations first.')).toBeInTheDocument();
});

it('card button should be disabled if integrations cards is not complete', () => {
props.isCardComplete.mockReturnValueOnce(false);

const { getByTestId } = render(
<TestProviders>
<AlertsCard {...props} />
</TestProviders>
);

expect(getByTestId('alertsCardButton').querySelector('button')).toBeDisabled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const AlertsCard: OnboardingCardComponent = ({
alignItems="flexStart"
>
<EuiFlexItem grow={false}>
<EuiText size="s" color="subdued">
<EuiText data-test-subj="alertsCardDescription" size="s" color="subdued">
{i18n.ALERTS_CARD_DESCRIPTION}
</EuiText>
{!isIntegrationsCardComplete && (
Expand All @@ -63,7 +63,7 @@ export const AlertsCard: OnboardingCardComponent = ({
</>
)}
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiFlexItem data-test-subj="alertsCardButton" grow={false}>
<SecuritySolutionLinkButton
onClick={() => setComplete(true)}
deepLinkId={SecurityPageName.alerts}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,22 @@
import React, { useCallback, useMemo } from 'react';
import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiLink, EuiText } from '@elastic/eui';
import { css } from '@emotion/css';
import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector';
import { OnboardingCardId } from '../../../../constants';
import type { OnboardingCardComponent } from '../../../../types';
import * as i18n from './translations';
import { OnboardingCardContentPanel } from '../common/card_content_panel';
import { ConfigureConnector } from './components/configure_connector/configure_connector';
import { ConnectorCards } from './components/connector_cards/connector_cards';
import { CardCallOut } from '../common/card_callout';

export const AsistantCard: OnboardingCardComponent = ({
const AllowedActionTypeIds = ['.bedrock', '.gen-ai', '.gemini'];

export const AssistantCard: OnboardingCardComponent = ({
setComplete,
isCardComplete,
setExpandedCardId,
checkCompleteMetadata,
checkComplete,
}) => {
const isIntegrationsCardComplete = useMemo(
() => isCardComplete(OnboardingCardId.integrations),
Expand All @@ -29,8 +34,10 @@ export const AsistantCard: OnboardingCardComponent = ({
setExpandedCardId(OnboardingCardId.integrations, { scroll: true });
}, [setExpandedCardId]);

const aiConnectors = checkCompleteMetadata?.connectors as AIConnector[];

return (
<OnboardingCardContentPanel>
<OnboardingCardContentPanel paddingSize="s">
<EuiFlexGroup direction="column">
<EuiFlexItem grow={false}>
<EuiText size="s" color="subdued">
Expand All @@ -39,7 +46,11 @@ export const AsistantCard: OnboardingCardComponent = ({
</EuiFlexItem>
<EuiFlexItem>
{isIntegrationsCardComplete ? (
<ConfigureConnector setComplete={setComplete} />
<ConnectorCards
connectors={aiConnectors}
actionTypeIds={AllowedActionTypeIds}
onConnectorSaved={checkComplete}
/>
) : (
<EuiFlexItem
className={css`
Expand Down Expand Up @@ -70,4 +81,4 @@ export const AsistantCard: OnboardingCardComponent = ({
};

// eslint-disable-next-line import/no-default-export
export default AsistantCard;
export default AssistantCard;
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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 { loadAllActions as loadConnectors } from '@kbn/triggers-actions-ui-plugin/public/common/constants';
import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector';
import type { OpenAiProviderType } from '@kbn/stack-connectors-plugin/public/common';
import type { OnboardingCardCheckComplete } from '../../../../types';

const AllowedActionTypeIds = ['.bedrock', '.gen-ai', '.gemini'];
const actionTypeKey = {
bedrock: '.bedrock',
openai: '.gen-ai',
gemini: '.gemini',
};

export const checkAssistantCardComplete: OnboardingCardCheckComplete = async ({ http }) => {
const aiConnectorsResult = await loadConnectors({ http });

const reducedAiConnectorsResult = aiConnectorsResult.reduce(
(acc: AIConnector[], connector) => [
...acc,
...(!connector.isMissingSecrets &&
[actionTypeKey.bedrock, actionTypeKey.openai, actionTypeKey.gemini].includes(
connector.actionTypeId
)
? [
{
...connector,
apiProvider:
!connector.isPreconfigured &&
!connector.isSystemAction &&
connector?.config?.apiProvider
? (connector?.config?.apiProvider as OpenAiProviderType)
: undefined,
},
]
: []),
],
[]
);

const filteredConnectors = reducedAiConnectorsResult.filter(({ actionTypeId }) =>
AllowedActionTypeIds.includes(actionTypeId)
);

return {
isComplete: filteredConnectors.length > 0,
metadata: {
connectors: filteredConnectors,
},
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import React, { useCallback, useMemo, useState } from 'react';
import type { AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector';
import { type AIConnector } from '@kbn/elastic-assistant/impl/connectorland/connector_selector';
import {
useEuiTheme,
EuiFlexGroup,
Expand All @@ -18,15 +18,15 @@ import {
EuiLink,
EuiTextColor,
useEuiBackgroundColor,
EuiBadge,
EuiSpacer,
} from '@elastic/eui';
import {
ConnectorAddModal,
type ActionConnector,
} from '@kbn/triggers-actions-ui-plugin/public/common/constants';
import { ConnectorAddModal } from '@kbn/triggers-actions-ui-plugin/public/common/constants';
import { useLoadActionTypes } from '@kbn/elastic-assistant/impl/connectorland/use_load_action_types';
import type { ActionType } from '@kbn/actions-plugin/common';
import { css } from '@emotion/css';
import { useKibana } from '../../../../../../../common/lib/kibana';
import { CreateConnectorPopover } from '../create_connector_popover/create_connector_popover';

const useConnectorCardsStyles = () => {
const { euiTheme } = useEuiTheme();
Expand All @@ -53,7 +53,7 @@ const useConnectorCardsStyles = () => {

interface ConnectorCardsProps {
connectors?: AIConnector[];
onConnectorSaved?: (savedAction: ActionConnector) => void;
onConnectorSaved: () => void;
onClose?: () => void;
actionTypeIds?: string[];
}
Expand All @@ -79,7 +79,39 @@ export const ConnectorCards = React.memo<ConnectorCardsProps>(
return actionTypeIds ? data?.filter(({ id }) => actionTypeIds.includes(id)) : data;
}, [data, actionTypeIds]);

if (!actionTypes) return <EuiLoadingSpinner />;
if (!actionTypes || !connectors) return <EuiLoadingSpinner />;

if (connectors.length > 0) {
return (
<>
<EuiFlexGroup wrap>
{connectors?.map((connector) => (
<EuiFlexItem
grow={false}
className={css`
width: 30%;
`}
>
<EuiPanel hasShadow={false} hasBorder paddingSize="m">
<EuiFlexGroup alignItems="center">
<EuiFlexItem>
<EuiText>{connector.name}</EuiText>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiBadge color="hollow">
{actionTypeRegistry.get(connector.actionTypeId).actionTypeTitle}
</EuiBadge>
</EuiFlexItem>
</EuiFlexGroup>
</EuiPanel>
</EuiFlexItem>
))}
</EuiFlexGroup>
<EuiSpacer />
<CreateConnectorPopover onConnectorSaved={onConnectorSaved} />
</>
);
}

return (
<>
Expand Down
Loading

0 comments on commit 7554939

Please sign in to comment.