Skip to content

Commit e08daa9

Browse files
[8.18] [EDR Workflows] Fix agent count on policy deploy modal (#209593) (#210043)
# Backport This will backport the following commits from `main` to `8.18`: - [[EDR Workflows] Fix agent count on policy deploy modal (#209593)](#209593) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Gergő Ábrahám","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-02-06T15:17:47Z","message":"[EDR Workflows] Fix agent count on policy deploy modal (#209593)\n\n## Summary\r\n\r\nFixes the agent count issue on the warning model when saving a Defend\r\npackage policy. Now it uses the same `active` field instead of `all`, as\r\nthe `AgentSummary` component.\r\n\r\nAlso, re-enables flaky unit test for `PolicySettingsLayout`:\r\ncloses: #179984\r\n\r\n### Checklist\r\n\r\nCheck the PR satisfies following conditions. \r\n\r\nReviewers should verify this PR satisfies this list as well.\r\n\r\n\r\n- [x] [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":"16fae1c86597d2f43e9120578346e26a8b5a88a5","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Defend Workflows","backport:prev-minor","backport:prev-major","v9.1.0"],"title":"[EDR Workflows] Fix agent count on policy deploy modal","number":209593,"url":"https://github.com/elastic/kibana/pull/209593","mergeCommit":{"message":"[EDR Workflows] Fix agent count on policy deploy modal (#209593)\n\n## Summary\r\n\r\nFixes the agent count issue on the warning model when saving a Defend\r\npackage policy. Now it uses the same `active` field instead of `all`, as\r\nthe `AgentSummary` component.\r\n\r\nAlso, re-enables flaky unit test for `PolicySettingsLayout`:\r\ncloses: #179984\r\n\r\n### Checklist\r\n\r\nCheck the PR satisfies following conditions. \r\n\r\nReviewers should verify this PR satisfies this list as well.\r\n\r\n\r\n- [x] [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":"16fae1c86597d2f43e9120578346e26a8b5a88a5"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/209593","number":209593,"mergeCommit":{"message":"[EDR Workflows] Fix agent count on policy deploy modal (#209593)\n\n## Summary\r\n\r\nFixes the agent count issue on the warning model when saving a Defend\r\npackage policy. Now it uses the same `active` field instead of `all`, as\r\nthe `AgentSummary` component.\r\n\r\nAlso, re-enables flaky unit test for `PolicySettingsLayout`:\r\ncloses: #179984\r\n\r\n### Checklist\r\n\r\nCheck the PR satisfies following conditions. \r\n\r\nReviewers should verify this PR satisfies this list as well.\r\n\r\n\r\n- [x] [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":"16fae1c86597d2f43e9120578346e26a8b5a88a5"}}]}] BACKPORT--> --------- Co-authored-by: Gergő Ábrahám <[email protected]>
1 parent a8f9e6e commit e08daa9

File tree

4 files changed

+64
-15
lines changed

4 files changed

+64
-15
lines changed

x-pack/solutions/security/plugins/security_solution/public/management/hooks/policy/use_fetch_endpoint_policy_agent_summary.test.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { PolicyData } from '../../../../common/endpoint/types';
1212
import { allFleetHttpMocks } from '../../mocks';
1313
import { FleetPackagePolicyGenerator } from '../../../../common/endpoint/data_generators/fleet_package_policy_generator';
1414
import { useFetchAgentByAgentPolicySummary } from './use_fetch_endpoint_policy_agent_summary';
15+
import type { GetAgentStatusResponse } from '@kbn/fleet-plugin/common';
1516
import { agentRouteService, API_VERSIONS } from '@kbn/fleet-plugin/common';
1617

1718
const useQueryMock = _useQuery as jest.Mock;
@@ -59,16 +60,20 @@ describe('When using the `useFetchEndpointPolicyAgentSummary()` hook', () => {
5960
query: { policyId: policy.policy_ids[0] },
6061
version: API_VERSIONS.public.v1,
6162
});
62-
expect(data).toEqual({
63+
const expectedData: GetAgentStatusResponse['results'] = {
64+
active: 50,
6365
total: 50,
66+
all: 0,
6467
inactive: 5,
6568
online: 40,
6669
error: 0,
6770
offline: 5,
6871
updating: 0,
6972
other: 0,
7073
events: 0,
71-
});
74+
unenrolled: 0,
75+
};
76+
expect(data).toEqual(expectedData);
7277
});
7378

7479
it('should apply default values to api returned data', async () => {

x-pack/solutions/security/plugins/security_solution/public/management/mocks/fleet_mocks.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,10 @@ export const fleetGetAgentStatusHttpMock =
415415
id: 'agentStatus',
416416
path: AGENT_API_ROUTES.STATUS_PATTERN,
417417
method: 'get',
418-
handler: () => {
418+
handler: (): GetAgentStatusResponse => {
419419
return {
420420
results: {
421+
active: 50,
421422
total: 50,
422423
inactive: 5,
423424
online: 40,
@@ -426,6 +427,8 @@ export const fleetGetAgentStatusHttpMock =
426427
updating: 0,
427428
other: 0,
428429
events: 0,
430+
unenrolled: 0,
431+
all: 0,
429432
},
430433
};
431434
},

x-pack/solutions/security/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/policy_settings_layout.test.tsx

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { cloneDeep } from 'lodash';
2525
import { set } from '@kbn/safer-lodash-set';
2626
import { ProtectionModes } from '../../../../../../common/endpoint/types';
2727
import { waitFor, cleanup } from '@testing-library/react';
28+
import type { GetAgentStatusResponse } from '@kbn/fleet-plugin/common';
2829
import { packagePolicyRouteService, API_VERSIONS } from '@kbn/fleet-plugin/common';
2930
import { getPolicyDataForUpdate } from '../../../../../../common/endpoint/service/policy';
3031
import { getDeferred } from '../../../../mocks/utils';
@@ -34,8 +35,7 @@ jest.mock('../../../../../common/components/user_privileges');
3435

3536
const useUserPrivilegesMock = _useUserPrivileges as jest.Mock;
3637

37-
// Failing: See https://github.com/elastic/kibana/issues/179984
38-
describe.skip('When rendering PolicySettingsLayout', () => {
38+
describe('When rendering PolicySettingsLayout', () => {
3939
jest.setTimeout(15000);
4040

4141
const testSubj = getPolicySettingsFormTestSubjects();
@@ -84,6 +84,14 @@ describe.skip('When rendering PolicySettingsLayout', () => {
8484
}
8585
};
8686

87+
/**
88+
* Performs a minimal number of updates to make 'Save' button enabled.
89+
*/
90+
const makeMinimalUpdates = async () => {
91+
const { getByTestId } = renderResult;
92+
await userEvent.click(getByTestId(testSubj.malware.enableDisableSwitch));
93+
};
94+
8795
/**
8896
* Makes updates to the policy form on the UI and return back a new (cloned) `PolicyData`
8997
* with the updates reflected in it
@@ -114,9 +122,11 @@ describe.skip('When rendering PolicySettingsLayout', () => {
114122
await userEvent.type(getByTestId(testSubj.ransomware.notifyCustomMessage), 'foo message');
115123
set(policySettings, 'windows.popup.ransomware.message', 'foo message');
116124

117-
await userEvent.click(getByTestId(testSubj.advancedSection.showHideButton));
118-
await userEvent.type(getByTestId('linux.advanced.agent.connection_delay'), '1000');
119-
set(policySettings, 'linux.advanced.agent.connection_delay', '1000');
125+
// skipping Advanced Options as changing them takes too long.
126+
// todo: re-enable them with this issue: https://github.com/elastic/security-team/issues/11765
127+
// await userEvent.click(getByTestId(testSubj.advancedSection.showHideButton));
128+
// await userEvent.type(getByTestId('linux.advanced.agent.connection_delay'), '1000');
129+
// set(policySettings, 'linux.advanced.agent.connection_delay', '1000');
120130

121131
return expectedUpdates;
122132
};
@@ -131,7 +141,7 @@ describe.skip('When rendering PolicySettingsLayout', () => {
131141

132142
it('should render layout with expected content when changes have been made', async () => {
133143
const { getByTestId } = render();
134-
await makeUpdates();
144+
await makeMinimalUpdates();
135145
expect(getByTestId('endpointPolicyForm'));
136146
expect(getByTestId('policyDetailsCancelButton')).not.toBeDisabled();
137147
expect(getByTestId('policyDetailsSaveButton')).not.toBeDisabled();
@@ -153,7 +163,7 @@ describe.skip('When rendering PolicySettingsLayout', () => {
153163
const deferred = getDeferred();
154164
apiMocks.responseProvider.updateEndpointPolicy.mockDelay.mockReturnValue(deferred.promise);
155165
const { getByTestId } = render();
156-
await makeUpdates();
166+
await makeMinimalUpdates();
157167
await clickSave(true, false);
158168

159169
await waitFor(() => {
@@ -164,13 +174,11 @@ describe.skip('When rendering PolicySettingsLayout', () => {
164174
expect(
165175
getByTestId('policyDetailsSaveButton').querySelector('.euiLoadingSpinner')
166176
).not.toBeNull();
167-
168-
deferred.resolve();
169177
});
170178

171179
it('should show success toast on update success', async () => {
172180
render();
173-
await makeUpdates();
181+
await makeMinimalUpdates();
174182
await clickSave();
175183

176184
await waitFor(() => {
@@ -189,7 +197,7 @@ describe.skip('When rendering PolicySettingsLayout', () => {
189197
throw new Error('oh oh!');
190198
});
191199
render();
192-
await makeUpdates();
200+
await makeMinimalUpdates();
193201
await clickSave();
194202

195203
await waitFor(() => {
@@ -202,6 +210,39 @@ describe.skip('When rendering PolicySettingsLayout', () => {
202210
title: 'Failed!',
203211
});
204212
});
213+
214+
it('should not show warning about endpoints if there are no active endpoints', async () => {
215+
apiMocks.responseProvider.agentStatus.mockReturnValue({
216+
results: { active: 0 },
217+
} as GetAgentStatusResponse);
218+
219+
const { getByTestId, queryByTestId } = render();
220+
await makeMinimalUpdates();
221+
222+
await userEvent.click(getByTestId('policyDetailsSaveButton'));
223+
await waitFor(() => {
224+
expect(getByTestId('confirmModalConfirmButton')).toBeInTheDocument();
225+
});
226+
expect(queryByTestId('policyDetailsWarningCallout')).not.toBeInTheDocument();
227+
});
228+
229+
it('should show warning about endpoints with the number of active endpoints', async () => {
230+
apiMocks.responseProvider.agentStatus.mockReturnValue({
231+
results: { active: 6 },
232+
} as GetAgentStatusResponse);
233+
234+
const { getByTestId } = render();
235+
await makeMinimalUpdates();
236+
237+
await userEvent.click(getByTestId('policyDetailsSaveButton'));
238+
await waitFor(() => {
239+
expect(getByTestId('confirmModalConfirmButton')).toBeInTheDocument();
240+
});
241+
242+
const callout = getByTestId('policyDetailsWarningCallout');
243+
expect(callout).toBeInTheDocument();
244+
expect(callout.textContent).toContain('This action will update 6 endpoints');
245+
});
205246
});
206247

207248
describe('and user has View Only permissions', () => {

x-pack/solutions/security/plugins/security_solution/public/management/pages/policy/view/policy_settings_layout/policy_settings_layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ export const PolicySettingsLayout = memo<PolicySettingsLayoutProps>(
170170
<>
171171
{showConfirm && (
172172
<ConfirmUpdate
173-
endpointCount={agentSummaryData ? agentSummaryData.all : 0}
173+
endpointCount={agentSummaryData ? agentSummaryData.active : 0}
174174
onCancel={handleSaveCancel}
175175
onConfirm={handleSaveConfirmation}
176176
/>

0 commit comments

Comments
 (0)