From fda66d96d9c3444667f4de7c5799e585fdcc9611 Mon Sep 17 00:00:00 2001 From: alex prozorov Date: Thu, 20 Feb 2025 14:53:43 +0200 Subject: [PATCH] renamed param on that indicates fleet extension state added unit test for CspPolicyTemplateForm component --- .../single_page_layout/index.tsx | 4 +- .../fleet/public/types/ui_extensions.ts | 2 +- .../policy_template_form.test.tsx | 87 +++++++++++++++++++ .../fleet_extensions/policy_template_form.tsx | 16 ++-- 4 files changed, 98 insertions(+), 11 deletions(-) diff --git a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index fee6c598c5de9..df08a44c6dfe8 100644 --- a/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/platform/plugins/shared/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -270,9 +270,9 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ const handleExtensionViewOnChange = useCallback< PackagePolicyEditExtensionComponentProps['onChange'] >( - ({ isValid, updatedPolicy, fetchedPackagePolicies }) => { + ({ isValid, updatedPolicy, isLoadedPackagePolicies }) => { updatePackagePolicy(updatedPolicy); - setIsFetchedPackagePolicies(fetchedPackagePolicies); + setIsFetchedPackagePolicies(isLoadedPackagePolicies); setFormState((prevState) => { if (prevState === 'VALID' && !isValid) { return 'INVALID'; diff --git a/x-pack/platform/plugins/shared/fleet/public/types/ui_extensions.ts b/x-pack/platform/plugins/shared/fleet/public/types/ui_extensions.ts index 7e38480e18c3c..87476f67407c9 100644 --- a/x-pack/platform/plugins/shared/fleet/public/types/ui_extensions.ts +++ b/x-pack/platform/plugins/shared/fleet/public/types/ui_extensions.ts @@ -75,7 +75,7 @@ export interface PackagePolicyEditExtensionComponentProps { isValid: boolean; /** The updated Integration Policy to be merged back and included in the API call */ updatedPolicy: Partial; - fetchedPackagePolicies?: boolean; + isLoadedPackagePolicies?: boolean; }) => void; } diff --git a/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx b/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx index 64019ad2690c6..c45610042408f 100644 --- a/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx +++ b/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.test.tsx @@ -124,12 +124,14 @@ describe('', () => { edit = false, packageInfo = {} as PackageInfo, isAgentlessEnabled, + integrationToEnable, }: { edit?: boolean; newPolicy: NewPackagePolicy; packageInfo?: PackageInfo; onChange?: jest.Mock; isAgentlessEnabled?: boolean; + integrationToEnable?: string; }) => { const { AppWrapper: FleetAppWrapper } = createFleetTestRendererMock(); return ( @@ -143,6 +145,7 @@ describe('', () => { packageInfo={packageInfo} isEditPage={true} isAgentlessEnabled={isAgentlessEnabled} + integrationToEnable={integrationToEnable} /> )} {!edit && ( @@ -152,6 +155,7 @@ describe('', () => { packageInfo={packageInfo} isEditPage={false} isAgentlessEnabled={isAgentlessEnabled} + integrationToEnable={integrationToEnable} /> )} @@ -425,6 +429,89 @@ describe('', () => { }); }); + it('KSPM - calls onChange with isLoadedPackagePolicies the second time after increment of package version', () => { + const policy = getMockPolicyK8s(); + + // enable all inputs of a policy template, same as fleet does + policy.inputs = policy.inputs.map((input) => ({ + ...input, + enabled: input.policy_template === 'kspm', + })); + policy.name = 'cloud_security_posture-1'; + + (useParams as jest.Mock).mockReturnValue({ + integration: 'kspm', + }); + + (useCspSetupStatusApi as jest.Mock).mockImplementation(() => + createReactQueryResponseWithRefetch({ + status: 'success', + data: { + kspm: { status: 'not-deployed', healthyAgents: 0, installedPackagePolicies: 1 }, + }, + }) + ); + + (usePackagePolicyList as jest.Mock).mockImplementation(() => + createReactQueryResponseWithRefetch({ + status: 'success', + data: { + items: [getPosturePolicy(getMockPolicyEKS(), CLOUDBEAT_EKS)], + }, + }) + ); + + render( + + ); + + // 1st call happens on mount and selects the default policy template enabled input + expect(onChange).nthCalledWith(1, { + isLoadedPackagePolicies: undefined, + isValid: true, + updatedPolicy: { + ...getMockPolicyK8s(), + name: 'cloud_security_posture-1', + }, + }); + + // 2nd call happens on mount and increments kspm template enabled input + expect(onChange).nthCalledWith(2, { + isLoadedPackagePolicies: undefined, + isValid: true, + updatedPolicy: { + ...getMockPolicyK8s(), + inputs: policy.inputs.map((input) => ({ + ...input, + enabled: input.type === 'cloudbeat/cis_k8s', + })), + name: 'cloud_security_posture-1', + }, + }); + + /* + 3rd call happens when policies are fetched and the package version is incremented + in that case isLoadedPackagePolicies is set to 'true' + */ + expect(onChange).nthCalledWith(3, { + isLoadedPackagePolicies: true, + isValid: true, + updatedPolicy: { + ...getMockPolicyK8s(), + inputs: policy.inputs.map((input) => ({ + ...input, + enabled: input.policy_template === 'kspm', + })), + name: 'kspm-1', + }, + }); + }); + it('selects default VULN_MGMT input selector', () => { const policy = getMockPolicyVulnMgmtAWS(); // enable all inputs of a policy template, same as fleet does diff --git a/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx b/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx index 52c0a4850ae73..e9cb76cf02afe 100644 --- a/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx +++ b/x-pack/solutions/security/plugins/cloud_security_posture/public/components/fleet_extensions/policy_template_form.tsx @@ -197,7 +197,7 @@ const AwsAccountTypeSelect = ({ }: { input: Extract; newPolicy: NewPackagePolicy; - updatePolicy: (updatedPolicy: NewPackagePolicy, fetchedPackagePolicies?: boolean) => void; + updatePolicy: (updatedPolicy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => void; packageInfo: PackageInfo; disabled: boolean; }) => { @@ -303,7 +303,7 @@ const GcpAccountTypeSelect = ({ }: { input: Extract; newPolicy: NewPackagePolicy; - updatePolicy: (updatedPolicy: NewPackagePolicy, fetchedPackagePolicies?: boolean) => void; + updatePolicy: (updatedPolicy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => void; packageInfo: PackageInfo; disabled: boolean; }) => { @@ -443,7 +443,7 @@ const AzureAccountTypeSelect = ({ }: { input: Extract; newPolicy: NewPackagePolicy; - updatePolicy: (updatedPolicy: NewPackagePolicy, fetchedPackagePolicies?: boolean) => void; + updatePolicy: (updatedPolicy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => void; disabled: boolean; packageInfo: PackageInfo; setupTechnology: SetupTechnology; @@ -548,7 +548,7 @@ const useEnsureDefaultNamespace = ({ }: { newPolicy: NewPackagePolicy; input: NewPackagePolicyPostureInput; - updatePolicy: (policy: NewPackagePolicy, fetchedPackagePolicies?: boolean) => void; + updatePolicy: (policy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => void; }) => { useEffect(() => { if (newPolicy.namespace === POSTURE_NAMESPACE) return; @@ -572,7 +572,7 @@ const usePolicyTemplateInitialName = ({ integration: CloudSecurityPolicyTemplate | undefined; newPolicy: NewPackagePolicy; packagePolicyList: PackagePolicy[] | undefined; - updatePolicy: (policy: NewPackagePolicy, fetchedPackagePolicies?: boolean) => void; + updatePolicy: (policy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => void; setCanFetchIntegration: (canFetch: boolean) => void; }) => { useEffect(() => { @@ -628,7 +628,7 @@ const useCloudFormationTemplate = ({ }: { packageInfo: PackageInfo; newPolicy: NewPackagePolicy; - updatePolicy: (policy: NewPackagePolicy, fetchedPackagePolicies?: boolean) => void; + updatePolicy: (policy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => void; }) => { useEffect(() => { const templateUrl = getVulnMgmtCloudFormationDefaultValue(packageInfo); @@ -743,8 +743,8 @@ export const CspPolicyTemplateForm = memo { - onChange({ isValid, updatedPolicy, fetchedPackagePolicies }); + (updatedPolicy: NewPackagePolicy, isLoadedPackagePolicies?: boolean) => { + onChange({ isValid, updatedPolicy, isLoadedPackagePolicies }); }, [onChange, isValid] );