[8.x] [Fleet] Display missing warning when triggering delete package policies actions (#194808) (#194828)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Fleet] Display missing warning when triggering delete package
policies actions
(#194808)](https://github.com/elastic/kibana/pull/194808)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Cristina
Amico","email":"criamico@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-03T12:21:56Z","message":"[Fleet]
Display missing warning when triggering delete package policies actions
(#194808)\n\nFixes
https://github.com/elastic/kibana/issues/190476\r\n\r\n##
Summary\r\nDisplay missing warning when triggering delete package
policies actions.\r\nCurrently when no agents are enrolled this warning
doesn't get\r\ndisplayed.\r\n- Also added unit tests for this action
provider component\r\n\r\n![Screenshot 2024-10-03 at 12
26\r\n59](https://github.com/user-attachments/assets/a1fa7753-f061-4f87-a0ba-54253690903a)\r\n\r\nVideo
showing the warnings in different cases. The case the was fixed
is\r\nthe first
one:\r\n\r\n\r\nhttps://github.com/user-attachments/assets/0fe9d1d2-c6fd-4f8c-84ad-1cce20ed7eac\r\n\r\n\r\n###
Testing\r\n\r\n- You need to have an integration policy shared between
several agent\r\npolicies and those agent policies shouldn't have any
agents enrolled.\r\n- Go to integration policy page and try to delete
the policy from\r\n\"delete integration\"\r\n- The warning above should
appear\r\n\r\n\r\n### Checklist\r\n- [ ] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"6c3ecd7fbaccb6d3d60495cbbaf0dabd19c7db9a","branchLabelMapping":{"^v9.0.0$":"main","^v8.16.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Fleet","v9.0.0","backport:prev-major"],"title":"[Fleet]
Display missing warning when triggering delete package policies
actions","number":194808,"url":"https://github.com/elastic/kibana/pull/194808","mergeCommit":{"message":"[Fleet]
Display missing warning when triggering delete package policies actions
(#194808)\n\nFixes
https://github.com/elastic/kibana/issues/190476\r\n\r\n##
Summary\r\nDisplay missing warning when triggering delete package
policies actions.\r\nCurrently when no agents are enrolled this warning
doesn't get\r\ndisplayed.\r\n- Also added unit tests for this action
provider component\r\n\r\n![Screenshot 2024-10-03 at 12
26\r\n59](https://github.com/user-attachments/assets/a1fa7753-f061-4f87-a0ba-54253690903a)\r\n\r\nVideo
showing the warnings in different cases. The case the was fixed
is\r\nthe first
one:\r\n\r\n\r\nhttps://github.com/user-attachments/assets/0fe9d1d2-c6fd-4f8c-84ad-1cce20ed7eac\r\n\r\n\r\n###
Testing\r\n\r\n- You need to have an integration policy shared between
several agent\r\npolicies and those agent policies shouldn't have any
agents enrolled.\r\n- Go to integration policy page and try to delete
the policy from\r\n\"delete integration\"\r\n- The warning above should
appear\r\n\r\n\r\n### Checklist\r\n- [ ] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"6c3ecd7fbaccb6d3d60495cbbaf0dabd19c7db9a"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194808","number":194808,"mergeCommit":{"message":"[Fleet]
Display missing warning when triggering delete package policies actions
(#194808)\n\nFixes
https://github.com/elastic/kibana/issues/190476\r\n\r\n##
Summary\r\nDisplay missing warning when triggering delete package
policies actions.\r\nCurrently when no agents are enrolled this warning
doesn't get\r\ndisplayed.\r\n- Also added unit tests for this action
provider component\r\n\r\n![Screenshot 2024-10-03 at 12
26\r\n59](https://github.com/user-attachments/assets/a1fa7753-f061-4f87-a0ba-54253690903a)\r\n\r\nVideo
showing the warnings in different cases. The case the was fixed
is\r\nthe first
one:\r\n\r\n\r\nhttps://github.com/user-attachments/assets/0fe9d1d2-c6fd-4f8c-84ad-1cce20ed7eac\r\n\r\n\r\n###
Testing\r\n\r\n- You need to have an integration policy shared between
several agent\r\npolicies and those agent policies shouldn't have any
agents enrolled.\r\n- Go to integration policy page and try to delete
the policy from\r\n\"delete integration\"\r\n- The warning above should
appear\r\n\r\n\r\n### Checklist\r\n- [ ] [Unit or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common
scenarios","sha":"6c3ecd7fbaccb6d3d60495cbbaf0dabd19c7db9a"}}]}]
BACKPORT-->

Co-authored-by: Cristina Amico <criamico@users.noreply.github.com>
This commit is contained in:
Kibana Machine 2024-10-04 00:09:30 +10:00 committed by GitHub
parent 2377a4a10f
commit 8347dedf0f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 278 additions and 16 deletions

View file

@ -0,0 +1,260 @@
/*
* 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 { act, fireEvent } from '@testing-library/react';
import { EuiContextMenuItem } from '@elastic/eui';
import type { AgentPolicy, PackagePolicy } from '../types';
import { createIntegrationsTestRendererMock } from '../mock';
import { sendGetAgents, useMultipleAgentPolicies } from '../hooks';
import { PackagePolicyDeleteProvider } from './package_policy_delete_provider';
jest.mock('../hooks', () => {
return {
...jest.requireActual('../hooks'),
useMultipleAgentPolicies: jest.fn(),
useStartServices: jest.fn().mockReturnValue({
notifications: {
toasts: { addSuccess: jest.fn() },
},
}),
sendGetAgents: jest.fn(),
useConfig: jest.fn().mockReturnValue({
agents: { enabled: true },
}),
};
});
const useMultipleAgentPoliciesMock = useMultipleAgentPolicies as jest.MockedFunction<
typeof useMultipleAgentPolicies
>;
const sendGetAgentsMock = sendGetAgents as jest.MockedFunction<typeof sendGetAgents>;
function renderMenu({
agentPolicies,
packagePolicyIds,
}: {
agentPolicies: AgentPolicy[];
packagePolicyIds: string[];
}) {
const renderer = createIntegrationsTestRendererMock();
const utils = renderer.render(
<PackagePolicyDeleteProvider agentPolicies={agentPolicies}>
{(deletePackagePoliciesPrompt) => {
return (
<EuiContextMenuItem
onClick={() => {
deletePackagePoliciesPrompt(packagePolicyIds, () => {});
}}
>
Delete integration
</EuiContextMenuItem>
);
}}
</PackagePolicyDeleteProvider>
);
return { utils };
}
function createMockAgentPolicies(
props: Partial<AgentPolicy> = {},
multiple?: boolean
): AgentPolicy[] {
if (!multiple) {
return [
{
id: 'some-uuid1',
namespace: 'default',
monitoring_enabled: [],
name: 'Test Policy',
description: '',
is_preconfigured: false,
status: 'active',
is_managed: false,
revision: 1,
updated_at: '',
updated_by: 'elastic',
package_policies: [
{ name: 'integration-0001' } as PackagePolicy,
{ name: 'integration-0002' } as PackagePolicy,
],
is_protected: false,
...props,
},
];
} else {
return [
{
id: 'some-uuid1',
namespace: 'default',
monitoring_enabled: [],
name: 'Test Policy 1',
description: '',
is_preconfigured: false,
status: 'active',
is_managed: false,
revision: 1,
updated_at: '',
updated_by: 'elastic',
package_policies: [],
is_protected: false,
...props,
},
{
id: 'some-uuid2',
namespace: 'default',
monitoring_enabled: [],
name: 'Test Policy 2',
description: '',
is_preconfigured: false,
status: 'active',
is_managed: false,
revision: 1,
updated_at: '',
updated_by: 'elastic',
package_policies: [
{ name: 'integration-0001' } as PackagePolicy,
{ name: 'integration-0002' } as PackagePolicy,
],
is_protected: false,
...props,
},
];
}
}
describe('PackagePolicyDeleteProvider', () => {
it('Should show delete integrations action and cancel modal', async () => {
useMultipleAgentPoliciesMock.mockReturnValue({ canUseMultipleAgentPolicies: false });
sendGetAgentsMock.mockResolvedValue({
data: {
statusSummary: {},
items: [
{
id: 'agent123',
policy_id: 'agent-policy-1',
},
],
total: 5,
},
} as any);
const agentPolicies = createMockAgentPolicies();
const { utils } = renderMenu({
agentPolicies,
packagePolicyIds: ['integration-0001'],
});
await act(async () => {
const button = utils.getByRole('button');
fireEvent.click(button);
});
expect(utils.getByText('This action will affect 5 agents.')).toBeInTheDocument();
expect(
utils.getByText('This action can not be undone. Are you sure you wish to continue?')
).toBeInTheDocument();
expect(utils.getAllByText(/is already in use by some of your agents./).length).toBe(1);
});
it('When multiple agent policies are present and agents are enrolled show additional warnings', async () => {
sendGetAgentsMock.mockResolvedValue({
data: {
statusSummary: {},
items: [
{
id: 'agent123',
policy_id: 'agent-policy-1',
},
],
total: 5,
},
} as any);
useMultipleAgentPoliciesMock.mockReturnValue({ canUseMultipleAgentPolicies: true });
const agentPolicies = createMockAgentPolicies(undefined, true);
const { utils } = renderMenu({
agentPolicies,
packagePolicyIds: ['integration-0001'],
});
await act(async () => {
const button = utils.getByRole('button');
fireEvent.click(button);
});
expect(utils.getByText('This action will affect 5 agents.')).toBeInTheDocument();
expect(
utils.getByText('This integration is shared by multiple agent policies.')
).toBeInTheDocument();
expect(
utils.getByText('This action can not be undone. Are you sure you wish to continue?')
).toBeInTheDocument();
expect(utils.queryAllByText(/is already in use by some of your agents./).length).toBe(0);
});
it('When multiple agent policies are present and no agents are enrolled show additional warnings', async () => {
sendGetAgentsMock.mockResolvedValue({
data: {
statusSummary: {},
items: [],
total: 0,
},
} as any);
useMultipleAgentPoliciesMock.mockReturnValue({ canUseMultipleAgentPolicies: true });
const agentPolicies = createMockAgentPolicies(undefined, true);
const { utils } = renderMenu({
agentPolicies,
packagePolicyIds: ['integration-0001'],
});
await act(async () => {
const button = utils.getByRole('button');
fireEvent.click(button);
});
expect(utils.queryByText('This action will affect 5 agents.')).not.toBeInTheDocument();
expect(utils.queryAllByText(/is already in use by some of your agents./).length).toBe(0);
expect(
utils.getByText('This integration is shared by multiple agent policies.')
).toBeInTheDocument();
expect(
utils.getByText('This action can not be undone. Are you sure you wish to continue?')
).toBeInTheDocument();
});
it('When agentless should show a different set of warnings', async () => {
useMultipleAgentPoliciesMock.mockReturnValue({ canUseMultipleAgentPolicies: false });
sendGetAgentsMock.mockResolvedValue({
data: {
statusSummary: {},
items: [
{
id: 'agent123',
policy_id: 'agent-policy-1',
},
],
total: 5,
},
} as any);
const agentPolicies = createMockAgentPolicies({ supports_agentless: true });
const { utils } = renderMenu({
agentPolicies,
packagePolicyIds: ['integration-0001'],
});
await act(async () => {
const button = utils.getByRole('button');
fireEvent.click(button);
});
// utils.debug();
expect(utils.queryByText('This action will affect 5 agents.')).not.toBeInTheDocument();
expect(utils.getByText(/about to delete an integration/)).toBeInTheDocument();
expect(
utils.getByText('This action can not be undone. Are you sure you wish to continue?')
).toBeInTheDocument();
expect(utils.getAllByText(/integration will stop data ingestion./).length).toBe(1);
});
});

View file

@ -15,10 +15,11 @@ import {
sendDeletePackagePolicy,
sendDeleteAgentPolicy,
useConfig,
sendGetAgents,
useMultipleAgentPolicies,
} from '../hooks';
import { AGENTS_PREFIX } from '../../common/constants';
import type { AgentPolicy } from '../types';
import { sendGetAgents, useMultipleAgentPolicies } from '../hooks';
interface Props {
agentPolicies?: AgentPolicy[];
@ -235,6 +236,22 @@ export const PackagePolicyDeleteProvider: React.FunctionComponent<Props> = ({
buttonColor="danger"
confirmButtonDisabled={isLoading || isLoadingAgentsCount}
>
{(hasMultipleAgentPolicies || isShared) && (
<>
<EuiCallOut
color="warning"
iconType="alert"
title={
<FormattedMessage
id="xpack.fleet.deletePackagePolicy.confirmModal.warningMultipleAgentPolicies"
defaultMessage="This integration is shared by multiple agent policies."
/>
}
/>
<EuiSpacer size="m" />
</>
)}
{isLoadingAgentsCount ? (
<FormattedMessage
id="xpack.fleet.deletePackagePolicy.confirmModal.loadingAgentsCountMessage"
@ -242,21 +259,6 @@ export const PackagePolicyDeleteProvider: React.FunctionComponent<Props> = ({
/>
) : agentsCount && agentPolicies ? (
<>
{(hasMultipleAgentPolicies || isShared) && (
<>
<EuiCallOut
color="warning"
iconType="alert"
title={
<FormattedMessage
id="xpack.fleet.deletePackagePolicy.confirmModal.warningMultipleAgentPolicies"
defaultMessage="This integration is shared by multiple agent policies."
/>
}
/>
<EuiSpacer size="m" />
</>
)}
<EuiCallOut
color="danger"
title={