-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Fleet] Display missing warning when triggering delete package polici…
…es actions (#194808) Fixes #190476 ## Summary Display missing warning when triggering delete package policies actions. Currently when no agents are enrolled this warning doesn't get displayed. - Also added unit tests for this action provider component ![Screenshot 2024-10-03 at 12 26 59](https://github.com/user-attachments/assets/a1fa7753-f061-4f87-a0ba-54253690903a) Video showing the warnings in different cases. The case the was fixed is the first one: https://github.com/user-attachments/assets/0fe9d1d2-c6fd-4f8c-84ad-1cce20ed7eac ### Testing - You need to have an integration policy shared between several agent policies and those agent policies shouldn't have any agents enrolled. - Go to integration policy page and try to delete the policy from "delete integration" - The warning above should appear ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios
- Loading branch information
Showing
2 changed files
with
278 additions
and
16 deletions.
There are no files selected for viewing
260 changes: 260 additions & 0 deletions
260
x-pack/plugins/fleet/public/components/package_policy_delete_provider.test.tsx
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,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); | ||
}); | ||
}); |
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